@k-msg/core 0.30.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import type { FieldCryptoConfig, FieldMode } from "./types";
1
+ import type { FieldCryptoConfig, FieldCryptoFailMode, FieldCryptoOpenFallback, FieldMode } from "./types";
2
2
  export interface FieldCryptoPolicyValidationIssue {
3
3
  message: string;
4
4
  rule: string;
@@ -14,5 +14,26 @@ export interface FieldCryptoPolicyValidationResult {
14
14
  issues: FieldCryptoPolicyValidationIssue[];
15
15
  }
16
16
  export declare function resolveFieldMode(config: FieldCryptoConfig, path: string, fallback: FieldMode): FieldMode;
17
+ /**
18
+ * The fail mode to apply. Only an explicit `"open"` fails open; a missing or
19
+ * unrecognized value, such as a typo in JSON configuration, fails closed.
20
+ */
21
+ export declare function resolveFieldCryptoFailMode(config: Pick<FieldCryptoConfig, "failMode">): FieldCryptoFailMode;
22
+ /**
23
+ * The fallback a fail-open write stores. A missing or unrecognized value
24
+ * falls back to `"masked"`.
25
+ */
26
+ export declare function resolveFieldCryptoOpenFallback(config: Pick<FieldCryptoConfig, "openFallback">): FieldCryptoOpenFallback;
27
+ /**
28
+ * @evidence docs/security/field-crypto-v1.md#fail-policy
29
+ * Rejects unknown failMode and openFallback values and
30
+ * openFallback=plaintext without unsafeAllowPlaintextStorage;
31
+ * resolveFieldCryptoFailMode and resolveFieldCryptoOpenFallback apply the
32
+ * closed and masked runtime defaults.
33
+ * @evidenceReview docs/security/field-crypto-v1.md#fail-policy #b4dd0b8
34
+ * Read the four bullets against this function and both resolvers, and ran
35
+ * policy.test.ts, which covers the plaintext guard, the rejected unknown
36
+ * values, and the closed and masked defaults.
37
+ */
17
38
  export declare function validateFieldCryptoConfig(config: FieldCryptoConfig, options?: FieldCryptoPolicyOptions): FieldCryptoPolicyValidationResult;
18
39
  export declare function assertFieldCryptoConfig(config: FieldCryptoConfig, options?: FieldCryptoPolicyOptions): void;
@@ -1,3 +1,9 @@
1
+ /**
2
+ * @evidence docs/security/field-crypto-v1.md#field-policy-modes
3
+ * Enumerates exactly the four field modes the v1 policy defines.
4
+ * @evidenceReview docs/security/field-crypto-v1.md#field-policy-modes #d6936dd
5
+ * Compared the section's four modes with this union member by member.
6
+ */
1
7
  export type FieldMode = "plain" | "encrypt" | "encrypt+hash" | "mask";
2
8
  export type FieldCryptoFailMode = "closed" | "open";
3
9
  export type FieldCryptoOpenFallback = "masked" | "plaintext" | "null";
@@ -26,6 +32,14 @@ export interface KeySetState {
26
32
  decryptKids?: readonly string[];
27
33
  refreshedAt?: number;
28
34
  }
35
+ /**
36
+ * @evidence docs/security/field-crypto-v1.md#key-management
37
+ * Separates the active encrypt kid from the multi-kid decrypt set that
38
+ * key rotation relies on.
39
+ * @evidenceReview docs/security/field-crypto-v1.md#key-management #e297ee5
40
+ * Read the three bullets against this interface and the AES-GCM provider's
41
+ * decrypt, which tries every candidate kid before failing.
42
+ */
29
43
  export interface KeyResolver {
30
44
  resolveEncryptKey(context: FieldCryptoKeyContext): MaybePromise<{
31
45
  kid: string;
@@ -64,6 +78,18 @@ export interface FieldCryptoProvider {
64
78
  hash(input: FieldCryptoHashInput): MaybePromise<string>;
65
79
  mask?(input: FieldCryptoMaskInput): MaybePromise<string>;
66
80
  }
81
+ /**
82
+ * @evidence docs/security/field-crypto-v1.md#scope
83
+ * The one configuration contract consumed by core, the messaging tracking
84
+ * stores, and the webhook registry storage.
85
+ * @evidenceReview docs/security/field-crypto-v1.md#scope #3e5d08b
86
+ * Confirmed the messaging tracking stores and the webhook registry storage
87
+ * import this type.
88
+ * @evidenceExclude docs/security/field-crypto-v1.md#companion-docs
89
+ * Links to companion documents and states no implementable requirement.
90
+ * @evidenceExcludeReview docs/security/field-crypto-v1.md#companion-docs #a4cb34b
91
+ * Checked the section only links the other docs/security guides.
92
+ */
67
93
  export interface FieldCryptoConfig {
68
94
  enabled?: boolean;
69
95
  fields: Record<string, FieldMode>;
@@ -74,6 +100,12 @@ export interface FieldCryptoConfig {
74
100
  keyResolver?: KeyResolver;
75
101
  provider: FieldCryptoProvider;
76
102
  }
103
+ /**
104
+ * @evidence docs/security/field-crypto-v1.md#metrics
105
+ * Names exactly the six metrics the v1 policy lists.
106
+ * @evidenceReview docs/security/field-crypto-v1.md#metrics #db248ba
107
+ * Compared the section's six metric names with this union one by one.
108
+ */
77
109
  export type FieldCryptoMetricName = "crypto_encrypt_ms" | "crypto_decrypt_ms" | "crypto_fail_count" | "key_kid_usage" | "crypto_circuit_open_count" | "crypto_circuit_state";
78
110
  export type FieldCryptoCircuitState = "closed" | "open" | "half-open";
79
111
  export interface FieldCryptoControlScope {
@@ -107,6 +139,39 @@ export interface AesGcmFieldCryptoProviderOptions {
107
139
  hashKeyEncoding?: "utf8" | "base64url";
108
140
  algorithm?: "A256GCM";
109
141
  }
142
+ /**
143
+ * @evidence docs/security/field-crypto-v1.md#threat-model
144
+ * Encrypts with a fresh random IV and the caller's AAD as GCM additional
145
+ * data, and serves lookups from a separate HMAC instead of deterministic
146
+ * ciphertext. The plaintext and logging bullets are answered by
147
+ * fail-policy and logging-policy, and the webhook legacy AAD bullet by
148
+ * revealFieldValue in @k-msg/webhook.
149
+ * @evidenceReview docs/security/field-crypto-v1.md#threat-model #98761bf
150
+ * Read encrypt, decrypt, and hash: a 12-byte getRandomValues IV per call,
151
+ * AAD passed as additionalData on both paths, and HMAC-SHA-256 for hash.
152
+ * The messaging stores bind messageId, providerId, tableName, fieldPath, and
153
+ * tenantId by default; webhook storage, which encrypts one field per table,
154
+ * binds the table, the endpoint or delivery id, and the tenant when one is
155
+ * set.
156
+ */
110
157
  export declare function createAesGcmFieldCryptoProvider(options: AesGcmFieldCryptoProviderOptions): FieldCryptoProvider;
111
158
  export declare function createNoopFieldCryptoProvider(): FieldCryptoProvider;
159
+ /**
160
+ * Throws unless `value` is a v1 envelope: `v` 1, `alg` "A256GCM", and string
161
+ * `kid`, `iv`, `tag`, and `ct`.
162
+ *
163
+ * @evidence docs/security/field-crypto-v1.md#envelope-format
164
+ * Rejects any envelope object but v1 A256GCM before
165
+ * toCiphertextEnvelopeString persists it; the AES-GCM provider emits
166
+ * exactly this shape, and string ciphertext stays the provider's own.
167
+ * @evidenceReview docs/security/field-crypto-v1.md#envelope-format #5d88509
168
+ * Compared the section's keys and constants with this check and the
169
+ * AES-GCM provider's encrypt output, and ran envelope.test.ts, which
170
+ * rejects v 2, A128GCM, and a missing ct and keeps string ciphertext.
171
+ */
172
+ export declare function assertCryptoEnvelopeV1(value: unknown): asserts value is CryptoEnvelope;
173
+ /**
174
+ * Serializes provider ciphertext for storage. An envelope object must be a v1
175
+ * envelope; a string is the provider's own serialized form and is kept as is.
176
+ */
112
177
  export declare function toCiphertextEnvelopeString(ciphertext: string | CryptoEnvelope): string;
package/dist/index.cjs ADDED
@@ -0,0 +1,5 @@
1
+ var{defineProperty:j,getOwnPropertyNames:Xe,getOwnPropertyDescriptor:Ze}=Object,et=Object.prototype.hasOwnProperty;function tt(e){return this[e]}var rt=(e)=>{var t=(ue??=new WeakMap).get(e),r;if(t)return t;if(t=j({},"__esModule",{value:!0}),e&&typeof e==="object"||typeof e==="function"){for(var n of Xe(e))if(!et.call(t,n))j(t,n,{get:tt.bind(e,n),enumerable:!(r=Ze(e,n))||r.enumerable})}return ue.set(e,t),t},ue;var nt=(e)=>e;function ot(e,t){this[e]=nt.bind(null,t)}var it=(e,t)=>{for(var r in t)j(e,r,{get:t[r],enumerable:!0,configurable:!0,set:ot.bind(t,r)})};var ar={};it(ar,{BulkOperationHandler:()=>H,CircuitBreaker:()=>se,ErrorUtils:()=>w,FieldCryptoError:()=>_,KMSG_DELIVERY_STATUSES:()=>He,KMSG_MESSAGE_TYPES:()=>Je,KMSG_POLLABLE_STATUSES:()=>ce,KMSG_TERMINAL_STATUSES:()=>je,KMsgError:()=>C,KMsgErrorCode:()=>F,KNOWN_MESSAGE_STATUSES:()=>ir,LogLevel:()=>ze,Logger:()=>Y,QUEUED_MESSAGE_STATUS:()=>Qe,RateLimiter:()=>ae,Result:()=>jt,RetryHandler:()=>P,assertCryptoEnvelopeV1:()=>Ve,assertFieldCryptoConfig:()=>Kt,createAesGcmFieldCryptoProvider:()=>wt,createAwsKmsKeyResolver:()=>At,createDefaultMasker:()=>ne,createEnvKeyResolver:()=>kt,createLogger:()=>ie,createNoopFieldCryptoProvider:()=>Ft,createRefreshableKeyResolver:()=>I,createRollingKeyResolver:()=>Tt,createStaticKeyResolver:()=>ee,createVaultTransitKeyResolver:()=>Mt,fail:()=>le,getLogger:()=>K,getPollableStatuses:()=>rr,getRolloutKnownKids:()=>Q,getRuntimeEnvSource:()=>Ye,isCryptoEnvelope:()=>Ue,isKMsgDeliveryStatus:()=>Xt,isKMsgMessageType:()=>or,isKMsgTerminalStatus:()=>Zt,isPollableDeliveryStatus:()=>tr,isTerminalDeliveryStatus:()=>er,logger:()=>Yt,loggerMiddleware:()=>Ht,normalizeErrorRetryPolicy:()=>Me,normalizeMessageStatus:()=>sr,normalizePhoneForHash:()=>Be,normalizeProviderError:()=>mt,normalizeRetryAfterMs:()=>k,ok:()=>de,parseErrorRetryPolicyFromJson:()=>yt,readRuntimeEnv:()=>Wt,redactLogText:()=>D,resolveFieldCryptoFailMode:()=>Fe,resolveFieldCryptoOpenFallback:()=>Le,resolveFieldMode:()=>re,selectActiveKidByRollout:()=>B,setGlobalLogger:()=>Gt,toCiphertextEnvelopeString:()=>Lt,validateErrorRetryPolicy:()=>ke,validateFieldCryptoConfig:()=>Ie});module.exports=rt(ar);var F;((p)=>{p.INVALID_REQUEST="INVALID_REQUEST";p.AUTHENTICATION_FAILED="AUTHENTICATION_FAILED";p.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE";p.TEMPLATE_NOT_FOUND="TEMPLATE_NOT_FOUND";p.RATE_LIMIT_EXCEEDED="RATE_LIMIT_EXCEEDED";p.NETWORK_ERROR="NETWORK_ERROR";p.NETWORK_TIMEOUT="NETWORK_TIMEOUT";p.NETWORK_SERVICE_UNAVAILABLE="NETWORK_SERVICE_UNAVAILABLE";p.REQUEST_ABORTED="REQUEST_ABORTED";p.PROVIDER_ERROR="PROVIDER_ERROR";p.MESSAGE_SEND_FAILED="MESSAGE_SEND_FAILED";p.CRYPTO_CONFIG_ERROR="CRYPTO_CONFIG_ERROR";p.CRYPTO_ENCRYPT_FAILED="CRYPTO_ENCRYPT_FAILED";p.CRYPTO_DECRYPT_FAILED="CRYPTO_DECRYPT_FAILED";p.CRYPTO_HASH_FAILED="CRYPTO_HASH_FAILED";p.CRYPTO_POLICY_VIOLATION="CRYPTO_POLICY_VIOLATION";p.UNKNOWN_ERROR="UNKNOWN_ERROR"})(F||={});var st={["INVALID_REQUEST"]:{ko:"잘못된 요청입니다",en:"Invalid request"},["AUTHENTICATION_FAILED"]:{ko:"인증에 실패했습니다",en:"Authentication failed"},["INSUFFICIENT_BALANCE"]:{ko:"잔액이 부족합니다",en:"Insufficient balance"},["TEMPLATE_NOT_FOUND"]:{ko:"템플릿을 찾을 수 없습니다",en:"Template not found"},["RATE_LIMIT_EXCEEDED"]:{ko:"요청 한도를 초과했습니다",en:"Rate limit exceeded"},["NETWORK_ERROR"]:{ko:"네트워크 오류가 발생했습니다",en:"Network error"},["NETWORK_TIMEOUT"]:{ko:"네트워크 요청 시간이 초과되었습니다",en:"Network timeout"},["NETWORK_SERVICE_UNAVAILABLE"]:{ko:"서비스를 일시적으로 사용할 수 없습니다",en:"Service temporarily unavailable"},["REQUEST_ABORTED"]:{ko:"요청이 취소되었습니다",en:"Request aborted"},["PROVIDER_ERROR"]:{ko:"제공자 오류가 발생했습니다",en:"Provider error"},["MESSAGE_SEND_FAILED"]:{ko:"메시지 전송에 실패했습니다",en:"Message send failed"},["CRYPTO_CONFIG_ERROR"]:{ko:"암호화 설정 오류가 발생했습니다",en:"Crypto configuration error"},["CRYPTO_ENCRYPT_FAILED"]:{ko:"암호화에 실패했습니다",en:"Encryption failed"},["CRYPTO_DECRYPT_FAILED"]:{ko:"복호화에 실패했습니다",en:"Decryption failed"},["CRYPTO_HASH_FAILED"]:{ko:"해시 생성에 실패했습니다",en:"Hash generation failed"},["CRYPTO_POLICY_VIOLATION"]:{ko:"암호화 정책 위반이 발생했습니다",en:"Crypto policy violation"},["UNKNOWN_ERROR"]:{ko:"알 수 없는 오류가 발생했습니다",en:"Unknown error"}},at=new Set(Object.values(F)),pe=new Set(["NETWORK_ERROR","RATE_LIMIT_EXCEEDED","NETWORK_TIMEOUT","NETWORK_SERVICE_UNAVAILABLE","PROVIDER_ERROR","UNKNOWN_ERROR"]),ye=new Set(["INVALID_REQUEST","AUTHENTICATION_FAILED","INSUFFICIENT_BALANCE","TEMPLATE_NOT_FOUND","MESSAGE_SEND_FAILED","REQUEST_ABORTED","CRYPTO_CONFIG_ERROR","CRYPTO_ENCRYPT_FAILED","CRYPTO_DECRYPT_FAILED","CRYPTO_HASH_FAILED","CRYPTO_POLICY_VIOLATION"]),x=(e)=>{if(typeof e!=="number"||Number.isNaN(e)||!Number.isFinite(e))return;return Math.trunc(e)},k=(e)=>{let t=x(e);if(t===void 0||t<0)return;return t},dt=(e)=>{if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0},W=(e)=>typeof e==="string"?e.toLowerCase().trim():void 0,v=(e,t="safe")=>{if(typeof e==="string"){let r=e.trim().toUpperCase();return r.length>0?r:void 0}if(t==="compat"&&(typeof e==="number"||typeof e==="boolean"))return String(e).toUpperCase();return},fe=(e,t)=>e?.some((r)=>v(r)===t)??!1,lt=(e,t)=>{if(t.nonRetryableCodes?.includes(e))return"non_retryable";if(t.retryableCodes?.includes(e))return"retryable";return},ge=(e,t)=>{let r=v(e,"compat");if(!r)return;if(fe(t.nonRetryableStatuses,r))return"non_retryable";if(fe(t.retryableStatuses,r))return"retryable";return},T=(e)=>typeof e==="object"&&e!==null&&!Array.isArray(e),O=(e,t)=>{for(let r of t)if(r in e)return e[r];return},ct=(e)=>e.length>0?e:"$",ve=(e)=>e==="compat"?"compat":"safe",me=(e)=>{if(e>=500)return"retryable";if(e===408||e===425||e===429)return"retryable";return"non_retryable"},Ee=(e)=>{let t=e.toLowerCase();if(t.includes("timeout")||t.includes("temporar")||t.includes("network")||t.includes("retry"))return"retryable";return};class C extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(e,t,r,n={}){super(t);if(this.name="KMsgError",this.code=e,this.details=r,this.providerErrorCode=n.providerErrorCode,this.providerErrorText=n.providerErrorText,this.httpStatus=x(n.httpStatus),this.requestId=typeof n.requestId==="string"?n.requestId:void 0,this.retryAfterMs=x(n.retryAfterMs),this.attempt=x(n.attempt),Array.isArray(n.causeChain))this.causeChain=n.causeChain;else if(n.causeChain!==void 0)this.causeChain=[n.causeChain];let o=Error.captureStackTrace;if(o)o(this,C)}getLocalizedMessage(e="ko"){let t=st[this.code];if(t?.[e])return t[e];return this.message}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details,providerErrorCode:this.providerErrorCode,providerErrorText:this.providerErrorText,httpStatus:this.httpStatus,requestId:this.requestId,retryAfterMs:this.retryAfterMs,attempt:this.attempt,causeChain:this.causeChain}}}var A=(e,t)=>{let r=x(e);if(r!==void 0)return r;if(t==="compat"&&typeof e==="string"){let n=Number(e.trim());if(Number.isFinite(n))return Math.trunc(n)}return},J=(e,t)=>{let r=dt(e);if(r)return r;if(t==="compat"&&(typeof e==="number"||typeof e==="boolean"))return String(e);return},Te=(e)=>{if(typeof e!=="string")return;let t=e.trim().toUpperCase();if(!at.has(t))return;return t},R=(e,t)=>{e.push({...t,path:ct(t.path)})},Ae=(e,t,r,n,o)=>{if(e===void 0)return[];let i=(()=>{if(Array.isArray(e))return e;if(r==="compat"&&typeof e==="string")return e.split(",").map((a)=>a.trim()).filter((a)=>a.length>0);return R(n,{code:"invalid_type",message:`expected array of ${o.label} values`,path:t}),[]})(),s=[],d=new Set;for(let a=0;a<i.length;a+=1){let l=i[a],c=o.normalize(l);if(!c){R(n,{code:o.label==="code"?"unknown_code":"invalid_status",message:`invalid retry policy ${o.label}: ${String(l)}`,path:`${t}[${a}]`});continue}if(d.has(c)){R(n,{code:o.label==="code"?"duplicate_code":"duplicate_status",message:`duplicate retry policy ${o.label}: ${c}`,path:`${t}[${a}]`});continue}d.add(c),s.push(c)}return s},he=(e,t,r,n)=>Ae(e,t,r,n,{label:"code",normalize:(o)=>Te(v(o,r))}),Ce=(e,t,r,n)=>Ae(e,t,r,n,{label:"status",normalize:(o)=>v(o,r)}),xe=(e,t,r,n)=>{if(e===void 0)return;let o=k(A(e,r));if(o!==void 0)return o;R(n,{code:"invalid_retry_after",message:`invalid retry delay: ${String(e)}`,path:t});return},Re=(e,t,r,n)=>{if(e===void 0)return;if(!T(e)){R(n,{code:"invalid_type",message:"expected retry delay map",path:t});return}let o={},i=new Set;for(let[s,d]of Object.entries(e)){let a=v(s,"safe"),l=`${t}.${s}`;if(!a){R(n,{code:"invalid_key",message:"retry delay map key must not be empty",path:l});continue}if(i.has(a)){R(n,{code:"duplicate_key",message:`duplicate retry delay map key: ${a}`,path:l});continue}let c=xe(d,l,r,n);if(c===void 0)continue;i.add(a),o[a]=c}return Object.keys(o).length>0?o:void 0},ut=(e,t,r)=>{if(e===void 0)return;if(typeof e==="function")return e;if(!T(e)){R(r,{code:"invalid_type",message:"expected retry delay resolver or policy object",path:"retryAfterMs"});return}let n=new Set(["defaultMs","byCode","byStatus"]);for(let d of Object.keys(e)){if(n.has(d))continue;R(r,{code:"unknown_field",message:`unknown retry-after policy field: ${d}`,path:`retryAfterMs.${d}`})}let o=xe(e.defaultMs,"retryAfterMs.defaultMs",t,r),i=Re(e.byCode,"retryAfterMs.byCode",t,r),s=Re(e.byStatus,"retryAfterMs.byStatus",t,r);if(o===void 0&&i===void 0&&s===void 0)return;return{...o!==void 0?{defaultMs:o}:{},...i!==void 0?{byCode:i}:{},...s!==void 0?{byStatus:s}:{}}},pt=(e,t,r)=>{if(e===void 0)return;if(typeof e==="string"){let n=e.trim().toLowerCase();if(n==="retryable")return"retryable";if(n==="non_retryable"||n==="non-retryable")return"non_retryable"}if(t==="compat"&&typeof e==="boolean")return e?"retryable":"non_retryable";R(r,{code:"invalid_fallback",message:`invalid fallback value: ${String(e)}`,path:"fallback"});return};function ke(e,t={}){let r=ve(t.mode),n=[];if(!T(e))return R(n,{code:"invalid_root",message:"retry policy must be an object",path:"$"}),{policy:null,issues:n};let o=new Set(["retryableCodes","nonRetryableCodes","retryableStatuses","nonRetryableStatuses","fallback","retryAfterMs"]);for(let p of Object.keys(e)){if(o.has(p))continue;R(n,{code:"unknown_field",message:`unknown retry policy field: ${p}`,path:p})}let i=he(e.retryableCodes,"retryableCodes",r,n),s=he(e.nonRetryableCodes,"nonRetryableCodes",r,n),d=Ce(e.retryableStatuses,"retryableStatuses",r,n),a=Ce(e.nonRetryableStatuses,"nonRetryableStatuses",r,n),l=pt(e.fallback,r,n),c=ut(e.retryAfterMs,r,n),y=new Set(i),f=new Set(s);for(let p of y){if(!f.has(p))continue;y.delete(p),R(n,{code:"conflicting_code",message:`code '${p}' is both retryable and nonRetryable; nonRetryable wins`,path:"retryableCodes"})}let g=new Set(d),E=new Set(a);for(let p of g){if(!E.has(p))continue;g.delete(p),R(n,{code:"conflicting_status",message:`status '${p}' is both retryable and nonRetryable; nonRetryable wins`,path:"retryableStatuses"})}let h={...y.size>0?{retryableCodes:Array.from(y)}:{},...f.size>0?{nonRetryableCodes:Array.from(f)}:{},...g.size>0?{retryableStatuses:Array.from(g)}:{},...E.size>0?{nonRetryableStatuses:Array.from(E)}:{},...l?{fallback:l}:{},...c?{retryAfterMs:c}:{}};return{policy:h.retryableCodes!==void 0||h.nonRetryableCodes!==void 0||h.retryableStatuses!==void 0||h.nonRetryableStatuses!==void 0||h.fallback!==void 0||h.retryAfterMs!==void 0?h:null,issues:n}}function Me(e,t={}){return ke(e,t).policy}function yt(e,t={}){if(typeof e!=="string"||e.trim().length===0)return null;try{let r=JSON.parse(e);return Me(r,t)}catch{return null}}var Se=(e,t)=>{let r=e.response;if(!T(r))return;return A(O(r,["status","statusCode","httpStatus"]),t)},ft=(e,t)=>{if(e instanceof C&&Array.isArray(e.causeChain))return e.causeChain.slice();if(T(e)){let i=e.causeChain;if(Array.isArray(i))return i.slice();let s=e.details;if(t==="compat"&&T(s)){let d=s.causeChain;if(Array.isArray(d))return d.slice();if(d!==void 0)return[d]}}let r=[],n=new Set,o=e;for(let i=0;i<8;i+=1){if(!T(o))break;let s=o.cause;if(s===void 0||n.has(s))break;n.add(s),r.push(s),o=s}return r.length>0?r:void 0},gt=(e)=>{if(e instanceof Error&&typeof e.message==="string")return e.message;if(T(e)&&typeof e.message==="string")return e.message;return typeof e==="string"?e:"Unknown error"},be=(e,t)=>{let r=v(t,"compat");if(!e||!r)return;if(Object.hasOwn(e,r))return k(e[r]);for(let[n,o]of Object.entries(e)){if(v(n)!==r)continue;return k(o)}return},Oe=(e,t)=>{let r=t?.retryAfterMs;if(typeof r==="function"){let d=k(r(e));if(d!==void 0)return{value:d,source:"policy"}}let n=k(e.retryAfterMs);if(n!==void 0)return{value:n,source:"input"};if(!r||typeof r==="function")return{};let o=[e.providerErrorCode,e.code];for(let d of o){let a=be(r.byCode,d);if(a!==void 0)return{value:a,source:"policy"}}let i=be(r.byStatus,e.httpStatus);if(i!==void 0)return{value:i,source:"policy"};let s=k(r.defaultMs);return s!==void 0?{value:s,source:"policy"}:{}};function mt(e,t={}){let r=ve(t.mode),o=t.defaultCode??"UNKNOWN_ERROR",i={code:"fallback",classification:t.policy?"policy":"fallback"},s,d,a,l,c,y,f,g=(u)=>{if(u.providerErrorCode!==void 0)s=u.providerErrorCode,i.providerErrorCode="metadata";if(u.providerErrorText!==void 0)d=u.providerErrorText,i.providerErrorText="metadata";if(u.httpStatus!==void 0)a=u.httpStatus,i.httpStatus="metadata";if(u.requestId!==void 0)l=u.requestId,i.requestId="metadata";if(u.retryAfterMs!==void 0)c=k(u.retryAfterMs),i.retryAfterMs="metadata";if(u.attempt!==void 0)y=A(u.attempt,r),i.attempt="metadata";if(Array.isArray(u.causeChain))f=u.causeChain.slice(),i.causeChain="metadata"},E=(u,b)=>{if(s===void 0){let m=J(O(u,["providerErrorCode","errorCode","resultCode"]),r);if(m!==void 0)s=m,i.providerErrorCode=b}if(d===void 0){let m=J(O(u,["providerErrorText","errorMessage","msg","message"]),r);if(m!==void 0)d=m,i.providerErrorText=b}if(a===void 0){let m=A(O(u,["httpStatus","statusCode","status"]),r)??Se(u,r);if(m!==void 0)a=m,i.httpStatus=b==="details"?"details":"http"}if(l===void 0){let m=J(O(u,["requestId","request_id","reqId","traceId"]),r);if(m!==void 0)l=m,i.requestId=b}if(c===void 0){let m=k(A(O(u,["retryAfterMs","retry_after_ms","retryAfter"]),r));if(m!==void 0)c=m,i.retryAfterMs=b}if(y===void 0){let m=A(u.attempt,r);if(m!==void 0&&m>0)y=m,i.attempt=b}};if(e instanceof C){if(o=e.code,i.code="input",g(e),r==="compat"&&T(e.details))E(e.details,"details")}else if(T(e)){let u=Te(O(e,["code","errorCode","resultCode"]));if(u!==void 0)o=u,i.code="input";else if(a===void 0){let b=A(O(e,["httpStatus","statusCode","status"]),r)??Se(e,r);if(b!==void 0&&b>=500)o="PROVIDER_ERROR",i.code="http"}if(E(e,"input"),r==="compat"&&T(e.details))E(e.details,"details")}if(f===void 0){let u=ft(e,r);if(u!==void 0)f=u,i.causeChain="input"}if(t.attempt!==void 0&&A(t.attempt,r)!==void 0){let u=A(t.attempt,r);if(u!==void 0&&u>0)y=u,i.attempt="input"}let h=new C(o,gt(e),void 0,{providerErrorCode:s,providerErrorText:d,httpStatus:a,requestId:l,retryAfterMs:c,attempt:y,causeChain:f}),S=Oe(h,t.policy);if(S.value!==void 0){if(c=S.value,S.source==="policy")i.retryAfterMs="policy"}let p=w.classifyForRetry(h,t.policy);return{code:o,classification:p,...s!==void 0?{providerErrorCode:s}:{},...d!==void 0?{providerErrorText:d}:{},...a!==void 0?{httpStatus:a}:{},...l!==void 0?{requestId:l}:{},...c!==void 0?{retryAfterMs:c}:{},...y!==void 0?{attempt:y}:{},...f!==void 0?{causeChain:f}:{},sources:i}}var w={isRetryable(e,t={}){return w.classifyForRetry(e,t)==="retryable"},classifyForRetry(e,t={}){if(e instanceof C){let a=lt(e.code,t);if(a)return a;let l=ge(e.httpStatus,t);if(l)return l;if(new Set(t.retryableCodes??Array.from(pe)).has(e.code))return"retryable";if(new Set(t.nonRetryableCodes??Array.from(ye)).has(e.code))return"non_retryable";if(e.httpStatus!==void 0)return me(e.httpStatus);let f=Ee(e.message);if(f)return f;if(t.classifyByMessage&&e.message){let g=t.classifyByMessage(e.message);if(g)return g}if(t.fallback)return t.fallback;return"non_retryable"}let r=e&&typeof e==="object"?e:void 0,n=v(r?.status,"compat")??v(r?.statusCode,"compat")??v(r?.httpStatus,"compat")??v(r?.code,"compat"),o=W(r?.status)??W(r?.statusCode)??W(r?.code),i=x(r?.status)??x(r?.statusCode)??x(r?.httpStatus),s=ge(n,t);if(s)return s;if(o?.startsWith("5"))return"retryable";if(i!==void 0){if(t.classifyByStatusCode)return t.classifyByStatusCode(i);return me(i)}let d=typeof r?.message==="string"?Ee(r.message):void 0;if(d)return d;if(t.classifyByMessage&&typeof r?.message==="string"){let a=t.classifyByMessage(r.message);if(a)return a}return t.fallback??"non_retryable"},resolveRetryAfterMs(e,t){return Oe(e,t).value},isUnknownStatus:(e)=>{if(e===void 0||Number.isNaN(e)||!Number.isFinite(e))return!1;return e<500},toRetryMetadata(e){return{providerErrorCode:e.providerErrorCode,providerErrorText:e.providerErrorText,httpStatus:e.httpStatus,requestId:e.requestId,retryAfterMs:e.retryAfterMs,attempt:e.attempt,causeChain:e.causeChain}},withAttempt(e,t){return new C(e.code,e.message,e.details,{...w.toRetryMetadata(e),attempt:x(t)})},DEFAULT_RETRYABLE_ERROR_CODES:pe,DEFAULT_NON_RETRYABLE_ERROR_CODES:ye};function Et(e){switch(e){case"config":return"CRYPTO_CONFIG_ERROR";case"encrypt":return"CRYPTO_ENCRYPT_FAILED";case"decrypt":return"CRYPTO_DECRYPT_FAILED";case"hash":return"CRYPTO_HASH_FAILED";case"policy":return"CRYPTO_POLICY_VIOLATION"}}class _ extends C{kind;fieldPath;failMode;openFallback;constructor(e,t,r,n={}){super(Et(e),t,r,n);this.name="FieldCryptoError",this.kind=e,this.fieldPath=typeof n.fieldPath==="string"?n.fieldPath:void 0,this.failMode=n.failMode,this.openFallback=n.openFallback}toJSON(){return{...super.toJSON(),kind:this.kind,fieldPath:this.fieldPath,failMode:this.failMode,openFallback:this.openFallback}}}var ht=["tenantId","providerId","messageId"];function U(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function Ct(e){if(typeof e!=="number"||!Number.isFinite(e))return;if(e<=0||e>100)return;return e}function Ke(e){let t=[];for(let r of e){let n=U(r.kid),o=Ct(r.percentage);if(!n||o===void 0)continue;t.push({kid:n,percentage:o})}return t}function Rt(e,t,r){let n=t.map((o)=>{let i=e[o];return typeof i==="string"?i:""}).join("|");return`${r}::${n}`}function St(e){let t=2166136261;for(let r=0;r<e.length;r+=1)t^=e.charCodeAt(r),t=t*16777619>>>0;return t>>>0}function bt(e,t){let r=0;for(let n of e)if(r+=n.percentage,t<r)return n.kid;return}function B(e,t,r){let n=Ke(t.buckets),o=U(t.defaultKid)??U(r);if(n.length===0)return o;let i=U(t.seed)??"kmsg-rollout-v1",s=t.stickyFields??ht,d=Rt(e,s,i),a=St(d)%100;return bt(n,a)??o}function Q(e){return Ke(e.buckets).map((t)=>t.kid)}function L(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function X(e){if(!Array.isArray(e))return[];return e.map((t)=>L(t)).filter((t)=>Boolean(t))}function Z(e){let t=[],r=new Set;for(let n of e){let o=L(n);if(!o||r.has(o))continue;r.add(o),t.push(o)}return t}function vt(e){return L(e.providerId)??"default"}function ee(e){let t=L(e.activeKid)??"default",r=Z([t,...X(e.decryptKids)]);return{async resolveEncryptKey(){return{kid:t}},async resolveDecryptKeys(){return r}}}function I(e){let t=typeof e.cacheTtlMs==="number"&&e.cacheTtlMs>=0?Math.trunc(e.cacheTtlMs):30000,r=L(e.fallback?.activeKid),n=X(e.fallback?.decryptKids),o;async function i(s){let d=Date.now();if(o&&d<o.expiresAt)return o.value;let a=await e.provider.loadKeySet(s),l=L(a.activeKid)??r??vt(s),c=Z([l,...X(a.decryptKids),...n]),y={activeKid:l,decryptKids:c,refreshedAt:Date.now()};return o={value:y,expiresAt:Date.now()+t},y}return{async resolveEncryptKey(s){return{kid:(await i(s)).activeKid}},async resolveDecryptKeys(s){let d=await i(s);return d.decryptKids??[d.activeKid]}}}function Tt(e,t){return{async resolveEncryptKey(r){let n=await e.resolveEncryptKey(r);return{kid:B(r,t,n.kid)??n.kid}},async resolveDecryptKeys(r){let n=await e.resolveEncryptKey(r),o=e.resolveDecryptKeys?await e.resolveDecryptKeys(r):[n.kid],i=B(r,t,n.kid),s=Q(t);return Z([...i?[i]:[],n.kid,...o??[],...s])}}}function At(e){return I({provider:{async loadKeySet(r){return e.client.getKeyState({...r,...e.keyAlias?{keyAlias:e.keyAlias}:{},...e.region?{region:e.region}:{}})}},cacheTtlMs:e.cacheTtlMs,fallback:{activeKid:e.fallbackActiveKid,decryptKids:e.fallbackDecryptKids}})}function V(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function _e(e,t){return V(e[t])}function xt(e,t){if(!e)return[];return e.split(t).map((r)=>V(r)).filter((r)=>Boolean(r))}function kt(e={}){let t=globalThis.process?.env,r=e.env??t??{},n=V(e.delimiter)??",",o=e.activeKidEnv??"KMSG_ACTIVE_KID",i=e.decryptKidsEnv??"KMSG_DECRYPT_KIDS",s=_e(r,o)??V(e.fallbackActiveKid)??"default",d=[s,...xt(_e(r,i),n),...e.fallbackDecryptKids??[]];return ee({activeKid:s,decryptKids:d})}function Mt(e){return I({provider:{async loadKeySet(r){return e.client.getKeyState({...r,...e.mountPath?{mountPath:e.mountPath}:{},...e.keyName?{keyName:e.keyName}:{},...e.namespace?{namespace:e.namespace}:{}})}},cacheTtlMs:e.cacheTtlMs,fallback:{activeKid:e.fallbackActiveKid,decryptKids:e.fallbackDecryptKids}})}function te(e){return typeof e==="function"}function Pe(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function re(e,t,r){let n=e.fields[t];if(n)return n;if(t.startsWith("metadata.")){let o=e.fields["metadata.*"];if(o)return o}return r}var Ot=["closed","open"],we=["masked","plaintext","null"];function Fe(e){return e.failMode==="open"?"open":"closed"}function Le(e){let t=e.openFallback;return t!==void 0&&we.includes(t)?t:"masked"}function Ie(e,t={}){let r=[];if(!e||typeof e!=="object")return{valid:!1,issues:[{message:"fieldCrypto config must be an object",rule:"fieldCrypto.config.object",hint:"Provide a valid FieldCryptoConfig object"}]};if(!e.provider||typeof e.provider!=="object")r.push({message:"fieldCrypto provider is required",rule:"fieldCrypto.provider.required",path:"provider",hint:"Set provider with encrypt/decrypt/hash methods"});else{if(!te(e.provider.encrypt))r.push({message:"provider.encrypt must be a function",rule:"fieldCrypto.provider.encrypt.required",path:"provider.encrypt"});if(!te(e.provider.decrypt))r.push({message:"provider.decrypt must be a function",rule:"fieldCrypto.provider.decrypt.required",path:"provider.decrypt"});if(!te(e.provider.hash))r.push({message:"provider.hash must be a function",rule:"fieldCrypto.provider.hash.required",path:"provider.hash"})}if(!e.fields||typeof e.fields!=="object")r.push({message:"fieldCrypto.fields must be an object",rule:"fieldCrypto.fields.object",path:"fields",hint:"Define policies such as to, from, metadata.phoneNumber"});else{let i=Object.entries(e.fields);if(i.length===0)r.push({message:"fieldCrypto.fields must not be empty",rule:"fieldCrypto.fields.non_empty",path:"fields",hint:"Add at least one field mode mapping"});for(let[s,d]of i){if(!Pe(s))r.push({message:"field path must be a non-empty string",rule:"fieldCrypto.fields.path.non_empty",path:"fields"});if(d!=="plain"&&d!=="encrypt"&&d!=="encrypt+hash"&&d!=="mask")r.push({message:`unsupported field mode: ${String(d)}`,rule:"fieldCrypto.fields.mode.supported",path:`fields.${s}`})}}if(e.failMode!==void 0&&!Ot.includes(e.failMode))r.push({message:`unsupported failMode: ${String(e.failMode)}`,rule:"fieldCrypto.fail_mode.supported",path:"failMode",hint:'Use "closed" (default) or "open"'});if(e.openFallback!==void 0&&!we.includes(e.openFallback))r.push({message:`unsupported openFallback: ${String(e.openFallback)}`,rule:"fieldCrypto.open_fallback.supported",path:"openFallback",hint:'Use "masked" (default), "null", or "plaintext"'});let n=Fe(e),o=Le(e);if(n==="open"&&o==="plaintext"&&e.unsafeAllowPlaintextStorage!==!0)r.push({message:"openFallback=plaintext requires unsafeAllowPlaintextStorage=true",rule:"fieldCrypto.fail_open.plaintext_guard",path:"openFallback",hint:"Use masked/null fallback, or explicitly enable unsafe plaintext"});if(Array.isArray(e.aadFields)){if(e.aadFields.length===0)r.push({message:"aadFields must not be empty when provided",rule:"fieldCrypto.aad_fields.non_empty",path:"aadFields"});for(let i=0;i<e.aadFields.length;i+=1){let s=e.aadFields[i];if(!Pe(s))r.push({message:"aadFields cannot include empty key",rule:"fieldCrypto.aad_fields.no_empty_key",path:`aadFields[${i}]`})}}if(t.secureMode&&!t.compatPlainColumns){let i=re(e,"to","encrypt+hash"),s=re(e,"from","encrypt+hash");if(i==="plain")r.push({message:"secure mode requires non-plain policy for `to` when compatPlainColumns=false",rule:"fieldCrypto.secure_mode.to_non_plain",path:"fields.to",hint:"Use encrypt+hash for lookup fields"});if(s==="plain")r.push({message:"secure mode requires non-plain policy for `from` when compatPlainColumns=false",rule:"fieldCrypto.secure_mode.from_non_plain",path:"fields.from",hint:"Use encrypt+hash for lookup fields"})}return{valid:r.length===0,issues:r}}function Kt(e,t={}){let r=Ie(e,t);if(r.valid)return;let n=r.issues[0];if(!n)throw new _("config","fieldCrypto config validation failed",{rule:"fieldCrypto.config.invalid",issues:r.issues});throw new _("config",n.message,{rule:n.rule,path:n.path,hint:n.hint,issues:r.issues},{fieldPath:n.path})}function z(e){let t=e instanceof Uint8Array?e:new Uint8Array(e),r=typeof globalThis<"u"?globalThis.Buffer:void 0;return(r?r.from(t).toString("base64"):btoa(String.fromCharCode(...t))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function q(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),r=t.length%4===0?t:`${t}${"=".repeat(4-t.length%4)}`,n=typeof globalThis<"u"?globalThis.Buffer:void 0;if(n)return new Uint8Array(n.from(r,"base64"));let o=atob(r),i=new Uint8Array(o.length);for(let s=0;s<o.length;s+=1)i[s]=o.charCodeAt(s);return i}function Ne(e,t){if(e instanceof Uint8Array)return e;if(e instanceof ArrayBuffer)return new Uint8Array(e);if(t==="base64url")return q(e);return new TextEncoder().encode(e)}function _t(e){let t=e instanceof Uint8Array?e:new Uint8Array(e);return Array.from(t).map((r)=>r.toString(16).padStart(2,"0")).join("")}function M(e){let t=new Uint8Array(e.byteLength);return t.set(e),t.buffer}function De(e){let t=JSON.parse(e);if(!t||typeof t!=="object"||typeof t.v!=="number"||typeof t.alg!=="string"||typeof t.kid!=="string"||typeof t.iv!=="string"||typeof t.tag!=="string"||typeof t.ct!=="string")throw Error("Invalid ciphertext envelope");return t}function Pt(e){if(typeof e==="string")return e;return JSON.stringify(e)}function Ue(e){if(!e||typeof e!=="object")return!1;let t=e;return typeof t.v==="number"&&typeof t.alg==="string"&&typeof t.kid==="string"&&typeof t.iv==="string"&&typeof t.tag==="string"&&typeof t.ct==="string"}function Be(e){let t=String(e??"").trim();if(t.length===0)return"";let r=t.startsWith("+"),n=t.replace(/\D/g,"");return r?`+${n}`:n}function ne(e=3,t=2){return(r)=>{let n=String(r??"");if(n.length<=e+t)return"*".repeat(Math.max(0,n.length));let o=n.slice(0,e),i=n.slice(-t);return`${o}${"*".repeat(n.length-e-t)}${i}`}}function wt(e){let t=e.algorithm??"A256GCM",r=e.keyEncoding??"base64url",n=e.hashKeyEncoding??r,o=new Map,i=new Map,s=(a)=>{let l=o.get(a);if(l)return l;let c=e.keys[a];if(!c)throw Error(`Unknown encryption key id: ${a}`);let y=Ne(c,r),f=crypto.subtle.importKey("raw",M(y),"AES-GCM",!1,["encrypt","decrypt"]);return o.set(a,f),f},d=(a)=>{let l=i.get(a);if(l)return l;let c=e.hashKeys?.[a]??e.keys[a];if(!c)throw Error(`Unknown hash key id: ${a}`);let y=Ne(c,n),f=crypto.subtle.importKey("raw",M(y),{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return i.set(a,f),f};return{async encrypt(a){let l=a.kid??e.activeKid,c=await s(l),y=crypto.getRandomValues(new Uint8Array(12)),f=new TextEncoder().encode(JSON.stringify(a.aad??{})),g=new TextEncoder().encode(a.value),E=await crypto.subtle.encrypt({name:"AES-GCM",iv:M(y),additionalData:M(f),tagLength:128},c,M(g)),h=new Uint8Array(E),S=h.slice(h.length-16),p=h.slice(0,h.length-16);return{ciphertext:{v:1,alg:t,kid:l,iv:z(y),tag:z(S),ct:z(p)},kid:l}},async decrypt(a){let l=De(a.ciphertext),c=a.candidateKids&&a.candidateKids.length>0?a.candidateKids:[l.kid],y=q(l.iv),f=q(l.tag),g=q(l.ct),E=new Uint8Array(g.length+f.length);E.set(g,0),E.set(f,g.length);let h=new TextEncoder().encode(JSON.stringify(a.aad??{})),S;for(let p of c)try{let u=await s(p),b=await crypto.subtle.decrypt({name:"AES-GCM",iv:M(y),additionalData:M(h),tagLength:128},u,M(E));return new TextDecoder().decode(new Uint8Array(b))}catch(u){S=u}throw Error(`Failed to decrypt ciphertext: ${S instanceof Error?S.message:String(S??"unknown")}`)},async hash(a){let l=a.kid??e.activeKid,c=await d(l),y=await crypto.subtle.sign("HMAC",c,M(new TextEncoder().encode(a.value)));return _t(y)},mask(a){return ne()(a.value)}}}function Ft(){return{encrypt(e){return{ciphertext:JSON.stringify({v:1,alg:"NOOP",kid:"noop",iv:"",tag:"",ct:e.value})}},decrypt(e){try{return De(e.ciphertext).ct}catch{return e.ciphertext}},hash(e){let t=Be(e.value);return z(new TextEncoder().encode(t))},mask(e){return ne()(e.value)}}}function Ve(e){let t=Ue(e);if(t&&e.v===1&&e.alg==="A256GCM")return;let r=e&&typeof e==="object"?e:{};throw new _("policy","ciphertext envelope must be v1 A256GCM with string kid, iv, tag, and ct",{rule:"fieldCrypto.envelope.v1",shapeValid:t,v:r.v,alg:r.alg})}function Lt(e){if(typeof e==="string")return e;Ve(e);let{v:t,alg:r,kid:n,iv:o,tag:i,ct:s}=e;return Pt({v:t,alg:r,kid:n,iv:o,tag:i,ct:s})}var ze;((o)=>{o.DEBUG="DEBUG";o.INFO="INFO";o.WARN="WARN";o.ERROR="ERROR"})(ze||={});var It=["to","from","phone","phoneNumber","recipient","sender","secret","apiKey","apiSecret","authorization","auth","token","password","payload","message","content","text"],N=String.raw`\w.[\]"'-`,Nt=new RegExp(String.raw`^[${N}]*(?:(?:secret|password|passwd|passphrase|token|credential|private[-_.]?key|api[-_.]?key)[${N}]*|auth(?:orization)?(?:[.[\]"'][${N}]*)?)$`,"i");function qe(e){return Nt.test(e.replace(/\s+/g,"_"))}function Dt(e){if(qe(e))return!0;let t=e.toLowerCase();return It.some((r)=>t.includes(r.toLowerCase()))}function Ge(e){let t=e.trim();if(t.length<=4)return"***";if(t.includes("@")){let[o,i]=t.split("@");return`${o.slice(0,2)}${"*".repeat(Math.max(1,o.length-2))}@${i}`}let r=t.slice(0,3),n=t.slice(-2);return`${r}${"*".repeat(Math.max(1,t.length-5))}${n}`}var Ut=new RegExp([String.raw`(?:\+82[-.\s]?(?:\(0\)[-.\s]?|0)?|0)(?:1[016789]|2|70|80|50\d|[3-6]\d)[-.\s]?\d{3,4}[-.\s]?\d{4}`,String.raw`\(0\d{1,2}\)[-.\s]?\d{3,4}[-.\s]?\d{4}`,String.raw`1[5-9]\d{2}[-\s]\d{4}`].map((e)=>String.raw`(?<![\w+])${e}(?!\w)`).join("|"),"g"),Bt=/(\b[a-z][\w+.-]{0,31}:\/\/[^\s/:@]*):[^\s/?#]*@/gi,Vt=[String.raw`"(?:\\.|[^"\\\n])*"?`,String.raw`'(?:\\.|[^'\\\n])*'?`,String.raw`\\"(?:\\\\(?:\\.|[^\\\n])|\\[^"\\\n]|[^\\\n])*(?:\\")?`,String.raw`\\'(?:\\\\(?:\\.|[^\\\n])|\\[^'\\\n]|[^\\\n])*(?:\\')?`],$t=new RegExp(String.raw`(?<![${N}])((?:["']?(?:api|private)[ \t]+)?[${N}]+)((?:\\?["'])?\s*[:=]\s*)`,"gi"),$e=new RegExp(String.raw`${Vt.join("|")}|((?:Bearer|Basic)\s+)?[^\s"',;&]+`,"iy");function zt(e){let t="",r=0;for(let n of e.matchAll($t)){let[o,i=""]=n;if(n.index<r||!qe(i))continue;let s=n.index+o.length;$e.lastIndex=s;let d=$e.exec(e);if(!d)continue;let a=/^\\?["']/.exec(d[0])?.[0];t+=e.slice(r,s),t+=a?`${a}[REDACTED]${a}`:`${d[1]??""}[REDACTED]`,r=s+d[0].length}return t+e.slice(r)}function D(e){return zt(e.replace(Bt,"$1:[REDACTED]@").replace(Ut,(t)=>Ge(t)))}function oe(e,t){if(t===void 0||t===null)return t;if(Dt(e)){if(typeof t==="string")return Ge(t);if(typeof t==="number"||typeof t==="boolean")return"***";if(Array.isArray(t))return"[REDACTED]";if(typeof t==="object")return"[REDACTED]"}if(Array.isArray(t))return t.map((r)=>oe(e,r));if(typeof t==="object"){let r={};for(let[n,o]of Object.entries(t))r[n]=oe(n,o);return r}if(typeof t==="string")return D(t);return t}function qt(e){let t={};for(let[r,n]of Object.entries(e))t[r]=oe(r,n);return t}class Y{config;context;constructor(e={},t={}){this.context=e,this.config={level:"INFO",enableConsole:!0,enableJson:!1,enableColors:!0,...t}}shouldLog(e){let t=["DEBUG","INFO","WARN","ERROR"];return t.indexOf(e)>=t.indexOf(this.config.level)}formatMessage(e){let t=qt(e.context),r=D(e.message),n=e.error&&{name:e.error.name,message:D(e.error.message),stack:e.error.stack?D(e.error.stack):void 0};if(this.config.enableJson)return JSON.stringify({level:e.level,message:r,timestamp:e.timestamp.toISOString(),context:t,...n&&{error:n},...e.duration&&{duration:e.duration}});let o=e.timestamp.toISOString(),i=this.config.enableColors?this.colorizeLevel(e.level):e.level,s=Object.keys(t).length>0?` [${Object.entries(t).map(([a,l])=>`${a}=${l}`).join(", ")}]`:"",d=`${o} ${i}${s}: ${r}`;if(e.duration!==void 0)d+=` (${e.duration}ms)`;if(n)d+=`
2
+ ${n.stack??`${n.name}: ${n.message}`}`;return d}colorizeLevel(e){if(!this.config.enableColors)return e;return`${{["DEBUG"]:"\x1B[36m",["INFO"]:"\x1B[32m",["WARN"]:"\x1B[33m",["ERROR"]:"\x1B[31m"}[e]}${e}\x1B[0m`}writeLog(e){if(!this.shouldLog(e.level))return;let t=this.formatMessage(e);if(this.config.enableConsole)(e.level==="ERROR"?console.error:e.level==="WARN"?console.warn:console.log)(t);if(this.config.enableFile&&this.config.filePath);}debug(e,t={}){this.writeLog({level:"DEBUG",message:e,timestamp:new Date,context:{...this.context,...t}})}info(e,t={}){this.writeLog({level:"INFO",message:e,timestamp:new Date,context:{...this.context,...t}})}warn(e,t={},r){this.writeLog({level:"WARN",message:e,timestamp:new Date,context:{...this.context,...t},error:r})}error(e,t={},r){this.writeLog({level:"ERROR",message:e,timestamp:new Date,context:{...this.context,...t},error:r})}child(e){return new Y({...this.context,...e},this.config)}time(e){let t=Date.now();return()=>{let r=Date.now()-t;this.info(`${e} completed`,{duration:r})}}async measure(e,t,r={}){let n=Date.now(),o={...r,operation:e};this.debug(`Starting ${e}`,o);try{let i=await t(),s=Date.now()-n;return this.info(`Completed ${e}`,{...o,duration:s}),i}catch(i){let s=Date.now()-n;throw this.error(`Failed ${e}`,{...o,duration:s},i instanceof Error?i:Error(String(i))),i}}}var G;function ie(e,t){return new Y(e,t)}function K(){if(!G)G=ie();return G}function Gt(e){G=e}var Yt={debug:(e,t)=>K().debug(e,t),info:(e,t)=>K().info(e,t),warn:(e,t,r)=>K().warn(e,t,r),error:(e,t,r)=>K().error(e,t,r),child:(e)=>K().child(e),time:(e)=>K().time(e),measure:(e,t,r)=>K().measure(e,t,r)};function Ht(e){let t=ie({},e);return async(r,n)=>{let o=Date.now(),s={requestId:Math.random().toString(36).substring(7),method:r.req.method,path:r.req.path,userAgent:r.req.header("user-agent")||"unknown"};t.info("Request started",s);try{await n();let d=Date.now()-o;t.info("Request completed",{...s,status:r.res.status,duration:d})}catch(d){let a=Date.now()-o;throw t.error("Request failed",{...s,duration:a},d instanceof Error?d:Error(String(d))),d}}}class P{static defaultOptions={maxAttempts:3,initialDelay:1000,maxDelay:30000,backoffMultiplier:2,jitter:!0,retryCondition:(e)=>w.isRetryable(e)};static async execute(e,t={}){let r={...P.defaultOptions,...t},n,o=r.initialDelay;for(let i=1;i<=r.maxAttempts;i++)try{return await e()}catch(s){if(n=s,i===r.maxAttempts||!r.retryCondition(n,i))throw n;let d=r.jitter?o+Math.random()*o*0.1:o;r.onRetry?.(n,i),await new Promise((a)=>setTimeout(a,d)),o=Math.min(o*r.backoffMultiplier,r.maxDelay)}throw n}static createRetryableFunction(e,t={}){return async(...r)=>P.execute(()=>e(...r),t)}}class H{static async execute(e,t,r={}){let n={concurrency:5,retryOptions:{maxAttempts:3,initialDelay:1000,maxDelay:1e4,backoffMultiplier:2,jitter:!0},failFast:!1,...r},o=Date.now(),i=[],s=[],d=0,a=P.createRetryableFunction(t,n.retryOptions),l=H.createBatches(e,n.concurrency);for(let y of l){let f=y.map(async(g)=>{try{let E=await a(g);i.push({item:g,result:E})}catch(E){if(s.push({item:g,error:E}),n.failFast)throw new C("MESSAGE_SEND_FAILED",`Bulk operation failed fast after ${s.length} failures`,{totalItems:e.length,failedCount:s.length})}finally{d++,n.onProgress?.(d,e.length,s.length)}});if(await Promise.allSettled(f),n.failFast&&s.length>0)break}let c=Date.now()-o;return{successful:i,failed:s,summary:{total:e.length,successful:i.length,failed:s.length,duration:c}}}static createBatches(e,t){let r=[];for(let n=0;n<e.length;n+=t)r.push(e.slice(n,n+t));return r}}class se{options;state="CLOSED";failureCount=0;lastFailureTime=0;nextAttemptTime=0;trial;constructor(e){this.options=e}async execute(e){let t=Date.now();switch(this.state){case"OPEN":if(t<this.nextAttemptTime)throw new C("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}let r;if(this.state==="HALF_OPEN"){if(this.trial)throw new C("NETWORK_SERVICE_UNAVAILABLE","Circuit breaker is HALF_OPEN and a trial call is in flight",{state:this.state});r=Symbol("trial"),this.trial=r}let n;try{let o=await Promise.race([e(),new Promise((i,s)=>{n=setTimeout(()=>s(new C("NETWORK_TIMEOUT","Circuit breaker timeout",{timeout:this.options.timeout})),this.options.timeout)})]);return this.recordSuccess(),o}catch(o){throw this.recordFailure(),o}finally{if(n!==void 0)clearTimeout(n);if(r&&this.trial===r)this.trial=void 0}}recordSuccess(){if(this.state==="HALF_OPEN"){this.state="CLOSED",this.failureCount=0,this.options.onClose?.();return}if(this.state==="CLOSED")this.failureCount=0}recordFailure(){if(this.failureCount++,this.lastFailureTime=Date.now(),this.state==="HALF_OPEN"||this.failureCount>=this.options.failureThreshold){let e=this.state==="OPEN";if(this.state="OPEN",this.nextAttemptTime=this.lastFailureTime+this.options.resetTimeout,!e)this.options.onOpen?.()}}getState(){return this.state}getFailureCount(){return this.failureCount}reset(){this.state="CLOSED",this.failureCount=0,this.lastFailureTime=0,this.nextAttemptTime=0,this.trial=void 0}}class ae{maxRequests;windowMs;requests=[];constructor(e,t){this.maxRequests=e;this.windowMs=t}async acquire(){let e=Date.now();if(this.requests=this.requests.filter((t)=>e-t<this.windowMs),this.requests.length>=this.maxRequests){let t=Math.min(...this.requests),r=this.windowMs-(e-t);if(r>0)return await new Promise((n)=>setTimeout(n,r)),this.acquire()}this.requests.push(e)}canMakeRequest(){let e=Date.now();return this.requests=this.requests.filter((t)=>e-t<this.windowMs),this.requests.length<this.maxRequests}getRemainingRequests(){let e=Date.now();return this.requests=this.requests.filter((t)=>e-t<this.windowMs),Math.max(0,this.maxRequests-this.requests.length)}}var de=(e)=>({isSuccess:!0,isFailure:!1,value:e}),le=(e)=>({isSuccess:!1,isFailure:!0,error:e}),jt={map(e,t){if(e.isSuccess)return de(t(e.value));return e},flatMap(e,t){if(e.isSuccess)return t(e.value);return e},mapError(e,t){if(e.isFailure)return le(t(e.error));return e},unwrap(e){if(e.isSuccess)return e.value;throw e.error},unwrapOr(e,t){if(e.isSuccess)return e.value;return t},unwrapOrElse(e,t){if(e.isSuccess)return e.value;return t(e.error)},match(e,t){if(e.isSuccess)return t.ok(e.value);return t.fail(e.error)},async fromPromise(e){try{let t=await e;return de(t)}catch(t){return le(t)}},isOk(e){return e.isSuccess},isFail(e){return e.isFailure},tap(e,t){return t(e),e},tapOk(e,t){if(e.isSuccess)t(e.value);return e},tapErr(e,t){if(e.isFailure)t(e.error);return e},expect(e,t){if(e.isSuccess)return e.value;throw Error(t,{cause:e.error})}};function Ye(){let e=globalThis;return e.__K_MSG_ENV__??e.__ENV__??e.process?.env??{}}function Wt(e){let t=Ye()[e];if(typeof t==="string")return t;if(t===void 0)return;return String(t)}var He=["PENDING","SENT","DELIVERED","FAILED","CANCELLED","UNKNOWN"],je=["DELIVERED","FAILED","CANCELLED","UNKNOWN"],ce=["PENDING","SENT"],Jt=new Set(He),We=new Set(je),Qt=new Set(ce);function Xt(e){return Jt.has(e)}function Zt(e){return We.has(e)}function er(e){return We.has(e)}function tr(e){return Qt.has(e)}function rr(){return ce}var Je=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS","NSA","VOICE","FAX","RCS_SMS","RCS_LMS","RCS_MMS","RCS_TPL","RCS_ITPL","RCS_LTPL"],nr=new Set(Je);function or(e){return nr.has(e)}var ir=["PENDING","SENT","FAILED"],Qe="PENDING",sr=(e)=>{let t=typeof e==="string"?e.trim().toUpperCase():"";if(t==="PENDING"||t==="SENT"||t==="FAILED")return t;return Qe};
3
+
4
+ //# debugId=DA2677BFFCB0755D64756E2164756E21
5
+ //# sourceMappingURL=index.cjs.map
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- var I;((o)=>{o.INVALID_REQUEST="INVALID_REQUEST";o.AUTHENTICATION_FAILED="AUTHENTICATION_FAILED";o.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE";o.TEMPLATE_NOT_FOUND="TEMPLATE_NOT_FOUND";o.RATE_LIMIT_EXCEEDED="RATE_LIMIT_EXCEEDED";o.NETWORK_ERROR="NETWORK_ERROR";o.NETWORK_TIMEOUT="NETWORK_TIMEOUT";o.NETWORK_SERVICE_UNAVAILABLE="NETWORK_SERVICE_UNAVAILABLE";o.REQUEST_ABORTED="REQUEST_ABORTED";o.PROVIDER_ERROR="PROVIDER_ERROR";o.MESSAGE_SEND_FAILED="MESSAGE_SEND_FAILED";o.CRYPTO_CONFIG_ERROR="CRYPTO_CONFIG_ERROR";o.CRYPTO_ENCRYPT_FAILED="CRYPTO_ENCRYPT_FAILED";o.CRYPTO_DECRYPT_FAILED="CRYPTO_DECRYPT_FAILED";o.CRYPTO_HASH_FAILED="CRYPTO_HASH_FAILED";o.CRYPTO_POLICY_VIOLATION="CRYPTO_POLICY_VIOLATION";o.UNKNOWN_ERROR="UNKNOWN_ERROR"})(I||={});var xt={["INVALID_REQUEST"]:{ko:"잘못된 요청입니다",en:"Invalid request"},["AUTHENTICATION_FAILED"]:{ko:"인증에 실패했습니다",en:"Authentication failed"},["INSUFFICIENT_BALANCE"]:{ko:"잔액이 부족합니다",en:"Insufficient balance"},["TEMPLATE_NOT_FOUND"]:{ko:"템플릿을 찾을 수 없습니다",en:"Template not found"},["RATE_LIMIT_EXCEEDED"]:{ko:"요청 한도를 초과했습니다",en:"Rate limit exceeded"},["NETWORK_ERROR"]:{ko:"네트워크 오류가 발생했습니다",en:"Network error"},["NETWORK_TIMEOUT"]:{ko:"네트워크 요청 시간이 초과되었습니다",en:"Network timeout"},["NETWORK_SERVICE_UNAVAILABLE"]:{ko:"서비스를 일시적으로 사용할 수 없습니다",en:"Service temporarily unavailable"},["REQUEST_ABORTED"]:{ko:"요청이 취소되었습니다",en:"Request aborted"},["PROVIDER_ERROR"]:{ko:"제공자 오류가 발생했습니다",en:"Provider error"},["MESSAGE_SEND_FAILED"]:{ko:"메시지 전송에 실패했습니다",en:"Message send failed"},["CRYPTO_CONFIG_ERROR"]:{ko:"암호화 설정 오류가 발생했습니다",en:"Crypto configuration error"},["CRYPTO_ENCRYPT_FAILED"]:{ko:"암호화에 실패했습니다",en:"Encryption failed"},["CRYPTO_DECRYPT_FAILED"]:{ko:"복호화에 실패했습니다",en:"Decryption failed"},["CRYPTO_HASH_FAILED"]:{ko:"해시 생성에 실패했습니다",en:"Hash generation failed"},["CRYPTO_POLICY_VIOLATION"]:{ko:"암호화 정책 위반이 발생했습니다",en:"Crypto policy violation"},["UNKNOWN_ERROR"]:{ko:"알 수 없는 오류가 발생했습니다",en:"Unknown error"}},Rt=new Set(Object.values(I)),v=new Set(["NETWORK_ERROR","RATE_LIMIT_EXCEEDED","NETWORK_TIMEOUT","NETWORK_SERVICE_UNAVAILABLE","PROVIDER_ERROR","UNKNOWN_ERROR"]),u=new Set(["INVALID_REQUEST","AUTHENTICATION_FAILED","INSUFFICIENT_BALANCE","TEMPLATE_NOT_FOUND","MESSAGE_SEND_FAILED","REQUEST_ABORTED","CRYPTO_CONFIG_ERROR","CRYPTO_ENCRYPT_FAILED","CRYPTO_DECRYPT_FAILED","CRYPTO_HASH_FAILED","CRYPTO_POLICY_VIOLATION"]),S=(t)=>{if(typeof t!=="number"||Number.isNaN(t)||!Number.isFinite(t))return;return Math.trunc(t)},x=(t)=>{let n=S(t);if(n===void 0||n<0)return;return n},Mt=(t)=>{if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0},J=(t)=>{return typeof t==="string"?t.toLowerCase().trim():void 0},T=(t,n="safe")=>{if(typeof t==="string"){let i=t.trim().toUpperCase();return i.length>0?i:void 0}if(n==="compat"&&(typeof t==="number"||typeof t==="boolean"))return String(t).toUpperCase();return},z=(t,n)=>t?.some((i)=>T(i)===n)??!1,_t=(t,n)=>{if(n.nonRetryableCodes?.includes(t))return"non_retryable";if(n.retryableCodes?.includes(t))return"retryable";return},tt=(t,n)=>{let i=T(t,"compat");if(!i)return;if(z(n.nonRetryableStatuses,i))return"non_retryable";if(z(n.retryableStatuses,i))return"retryable";return},O=(t)=>{return typeof t==="object"&&t!==null&&!Array.isArray(t)},E=(t,n)=>{for(let i of n)if(i in t)return t[i];return},Nt=(t)=>{return t.length>0?t:"$"},yt=(t)=>{return t==="compat"?"compat":"safe"},nt=(t)=>{if(t>=500)return"retryable";if(t===408||t===425||t===429)return"retryable";return"non_retryable"},it=(t)=>{let n=t.toLowerCase();if(n.includes("timeout")||n.includes("temporar")||n.includes("network")||n.includes("retry"))return"retryable";return};class A extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(t,n,i,e={}){super(n);if(this.name="KMsgError",this.code=t,this.details=i,this.providerErrorCode=e.providerErrorCode,this.providerErrorText=e.providerErrorText,this.httpStatus=S(e.httpStatus),this.requestId=typeof e.requestId==="string"?e.requestId:void 0,this.retryAfterMs=S(e.retryAfterMs),this.attempt=S(e.attempt),Array.isArray(e.causeChain))this.causeChain=e.causeChain;else if(e.causeChain!==void 0)this.causeChain=[e.causeChain];let p=Error.captureStackTrace;if(p)p(this,A)}getLocalizedMessage(t="ko"){let n=xt[this.code];if(n?.[t])return n[t];return this.message}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details,providerErrorCode:this.providerErrorCode,providerErrorText:this.providerErrorText,httpStatus:this.httpStatus,requestId:this.requestId,retryAfterMs:this.retryAfterMs,attempt:this.attempt,causeChain:this.causeChain}}}var b=(t,n)=>{let i=S(t);if(i!==void 0)return i;if(n==="compat"&&typeof t==="string"){let e=Number(t.trim());if(Number.isFinite(e))return Math.trunc(e)}return},W=(t,n)=>{let i=Mt(t);if(i)return i;if(n==="compat"&&(typeof t==="number"||typeof t==="boolean"))return String(t);return},ct=(t)=>{if(typeof t!=="string")return;let n=t.trim().toUpperCase();if(!Rt.has(n))return;return n},w=(t,n)=>{t.push({...n,path:Nt(n.path)})},ht=(t,n,i,e,p)=>{if(t===void 0)return[];let s=(()=>{if(Array.isArray(t))return t;if(i==="compat"&&typeof t==="string")return t.split(",").map((r)=>r.trim()).filter((r)=>r.length>0);return w(e,{code:"invalid_type",message:`expected array of ${p.label} values`,path:n}),[]})(),f=[],y=new Set;for(let r=0;r<s.length;r+=1){let c=s[r],h=p.normalize(c);if(!h){w(e,{code:p.label==="code"?"unknown_code":"invalid_status",message:`invalid retry policy ${p.label}: ${String(c)}`,path:`${n}[${r}]`});continue}if(y.has(h)){w(e,{code:p.label==="code"?"duplicate_code":"duplicate_status",message:`duplicate retry policy ${p.label}: ${h}`,path:`${n}[${r}]`});continue}y.add(h),f.push(h)}return f},et=(t,n,i,e)=>ht(t,n,i,e,{label:"code",normalize:(p)=>ct(T(p,i))}),pt=(t,n,i,e)=>ht(t,n,i,e,{label:"status",normalize:(p)=>T(p,i)}),dt=(t,n,i,e)=>{if(t===void 0)return;let p=x(b(t,i));if(p!==void 0)return p;w(e,{code:"invalid_retry_after",message:`invalid retry delay: ${String(t)}`,path:n});return},st=(t,n,i,e)=>{if(t===void 0)return;if(!O(t)){w(e,{code:"invalid_type",message:"expected retry delay map",path:n});return}let p={},s=new Set;for(let[f,y]of Object.entries(t)){let r=T(f,"safe"),c=`${n}.${f}`;if(!r){w(e,{code:"invalid_key",message:"retry delay map key must not be empty",path:c});continue}if(s.has(r)){w(e,{code:"duplicate_key",message:`duplicate retry delay map key: ${r}`,path:c});continue}let h=dt(y,c,i,e);if(h===void 0)continue;s.add(r),p[r]=h}return Object.keys(p).length>0?p:void 0},It=(t,n,i)=>{if(t===void 0)return;if(typeof t==="function")return t;if(!O(t)){w(i,{code:"invalid_type",message:"expected retry delay resolver or policy object",path:"retryAfterMs"});return}let e=new Set(["defaultMs","byCode","byStatus"]);for(let y of Object.keys(t)){if(e.has(y))continue;w(i,{code:"unknown_field",message:`unknown retry-after policy field: ${y}`,path:`retryAfterMs.${y}`})}let p=dt(t.defaultMs,"retryAfterMs.defaultMs",n,i),s=st(t.byCode,"retryAfterMs.byCode",n,i),f=st(t.byStatus,"retryAfterMs.byStatus",n,i);if(p===void 0&&s===void 0&&f===void 0)return;return{...p!==void 0?{defaultMs:p}:{},...s!==void 0?{byCode:s}:{},...f!==void 0?{byStatus:f}:{}}},Ut=(t,n,i)=>{if(t===void 0)return;if(typeof t==="string"){let e=t.trim().toLowerCase();if(e==="retryable")return"retryable";if(e==="non_retryable"||e==="non-retryable")return"non_retryable"}if(n==="compat"&&typeof t==="boolean")return t?"retryable":"non_retryable";w(i,{code:"invalid_fallback",message:`invalid fallback value: ${String(t)}`,path:"fallback"});return};function qt(t,n={}){let i=yt(n.mode),e=[];if(!O(t))return w(e,{code:"invalid_root",message:"retry policy must be an object",path:"$"}),{policy:null,issues:e};let p=new Set(["retryableCodes","nonRetryableCodes","retryableStatuses","nonRetryableStatuses","fallback","retryAfterMs"]);for(let o of Object.keys(t)){if(p.has(o))continue;w(e,{code:"unknown_field",message:`unknown retry policy field: ${o}`,path:o})}let s=et(t.retryableCodes,"retryableCodes",i,e),f=et(t.nonRetryableCodes,"nonRetryableCodes",i,e),y=pt(t.retryableStatuses,"retryableStatuses",i,e),r=pt(t.nonRetryableStatuses,"nonRetryableStatuses",i,e),c=Ut(t.fallback,i,e),h=It(t.retryAfterMs,i,e),a=new Set(s),g=new Set(f);for(let o of a){if(!g.has(o))continue;a.delete(o),w(e,{code:"conflicting_code",message:`code '${o}' is both retryable and nonRetryable; nonRetryable wins`,path:"retryableCodes"})}let F=new Set(y),K=new Set(r);for(let o of F){if(!K.has(o))continue;F.delete(o),w(e,{code:"conflicting_status",message:`status '${o}' is both retryable and nonRetryable; nonRetryable wins`,path:"retryableStatuses"})}let l={...a.size>0?{retryableCodes:Array.from(a)}:{},...g.size>0?{nonRetryableCodes:Array.from(g)}:{},...F.size>0?{retryableStatuses:Array.from(F)}:{},...K.size>0?{nonRetryableStatuses:Array.from(K)}:{},...c?{fallback:c}:{},...h?{retryAfterMs:h}:{}};return{policy:l.retryableCodes!==void 0||l.nonRetryableCodes!==void 0||l.retryableStatuses!==void 0||l.nonRetryableStatuses!==void 0||l.fallback!==void 0||l.retryAfterMs!==void 0?l:null,issues:e}}function Bt(t,n={}){return qt(t,n).policy}function on(t,n={}){if(typeof t!=="string"||t.trim().length===0)return null;try{let i=JSON.parse(t);return Bt(i,n)}catch{return null}}var ft=(t,n)=>{let i=t.response;if(!O(i))return;return b(E(i,["status","statusCode","httpStatus"]),n)},$t=(t,n)=>{if(t instanceof A&&Array.isArray(t.causeChain))return t.causeChain.slice();if(O(t)){let s=t.causeChain;if(Array.isArray(s))return s.slice();let f=t.details;if(n==="compat"&&O(f)){let y=f.causeChain;if(Array.isArray(y))return y.slice();if(y!==void 0)return[y]}}let i=[],e=new Set,p=t;for(let s=0;s<8;s+=1){if(!O(p))break;let f=p.cause;if(f===void 0||e.has(f))break;e.add(f),i.push(f),p=f}return i.length>0?i:void 0},Ht=(t)=>{if(t instanceof Error&&typeof t.message==="string")return t.message;if(O(t)&&typeof t.message==="string")return t.message;return typeof t==="string"?t:"Unknown error"},rt=(t,n)=>{let i=T(n,"compat");if(!t||!i)return;if(Object.prototype.hasOwnProperty.call(t,i))return x(t[i]);for(let[e,p]of Object.entries(t)){if(T(e)!==i)continue;return x(p)}return},ot=(t,n)=>{let i=n?.retryAfterMs;if(typeof i==="function"){let y=x(i(t));if(y!==void 0)return{value:y,source:"policy"}}let e=x(t.retryAfterMs);if(e!==void 0)return{value:e,source:"input"};if(!i||typeof i==="function")return{};let p=[t.providerErrorCode,t.code];for(let y of p){let r=rt(i.byCode,y);if(r!==void 0)return{value:r,source:"policy"}}let s=rt(i.byStatus,t.httpStatus);if(s!==void 0)return{value:s,source:"policy"};let f=x(i.defaultMs);return f!==void 0?{value:f,source:"policy"}:{}};function an(t,n={}){let i=yt(n.mode),p=n.defaultCode??"UNKNOWN_ERROR",s={code:"fallback",classification:n.policy?"policy":"fallback"},f,y,r,c,h,a,g,F=(d)=>{if(d.providerErrorCode!==void 0)f=d.providerErrorCode,s.providerErrorCode="metadata";if(d.providerErrorText!==void 0)y=d.providerErrorText,s.providerErrorText="metadata";if(d.httpStatus!==void 0)r=d.httpStatus,s.httpStatus="metadata";if(d.requestId!==void 0)c=d.requestId,s.requestId="metadata";if(d.retryAfterMs!==void 0)h=x(d.retryAfterMs),s.retryAfterMs="metadata";if(d.attempt!==void 0)a=b(d.attempt,i),s.attempt="metadata";if(Array.isArray(d.causeChain))g=d.causeChain.slice(),s.causeChain="metadata"},K=(d,D)=>{if(f===void 0){let C=W(E(d,["providerErrorCode","errorCode","resultCode"]),i);if(C!==void 0)f=C,s.providerErrorCode=D}if(y===void 0){let C=W(E(d,["providerErrorText","errorMessage","msg","message"]),i);if(C!==void 0)y=C,s.providerErrorText=D}if(r===void 0){let C=b(E(d,["httpStatus","statusCode","status"]),i)??ft(d,i);if(C!==void 0)r=C,s.httpStatus=D==="details"?"details":"http"}if(c===void 0){let C=W(E(d,["requestId","request_id","reqId","traceId"]),i);if(C!==void 0)c=C,s.requestId=D}if(h===void 0){let C=x(b(E(d,["retryAfterMs","retry_after_ms","retryAfter"]),i));if(C!==void 0)h=C,s.retryAfterMs=D}if(a===void 0){let C=b(d.attempt,i);if(C!==void 0&&C>0)a=C,s.attempt=D}};if(t instanceof A){if(p=t.code,s.code="input",F(t),i==="compat"&&O(t.details))K(t.details,"details")}else if(O(t)){let d=ct(E(t,["code","errorCode","resultCode"]));if(d!==void 0)p=d,s.code="input";else if(r===void 0){let D=b(E(t,["httpStatus","statusCode","status"]),i)??ft(t,i);if(D!==void 0&&D>=500)p="PROVIDER_ERROR",s.code="http"}if(K(t,"input"),i==="compat"&&O(t.details))K(t.details,"details")}if(g===void 0){let d=$t(t,i);if(d!==void 0)g=d,s.causeChain="input"}if(n.attempt!==void 0&&b(n.attempt,i)!==void 0){let d=b(n.attempt,i);if(d!==void 0&&d>0)a=d,s.attempt="input"}let l=new A(p,Ht(t),void 0,{providerErrorCode:f,providerErrorText:y,httpStatus:r,requestId:c,retryAfterMs:h,attempt:a,causeChain:g}),P=ot(l,n.policy);if(P.value!==void 0){if(h=P.value,P.source==="policy")s.retryAfterMs="policy"}let o=N.classifyForRetry(l,n.policy);return{code:p,classification:o,...f!==void 0?{providerErrorCode:f}:{},...y!==void 0?{providerErrorText:y}:{},...r!==void 0?{httpStatus:r}:{},...c!==void 0?{requestId:c}:{},...h!==void 0?{retryAfterMs:h}:{},...a!==void 0?{attempt:a}:{},...g!==void 0?{causeChain:g}:{},sources:s}}var N={isRetryable(t,n={}){return N.classifyForRetry(t,n)==="retryable"},classifyForRetry(t,n={}){if(t instanceof A){let r=_t(t.code,n);if(r)return r;let c=tt(t.httpStatus,n);if(c)return c;if(new Set(n.retryableCodes??Array.from(v)).has(t.code))return"retryable";if(new Set(n.nonRetryableCodes??Array.from(u)).has(t.code))return"non_retryable";if(t.httpStatus!==void 0)return nt(t.httpStatus);let g=it(t.message);if(g)return g;if(n.classifyByMessage&&t.message){let F=n.classifyByMessage(t.message);if(F)return F}if(n.fallback)return n.fallback;return"non_retryable"}let i=t&&typeof t==="object"?t:void 0,e=T(i?.status,"compat")??T(i?.statusCode,"compat")??T(i?.httpStatus,"compat")??T(i?.code,"compat"),p=J(i?.status)??J(i?.statusCode)??J(i?.code),s=S(i?.status)??S(i?.statusCode)??S(i?.httpStatus),f=tt(e,n);if(f)return f;if(p?.startsWith("5"))return"retryable";if(s!==void 0){if(n.classifyByStatusCode)return n.classifyByStatusCode(s);return nt(s)}let y=typeof i?.message==="string"?it(i.message):void 0;if(y)return y;if(n.classifyByMessage&&typeof i?.message==="string"){let r=n.classifyByMessage(i.message);if(r)return r}return n.fallback??"non_retryable"},resolveRetryAfterMs(t,n){return ot(t,n).value},isUnknownStatus:(t)=>{if(t===void 0||Number.isNaN(t)||!Number.isFinite(t))return!1;return t<500},toRetryMetadata(t){return{providerErrorCode:t.providerErrorCode,providerErrorText:t.providerErrorText,httpStatus:t.httpStatus,requestId:t.requestId,retryAfterMs:t.retryAfterMs,attempt:t.attempt,causeChain:t.causeChain}},withAttempt(t,n){return new A(t.code,t.message,t.details,{...N.toRetryMetadata(t),attempt:S(n)})},DEFAULT_RETRYABLE_ERROR_CODES:v,DEFAULT_NON_RETRYABLE_ERROR_CODES:u};function mt(t){switch(t){case"config":return"CRYPTO_CONFIG_ERROR";case"encrypt":return"CRYPTO_ENCRYPT_FAILED";case"decrypt":return"CRYPTO_DECRYPT_FAILED";case"hash":return"CRYPTO_HASH_FAILED";case"policy":return"CRYPTO_POLICY_VIOLATION"}}class U extends A{kind;fieldPath;failMode;openFallback;constructor(t,n,i,e={}){super(mt(t),n,i,e);this.name="FieldCryptoError",this.kind=t,this.fieldPath=typeof e.fieldPath==="string"?e.fieldPath:void 0,this.failMode=e.failMode,this.openFallback=e.openFallback}toJSON(){return{...super.toJSON(),kind:this.kind,fieldPath:this.fieldPath,failMode:this.failMode,openFallback:this.openFallback}}}var Gt=["tenantId","providerId","messageId"];function q(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function Jt(t){if(typeof t!=="number"||!Number.isFinite(t))return;if(t<=0||t>100)return;return t}function at(t){let n=[];for(let i of t){let e=q(i.kid),p=Jt(i.percentage);if(!e||p===void 0)continue;n.push({kid:e,percentage:p})}return n}function Wt(t,n,i){let e=n.map((p)=>{let s=t[p];return typeof s==="string"?s:""}).join("|");return`${i}::${e}`}function Yt(t){let n=2166136261;for(let i=0;i<t.length;i+=1)n^=t.charCodeAt(i),n=n*16777619>>>0;return n>>>0}function Vt(t,n){let i=0;for(let e of t)if(i+=e.percentage,n<i)return e.kid;return}function Y(t,n,i){let e=at(n.buckets),p=q(n.defaultKid)??q(i);if(e.length===0)return p;let s=q(n.seed)??"kmsg-rollout-v1",f=n.stickyFields??Gt,y=Wt(t,f,s),r=Yt(y)%100;return Vt(e,r)??p}function gt(t){return at(t.buckets).map((n)=>n.kid)}function M(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function V(t){if(!Array.isArray(t))return[];return t.map((n)=>M(n)).filter((n)=>Boolean(n))}function j(t){let n=[],i=new Set;for(let e of t){let p=M(e);if(!p||i.has(p))continue;i.add(p),n.push(p)}return n}function jt(t){return M(t.providerId)??"default"}function Ft(t){let n=M(t.activeKid)??"default",i=j([n,...V(t.decryptKids)]);return{async resolveEncryptKey(){return{kid:n}},async resolveDecryptKeys(){return i}}}function B(t){let n=typeof t.cacheTtlMs==="number"&&t.cacheTtlMs>=0?Math.trunc(t.cacheTtlMs):30000,i=M(t.fallback?.activeKid),e=V(t.fallback?.decryptKids),p;async function s(f){let y=Date.now();if(p&&y<p.expiresAt)return p.value;let r=await t.provider.loadKeySet(f),c=M(r.activeKid)??i??jt(f),h=j([c,...V(r.decryptKids),...e]),a={activeKid:c,decryptKids:h,refreshedAt:Date.now()};return p={value:a,expiresAt:Date.now()+n},a}return{async resolveEncryptKey(f){return{kid:(await s(f)).activeKid}},async resolveDecryptKeys(f){let y=await s(f);return y.decryptKids??[y.activeKid]}}}function wn(t,n){return{async resolveEncryptKey(i){let e=await t.resolveEncryptKey(i);return{kid:Y(i,n,e.kid)??e.kid}},async resolveDecryptKeys(i){let e=await t.resolveEncryptKey(i),p=t.resolveDecryptKeys?await t.resolveDecryptKeys(i):[e.kid],s=Y(i,n,e.kid),f=gt(n);return j([...s?[s]:[],e.kid,...p??[],...f])}}}function Dn(t){return B({provider:{async loadKeySet(i){return t.client.getKeyState({...i,...t.keyAlias?{keyAlias:t.keyAlias}:{},...t.region?{region:t.region}:{}})}},cacheTtlMs:t.cacheTtlMs,fallback:{activeKid:t.fallbackActiveKid,decryptKids:t.fallbackDecryptKids}})}function $(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function Ct(t,n){return $(t[n])}function Qt(t,n){if(!t)return[];return t.split(n).map((i)=>$(i)).filter((i)=>Boolean(i))}function bn(t={}){let n=globalThis.process?.env,i=t.env??n??{},e=$(t.delimiter)??",",p=t.activeKidEnv??"KMSG_ACTIVE_KID",s=t.decryptKidsEnv??"KMSG_DECRYPT_KIDS",f=Ct(i,p)??$(t.fallbackActiveKid)??"default",y=[f,...Qt(Ct(i,s),e),...t.fallbackDecryptKids??[]];return Ft({activeKid:f,decryptKids:y})}function En(t){return B({provider:{async loadKeySet(i){return t.client.getKeyState({...i,...t.mountPath?{mountPath:t.mountPath}:{},...t.keyName?{keyName:t.keyName}:{},...t.namespace?{namespace:t.namespace}:{}})}},cacheTtlMs:t.cacheTtlMs,fallback:{activeKid:t.fallbackActiveKid,decryptKids:t.fallbackDecryptKids}})}function Q(t){return typeof t==="function"}function Kt(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function lt(t,n,i){let e=t.fields[n];if(e)return e;if(n.startsWith("metadata.")){let p=t.fields["metadata.*"];if(p)return p}return i}function Zt(t,n={}){let i=[];if(!t||typeof t!=="object")return{valid:!1,issues:[{message:"fieldCrypto config must be an object",rule:"fieldCrypto.config.object",hint:"Provide a valid FieldCryptoConfig object"}]};if(!t.provider||typeof t.provider!=="object")i.push({message:"fieldCrypto provider is required",rule:"fieldCrypto.provider.required",path:"provider",hint:"Set provider with encrypt/decrypt/hash methods"});else{if(!Q(t.provider.encrypt))i.push({message:"provider.encrypt must be a function",rule:"fieldCrypto.provider.encrypt.required",path:"provider.encrypt"});if(!Q(t.provider.decrypt))i.push({message:"provider.decrypt must be a function",rule:"fieldCrypto.provider.decrypt.required",path:"provider.decrypt"});if(!Q(t.provider.hash))i.push({message:"provider.hash must be a function",rule:"fieldCrypto.provider.hash.required",path:"provider.hash"})}if(!t.fields||typeof t.fields!=="object")i.push({message:"fieldCrypto.fields must be an object",rule:"fieldCrypto.fields.object",path:"fields",hint:"Define policies such as to, from, metadata.phoneNumber"});else{let s=Object.entries(t.fields);if(s.length===0)i.push({message:"fieldCrypto.fields must not be empty",rule:"fieldCrypto.fields.non_empty",path:"fields",hint:"Add at least one field mode mapping"});for(let[f,y]of s){if(!Kt(f))i.push({message:"field path must be a non-empty string",rule:"fieldCrypto.fields.path.non_empty",path:"fields"});if(y!=="plain"&&y!=="encrypt"&&y!=="encrypt+hash"&&y!=="mask")i.push({message:`unsupported field mode: ${String(y)}`,rule:"fieldCrypto.fields.mode.supported",path:`fields.${f}`})}}let e=t.failMode??"closed",p=t.openFallback??"masked";if(e==="open"&&p==="plaintext"&&t.unsafeAllowPlaintextStorage!==!0)i.push({message:"openFallback=plaintext requires unsafeAllowPlaintextStorage=true",rule:"fieldCrypto.fail_open.plaintext_guard",path:"openFallback",hint:"Use masked/null fallback, or explicitly enable unsafe plaintext"});if(Array.isArray(t.aadFields)){if(t.aadFields.length===0)i.push({message:"aadFields must not be empty when provided",rule:"fieldCrypto.aad_fields.non_empty",path:"aadFields"});for(let s=0;s<t.aadFields.length;s+=1){let f=t.aadFields[s];if(!Kt(f))i.push({message:"aadFields cannot include empty key",rule:"fieldCrypto.aad_fields.no_empty_key",path:`aadFields[${s}]`})}}if(n.secureMode&&!n.compatPlainColumns){let s=lt(t,"to","encrypt+hash"),f=lt(t,"from","encrypt+hash");if(s==="plain")i.push({message:"secure mode requires non-plain policy for `to` when compatPlainColumns=false",rule:"fieldCrypto.secure_mode.to_non_plain",path:"fields.to",hint:"Use encrypt+hash for lookup fields"});if(f==="plain")i.push({message:"secure mode requires non-plain policy for `from` when compatPlainColumns=false",rule:"fieldCrypto.secure_mode.from_non_plain",path:"fields.from",hint:"Use encrypt+hash for lookup fields"})}return{valid:i.length===0,issues:i}}function Mn(t,n={}){let i=Zt(t,n);if(i.valid)return;let e=i.issues[0];if(!e)throw new U("config","fieldCrypto config validation failed",{rule:"fieldCrypto.config.invalid",issues:i.issues});throw new U("config",e.message,{rule:e.rule,path:e.path,hint:e.hint,issues:i.issues},{fieldPath:e.path})}function H(t){let n=t instanceof Uint8Array?t:new Uint8Array(t),i=typeof globalThis<"u"?globalThis.Buffer:void 0;return(i?i.from(n).toString("base64"):btoa(String.fromCharCode(...n))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function m(t){let n=t.replace(/-/g,"+").replace(/_/g,"/"),i=n.length%4===0?n:`${n}${"=".repeat(4-n.length%4)}`,e=typeof globalThis<"u"?globalThis.Buffer:void 0;if(e)return new Uint8Array(e.from(i,"base64"));let p=atob(i),s=new Uint8Array(p.length);for(let f=0;f<p.length;f+=1)s[f]=p.charCodeAt(f);return s}function wt(t,n){if(t instanceof Uint8Array)return t;if(t instanceof ArrayBuffer)return new Uint8Array(t);if(n==="base64url")return m(t);return new TextEncoder().encode(t)}function Xt(t){let n=t instanceof Uint8Array?t:new Uint8Array(t);return Array.from(n).map((i)=>i.toString(16).padStart(2,"0")).join("")}function k(t){let n=new Uint8Array(t.byteLength);return n.set(t),n.buffer}function At(t){let n=JSON.parse(t);if(!n||typeof n!=="object"||typeof n.v!=="number"||typeof n.alg!=="string"||typeof n.kid!=="string"||typeof n.iv!=="string"||typeof n.tag!=="string"||typeof n.ct!=="string")throw Error("Invalid ciphertext envelope");return n}function Lt(t){if(typeof t==="string")return t;return JSON.stringify(t)}function Nn(t){if(!t||typeof t!=="object")return!1;let n=t;return typeof n.v==="number"&&typeof n.alg==="string"&&typeof n.kid==="string"&&typeof n.iv==="string"&&typeof n.tag==="string"&&typeof n.ct==="string"}function vt(t){let n=String(t??"").trim();if(n.length===0)return"";let i=n.startsWith("+"),e=n.replace(/\D/g,"");return i?`+${e}`:e}function Pt(t=3,n=2){return(i)=>{let e=String(i??"");if(e.length<=t+n)return"*".repeat(Math.max(0,e.length));let p=e.slice(0,t),s=e.slice(-n);return`${p}${"*".repeat(e.length-t-n)}${s}`}}function In(t){let n=t.algorithm??"A256GCM",i=t.keyEncoding??"base64url",e=t.hashKeyEncoding??i,p=new Map,s=new Map,f=(r)=>{let c=p.get(r);if(c)return c;let h=t.keys[r];if(!h)throw Error(`Unknown encryption key id: ${r}`);let a=wt(h,i),g=crypto.subtle.importKey("raw",k(a),"AES-GCM",!1,["encrypt","decrypt"]);return p.set(r,g),g},y=(r)=>{let c=s.get(r);if(c)return c;let h=t.hashKeys?.[r]??t.keys[r];if(!h)throw Error(`Unknown hash key id: ${r}`);let a=wt(h,e),g=crypto.subtle.importKey("raw",k(a),{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return s.set(r,g),g};return{async encrypt(r){let c=r.kid??t.activeKid,h=await f(c),a=crypto.getRandomValues(new Uint8Array(12)),g=new TextEncoder().encode(JSON.stringify(r.aad??{})),F=new TextEncoder().encode(r.value),K=await crypto.subtle.encrypt({name:"AES-GCM",iv:k(a),additionalData:k(g),tagLength:128},h,k(F)),l=new Uint8Array(K),P=l.slice(l.length-16),o=l.slice(0,l.length-16);return{ciphertext:{v:1,alg:n,kid:c,iv:H(a),tag:H(P),ct:H(o)},kid:c}},async decrypt(r){let c=At(r.ciphertext),h=r.candidateKids&&r.candidateKids.length>0?r.candidateKids:[c.kid],a=m(c.iv),g=m(c.tag),F=m(c.ct),K=new Uint8Array(F.length+g.length);K.set(F,0),K.set(g,F.length);let l=new TextEncoder().encode(JSON.stringify(r.aad??{})),P;for(let o of h)try{let d=await f(o),D=await crypto.subtle.decrypt({name:"AES-GCM",iv:k(a),additionalData:k(l),tagLength:128},d,k(K));return new TextDecoder().decode(new Uint8Array(D))}catch(d){P=d}throw Error(`Failed to decrypt ciphertext: ${P instanceof Error?P.message:String(P??"unknown")}`)},async hash(r){let c=r.kid??t.activeKid,h=await y(c),a=await crypto.subtle.sign("HMAC",h,k(new TextEncoder().encode(r.value)));return Xt(a)},mask(r){return Pt()(r.value)}}}function Un(){return{encrypt(t){return{ciphertext:JSON.stringify({v:1,alg:"NOOP",kid:"noop",iv:"",tag:"",ct:t.value})}},decrypt(t){try{return At(t.ciphertext).ct}catch{return t.ciphertext}},hash(t){let n=vt(t.value);return H(new TextEncoder().encode(n))},mask(t){return Pt()(t.value)}}}function qn(t){return Lt(t)}var ut;((p)=>{p.DEBUG="DEBUG";p.INFO="INFO";p.WARN="WARN";p.ERROR="ERROR"})(ut||={});var zt=["to","from","phone","phoneNumber","recipient","sender","secret","apiKey","apiSecret","authorization","auth","token","password","payload","message","content","text"];function tn(t){let n=t.toLowerCase();return zt.some((i)=>n.includes(i.toLowerCase()))}function nn(t){let n=t.trim();if(n.length<=4)return"***";if(n.includes("@")){let[p,s]=n.split("@");return`${p.slice(0,2)}${"*".repeat(Math.max(1,p.length-2))}@${s}`}let i=n.slice(0,3),e=n.slice(-2);return`${i}${"*".repeat(Math.max(1,n.length-5))}${e}`}function Z(t,n){if(n===void 0||n===null)return n;if(tn(t)){if(typeof n==="string")return nn(n);if(typeof n==="number"||typeof n==="boolean")return"***";if(Array.isArray(n))return"[REDACTED]";if(typeof n==="object")return"[REDACTED]"}if(Array.isArray(n))return n.map((i)=>Z(t,i));if(typeof n==="object"){let i={};for(let[e,p]of Object.entries(n))i[e]=Z(e,p);return i}return n}function en(t){let n={};for(let[i,e]of Object.entries(t))n[i]=Z(i,e);return n}class X{config;context;constructor(t={},n={}){this.context=t,this.config={level:"INFO",enableConsole:!0,enableJson:!1,enableColors:!0,...n}}shouldLog(t){let n=["DEBUG","INFO","WARN","ERROR"];return n.indexOf(t)>=n.indexOf(this.config.level)}formatMessage(t){let n=en(t.context);if(this.config.enableJson)return JSON.stringify({level:t.level,message:t.message,timestamp:t.timestamp.toISOString(),context:n,...t.error&&{error:{name:t.error.name,message:t.error.message,stack:t.error.stack}},...t.duration&&{duration:t.duration}});let i=t.timestamp.toISOString(),e=this.config.enableColors?this.colorizeLevel(t.level):t.level,p=Object.keys(n).length>0?` [${Object.entries(n).map(([f,y])=>`${f}=${y}`).join(", ")}]`:"",s=`${i} ${e}${p}: ${t.message}`;if(t.duration!==void 0)s+=` (${t.duration}ms)`;if(t.error)s+=`
2
- ${t.error.stack}`;return s}colorizeLevel(t){if(!this.config.enableColors)return t;return`${{["DEBUG"]:"\x1B[36m",["INFO"]:"\x1B[32m",["WARN"]:"\x1B[33m",["ERROR"]:"\x1B[31m"}[t]}${t}\x1B[0m`}writeLog(t){if(!this.shouldLog(t.level))return;let n=this.formatMessage(t);if(this.config.enableConsole)(t.level==="ERROR"?console.error:t.level==="WARN"?console.warn:console.log)(n);if(this.config.enableFile&&this.config.filePath);}debug(t,n={}){this.writeLog({level:"DEBUG",message:t,timestamp:new Date,context:{...this.context,...n}})}info(t,n={}){this.writeLog({level:"INFO",message:t,timestamp:new Date,context:{...this.context,...n}})}warn(t,n={},i){this.writeLog({level:"WARN",message:t,timestamp:new Date,context:{...this.context,...n},error:i})}error(t,n={},i){this.writeLog({level:"ERROR",message:t,timestamp:new Date,context:{...this.context,...n},error:i})}child(t){return new X({...this.context,...t},this.config)}time(t){let n=Date.now();return()=>{let i=Date.now()-n;this.info(`${t} completed`,{duration:i})}}async measure(t,n,i={}){let e=Date.now(),p={...i,operation:t};this.debug(`Starting ${t}`,p);try{let s=await n(),f=Date.now()-e;return this.info(`Completed ${t}`,{...p,duration:f}),s}catch(s){let f=Date.now()-e;throw this.error(`Failed ${t}`,{...p,duration:f},s instanceof Error?s:Error(String(s))),s}}}var G;function Dt(t,n){return new X(t,n)}function R(){if(!G)G=Dt();return G}function $n(t){G=t}var Hn={debug:(t,n)=>R().debug(t,n),info:(t,n)=>R().info(t,n),warn:(t,n,i)=>R().warn(t,n,i),error:(t,n,i)=>R().error(t,n,i),child:(t)=>R().child(t),time:(t)=>R().time(t),measure:(t,n,i)=>R().measure(t,n,i)};function mn(t){let n=Dt({},t);return async(i,e)=>{let p=Date.now(),f={requestId:Math.random().toString(36).substring(7),method:i.req.method,path:i.req.path,userAgent:i.req.header("user-agent")||"unknown"};n.info("Request started",f);try{await e();let y=Date.now()-p;n.info("Request completed",{...f,status:i.res.status,duration:y})}catch(y){let r=Date.now()-p;throw n.error("Request failed",{...f,duration:r},y instanceof Error?y:Error(String(y))),y}}}class _{static defaultOptions={maxAttempts:3,initialDelay:1000,maxDelay:30000,backoffMultiplier:2,jitter:!0,retryCondition:(t)=>N.isRetryable(t)};static async execute(t,n={}){let i={..._.defaultOptions,...n},e,p=i.initialDelay;for(let s=1;s<=i.maxAttempts;s++)try{return await t()}catch(f){if(e=f,s===i.maxAttempts||!i.retryCondition(e,s))throw e;let y=i.jitter?p+Math.random()*p*0.1:p;i.onRetry?.(e,s),await new Promise((r)=>setTimeout(r,y)),p=Math.min(p*i.backoffMultiplier,i.maxDelay)}throw e}static createRetryableFunction(t,n={}){return async(...i)=>{return _.execute(()=>t(...i),n)}}}class L{static async execute(t,n,i={}){let e={concurrency:5,retryOptions:{maxAttempts:3,initialDelay:1000,maxDelay:1e4,backoffMultiplier:2,jitter:!0},failFast:!1,...i},p=Date.now(),s=[],f=[],y=0,r=_.createRetryableFunction(n,e.retryOptions),c=L.createBatches(t,e.concurrency);for(let a of c){let g=a.map(async(F)=>{try{let K=await r(F);s.push({item:F,result:K})}catch(K){if(f.push({item:F,error:K}),e.failFast)throw new A("MESSAGE_SEND_FAILED",`Bulk operation failed fast after ${f.length} failures`,{totalItems:t.length,failedCount:f.length})}finally{y++,e.onProgress?.(y,t.length,f.length)}});if(await Promise.allSettled(g),e.failFast&&f.length>0)break}let h=Date.now()-p;return{successful:s,failed:f,summary:{total:t.length,successful:s.length,failed:f.length,duration:h}}}static createBatches(t,n){let i=[];for(let e=0;e<t.length;e+=n)i.push(t.slice(e,e+n));return i}}class Tt{options;state="CLOSED";failureCount=0;lastFailureTime=0;nextAttemptTime=0;constructor(t){this.options=t}async execute(t){let n=Date.now();switch(this.state){case"OPEN":if(n<this.nextAttemptTime)throw new A("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 i=await Promise.race([t(),new Promise((e,p)=>setTimeout(()=>p(new A("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 i}catch(i){throw this.recordFailure(),i}}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(t,n){this.maxRequests=t;this.windowMs=n}async acquire(){let t=Date.now();if(this.requests=this.requests.filter((n)=>t-n<this.windowMs),this.requests.length>=this.maxRequests){let n=Math.min(...this.requests),i=this.windowMs-(t-n);if(i>0)return await new Promise((e)=>setTimeout(e,i)),this.acquire()}this.requests.push(t)}canMakeRequest(){let t=Date.now();return this.requests=this.requests.filter((n)=>t-n<this.windowMs),this.requests.length<this.maxRequests}getRemainingRequests(){let t=Date.now();return this.requests=this.requests.filter((n)=>t-n<this.windowMs),Math.max(0,this.maxRequests-this.requests.length)}}var bt=(t)=>({isSuccess:!0,isFailure:!1,value:t}),St=(t)=>({isSuccess:!1,isFailure:!0,error:t}),ni={map(t,n){if(t.isSuccess)return bt(n(t.value));return t},flatMap(t,n){if(t.isSuccess)return n(t.value);return t},mapError(t,n){if(t.isFailure)return St(n(t.error));return t},unwrap(t){if(t.isSuccess)return t.value;throw t.error},unwrapOr(t,n){if(t.isSuccess)return t.value;return n},unwrapOrElse(t,n){if(t.isSuccess)return t.value;return n(t.error)},match(t,n){if(t.isSuccess)return n.ok(t.value);return n.fail(t.error)},async fromPromise(t){try{let n=await t;return bt(n)}catch(n){return St(n)}},isOk(t){return t.isSuccess},isFail(t){return t.isFailure},tap(t,n){return n(t),t},tapOk(t,n){if(t.isSuccess)n(t.value);return t},tapErr(t,n){if(t.isFailure)n(t.error);return t},expect(t,n){if(t.isSuccess)return t.value;throw Error(n,{cause:t.error})}};function pn(){let t=globalThis;return t.__K_MSG_ENV__??t.__ENV__??t.process?.env??{}}function ei(t){let n=pn()[t];if(typeof n==="string")return n;if(n===void 0)return;return String(n)}var sn=["PENDING","SENT","DELIVERED","FAILED","CANCELLED","UNKNOWN"],fn=["DELIVERED","FAILED","CANCELLED","UNKNOWN"],kt=["PENDING","SENT"],rn=new Set(sn),Et=new Set(fn),yn=new Set(kt);function si(t){return rn.has(t)}function fi(t){return Et.has(t)}function ri(t){return Et.has(t)}function yi(t){return yn.has(t)}function ci(){return kt}var cn=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS","NSA","VOICE","FAX","RCS_SMS","RCS_LMS","RCS_MMS","RCS_TPL","RCS_ITPL","RCS_LTPL"],hn=new Set(cn);function di(t){return hn.has(t)}var oi=["PENDING","SENT","FAILED"],dn="PENDING",ai=(t)=>{let n=typeof t==="string"?t.trim().toUpperCase():"";if(n==="PENDING"||n==="SENT"||n==="FAILED")return n;return dn};export{Zt as validateFieldCryptoConfig,qt as validateErrorRetryPolicy,qn as toCiphertextEnvelopeString,$n as setGlobalLogger,Y as selectActiveKidByRollout,lt as resolveFieldMode,ei as readRuntimeEnv,on as parseErrorRetryPolicyFromJson,bt as ok,x as normalizeRetryAfterMs,an as normalizeProviderError,vt as normalizePhoneForHash,ai as normalizeMessageStatus,Bt as normalizeErrorRetryPolicy,mn as loggerMiddleware,Hn as logger,ri as isTerminalDeliveryStatus,yi as isPollableDeliveryStatus,fi as isKMsgTerminalStatus,di as isKMsgMessageType,si as isKMsgDeliveryStatus,Nn as isCryptoEnvelope,pn as getRuntimeEnvSource,gt as getRolloutKnownKids,ci as getPollableStatuses,R as getLogger,St as fail,En as createVaultTransitKeyResolver,Ft as createStaticKeyResolver,wn as createRollingKeyResolver,B as createRefreshableKeyResolver,Un as createNoopFieldCryptoProvider,Dt as createLogger,bn as createEnvKeyResolver,Pt as createDefaultMasker,Dn as createAwsKmsKeyResolver,In as createAesGcmFieldCryptoProvider,Mn as assertFieldCryptoConfig,_ as RetryHandler,ni as Result,Ot as RateLimiter,dn as QUEUED_MESSAGE_STATUS,X as Logger,ut as LogLevel,oi as KNOWN_MESSAGE_STATUSES,I as KMsgErrorCode,A as KMsgError,fn as KMSG_TERMINAL_STATUSES,kt as KMSG_POLLABLE_STATUSES,cn as KMSG_MESSAGE_TYPES,sn as KMSG_DELIVERY_STATUSES,U as FieldCryptoError,N as ErrorUtils,Tt as CircuitBreaker,L as BulkOperationHandler};
1
+ var L;((p)=>{p.INVALID_REQUEST="INVALID_REQUEST";p.AUTHENTICATION_FAILED="AUTHENTICATION_FAILED";p.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE";p.TEMPLATE_NOT_FOUND="TEMPLATE_NOT_FOUND";p.RATE_LIMIT_EXCEEDED="RATE_LIMIT_EXCEEDED";p.NETWORK_ERROR="NETWORK_ERROR";p.NETWORK_TIMEOUT="NETWORK_TIMEOUT";p.NETWORK_SERVICE_UNAVAILABLE="NETWORK_SERVICE_UNAVAILABLE";p.REQUEST_ABORTED="REQUEST_ABORTED";p.PROVIDER_ERROR="PROVIDER_ERROR";p.MESSAGE_SEND_FAILED="MESSAGE_SEND_FAILED";p.CRYPTO_CONFIG_ERROR="CRYPTO_CONFIG_ERROR";p.CRYPTO_ENCRYPT_FAILED="CRYPTO_ENCRYPT_FAILED";p.CRYPTO_DECRYPT_FAILED="CRYPTO_DECRYPT_FAILED";p.CRYPTO_HASH_FAILED="CRYPTO_HASH_FAILED";p.CRYPTO_POLICY_VIOLATION="CRYPTO_POLICY_VIOLATION";p.UNKNOWN_ERROR="UNKNOWN_ERROR"})(L||={});var Ie={["INVALID_REQUEST"]:{ko:"잘못된 요청입니다",en:"Invalid request"},["AUTHENTICATION_FAILED"]:{ko:"인증에 실패했습니다",en:"Authentication failed"},["INSUFFICIENT_BALANCE"]:{ko:"잔액이 부족합니다",en:"Insufficient balance"},["TEMPLATE_NOT_FOUND"]:{ko:"템플릿을 찾을 수 없습니다",en:"Template not found"},["RATE_LIMIT_EXCEEDED"]:{ko:"요청 한도를 초과했습니다",en:"Rate limit exceeded"},["NETWORK_ERROR"]:{ko:"네트워크 오류가 발생했습니다",en:"Network error"},["NETWORK_TIMEOUT"]:{ko:"네트워크 요청 시간이 초과되었습니다",en:"Network timeout"},["NETWORK_SERVICE_UNAVAILABLE"]:{ko:"서비스를 일시적으로 사용할 수 없습니다",en:"Service temporarily unavailable"},["REQUEST_ABORTED"]:{ko:"요청이 취소되었습니다",en:"Request aborted"},["PROVIDER_ERROR"]:{ko:"제공자 오류가 발생했습니다",en:"Provider error"},["MESSAGE_SEND_FAILED"]:{ko:"메시지 전송에 실패했습니다",en:"Message send failed"},["CRYPTO_CONFIG_ERROR"]:{ko:"암호화 설정 오류가 발생했습니다",en:"Crypto configuration error"},["CRYPTO_ENCRYPT_FAILED"]:{ko:"암호화에 실패했습니다",en:"Encryption failed"},["CRYPTO_DECRYPT_FAILED"]:{ko:"복호화에 실패했습니다",en:"Decryption failed"},["CRYPTO_HASH_FAILED"]:{ko:"해시 생성에 실패했습니다",en:"Hash generation failed"},["CRYPTO_POLICY_VIOLATION"]:{ko:"암호화 정책 위반이 발생했습니다",en:"Crypto policy violation"},["UNKNOWN_ERROR"]:{ko:"알 수 없는 오류가 발생했습니다",en:"Unknown error"}},Ne=new Set(Object.values(L)),ee=new Set(["NETWORK_ERROR","RATE_LIMIT_EXCEEDED","NETWORK_TIMEOUT","NETWORK_SERVICE_UNAVAILABLE","PROVIDER_ERROR","UNKNOWN_ERROR"]),te=new Set(["INVALID_REQUEST","AUTHENTICATION_FAILED","INSUFFICIENT_BALANCE","TEMPLATE_NOT_FOUND","MESSAGE_SEND_FAILED","REQUEST_ABORTED","CRYPTO_CONFIG_ERROR","CRYPTO_ENCRYPT_FAILED","CRYPTO_DECRYPT_FAILED","CRYPTO_HASH_FAILED","CRYPTO_POLICY_VIOLATION"]),x=(e)=>{if(typeof e!=="number"||Number.isNaN(e)||!Number.isFinite(e))return;return Math.trunc(e)},O=(e)=>{let t=x(e);if(t===void 0||t<0)return;return t},De=(e)=>{if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0},G=(e)=>typeof e==="string"?e.toLowerCase().trim():void 0,v=(e,t="safe")=>{if(typeof e==="string"){let r=e.trim().toUpperCase();return r.length>0?r:void 0}if(t==="compat"&&(typeof e==="number"||typeof e==="boolean"))return String(e).toUpperCase();return},re=(e,t)=>e?.some((r)=>v(r)===t)??!1,Ue=(e,t)=>{if(t.nonRetryableCodes?.includes(e))return"non_retryable";if(t.retryableCodes?.includes(e))return"retryable";return},ne=(e,t)=>{let r=v(e,"compat");if(!r)return;if(re(t.nonRetryableStatuses,r))return"non_retryable";if(re(t.retryableStatuses,r))return"retryable";return},T=(e)=>typeof e==="object"&&e!==null&&!Array.isArray(e),M=(e,t)=>{for(let r of t)if(r in e)return e[r];return},Be=(e)=>e.length>0?e:"$",ue=(e)=>e==="compat"?"compat":"safe",oe=(e)=>{if(e>=500)return"retryable";if(e===408||e===425||e===429)return"retryable";return"non_retryable"},ie=(e)=>{let t=e.toLowerCase();if(t.includes("timeout")||t.includes("temporar")||t.includes("network")||t.includes("retry"))return"retryable";return};class C extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(e,t,r,n={}){super(t);if(this.name="KMsgError",this.code=e,this.details=r,this.providerErrorCode=n.providerErrorCode,this.providerErrorText=n.providerErrorText,this.httpStatus=x(n.httpStatus),this.requestId=typeof n.requestId==="string"?n.requestId:void 0,this.retryAfterMs=x(n.retryAfterMs),this.attempt=x(n.attempt),Array.isArray(n.causeChain))this.causeChain=n.causeChain;else if(n.causeChain!==void 0)this.causeChain=[n.causeChain];let o=Error.captureStackTrace;if(o)o(this,C)}getLocalizedMessage(e="ko"){let t=Ie[this.code];if(t?.[e])return t[e];return this.message}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details,providerErrorCode:this.providerErrorCode,providerErrorText:this.providerErrorText,httpStatus:this.httpStatus,requestId:this.requestId,retryAfterMs:this.retryAfterMs,attempt:this.attempt,causeChain:this.causeChain}}}var A=(e,t)=>{let r=x(e);if(r!==void 0)return r;if(t==="compat"&&typeof e==="string"){let n=Number(e.trim());if(Number.isFinite(n))return Math.trunc(n)}return},Y=(e,t)=>{let r=De(e);if(r)return r;if(t==="compat"&&(typeof e==="number"||typeof e==="boolean"))return String(e);return},pe=(e)=>{if(typeof e!=="string")return;let t=e.trim().toUpperCase();if(!Ne.has(t))return;return t},R=(e,t)=>{e.push({...t,path:Be(t.path)})},ye=(e,t,r,n,o)=>{if(e===void 0)return[];let i=(()=>{if(Array.isArray(e))return e;if(r==="compat"&&typeof e==="string")return e.split(",").map((a)=>a.trim()).filter((a)=>a.length>0);return R(n,{code:"invalid_type",message:`expected array of ${o.label} values`,path:t}),[]})(),s=[],d=new Set;for(let a=0;a<i.length;a+=1){let l=i[a],c=o.normalize(l);if(!c){R(n,{code:o.label==="code"?"unknown_code":"invalid_status",message:`invalid retry policy ${o.label}: ${String(l)}`,path:`${t}[${a}]`});continue}if(d.has(c)){R(n,{code:o.label==="code"?"duplicate_code":"duplicate_status",message:`duplicate retry policy ${o.label}: ${c}`,path:`${t}[${a}]`});continue}d.add(c),s.push(c)}return s},se=(e,t,r,n)=>ye(e,t,r,n,{label:"code",normalize:(o)=>pe(v(o,r))}),ae=(e,t,r,n)=>ye(e,t,r,n,{label:"status",normalize:(o)=>v(o,r)}),fe=(e,t,r,n)=>{if(e===void 0)return;let o=O(A(e,r));if(o!==void 0)return o;R(n,{code:"invalid_retry_after",message:`invalid retry delay: ${String(e)}`,path:t});return},de=(e,t,r,n)=>{if(e===void 0)return;if(!T(e)){R(n,{code:"invalid_type",message:"expected retry delay map",path:t});return}let o={},i=new Set;for(let[s,d]of Object.entries(e)){let a=v(s,"safe"),l=`${t}.${s}`;if(!a){R(n,{code:"invalid_key",message:"retry delay map key must not be empty",path:l});continue}if(i.has(a)){R(n,{code:"duplicate_key",message:`duplicate retry delay map key: ${a}`,path:l});continue}let c=fe(d,l,r,n);if(c===void 0)continue;i.add(a),o[a]=c}return Object.keys(o).length>0?o:void 0},Ve=(e,t,r)=>{if(e===void 0)return;if(typeof e==="function")return e;if(!T(e)){R(r,{code:"invalid_type",message:"expected retry delay resolver or policy object",path:"retryAfterMs"});return}let n=new Set(["defaultMs","byCode","byStatus"]);for(let d of Object.keys(e)){if(n.has(d))continue;R(r,{code:"unknown_field",message:`unknown retry-after policy field: ${d}`,path:`retryAfterMs.${d}`})}let o=fe(e.defaultMs,"retryAfterMs.defaultMs",t,r),i=de(e.byCode,"retryAfterMs.byCode",t,r),s=de(e.byStatus,"retryAfterMs.byStatus",t,r);if(o===void 0&&i===void 0&&s===void 0)return;return{...o!==void 0?{defaultMs:o}:{},...i!==void 0?{byCode:i}:{},...s!==void 0?{byStatus:s}:{}}},$e=(e,t,r)=>{if(e===void 0)return;if(typeof e==="string"){let n=e.trim().toLowerCase();if(n==="retryable")return"retryable";if(n==="non_retryable"||n==="non-retryable")return"non_retryable"}if(t==="compat"&&typeof e==="boolean")return e?"retryable":"non_retryable";R(r,{code:"invalid_fallback",message:`invalid fallback value: ${String(e)}`,path:"fallback"});return};function ze(e,t={}){let r=ue(t.mode),n=[];if(!T(e))return R(n,{code:"invalid_root",message:"retry policy must be an object",path:"$"}),{policy:null,issues:n};let o=new Set(["retryableCodes","nonRetryableCodes","retryableStatuses","nonRetryableStatuses","fallback","retryAfterMs"]);for(let p of Object.keys(e)){if(o.has(p))continue;R(n,{code:"unknown_field",message:`unknown retry policy field: ${p}`,path:p})}let i=se(e.retryableCodes,"retryableCodes",r,n),s=se(e.nonRetryableCodes,"nonRetryableCodes",r,n),d=ae(e.retryableStatuses,"retryableStatuses",r,n),a=ae(e.nonRetryableStatuses,"nonRetryableStatuses",r,n),l=$e(e.fallback,r,n),c=Ve(e.retryAfterMs,r,n),y=new Set(i),f=new Set(s);for(let p of y){if(!f.has(p))continue;y.delete(p),R(n,{code:"conflicting_code",message:`code '${p}' is both retryable and nonRetryable; nonRetryable wins`,path:"retryableCodes"})}let g=new Set(d),E=new Set(a);for(let p of g){if(!E.has(p))continue;g.delete(p),R(n,{code:"conflicting_status",message:`status '${p}' is both retryable and nonRetryable; nonRetryable wins`,path:"retryableStatuses"})}let h={...y.size>0?{retryableCodes:Array.from(y)}:{},...f.size>0?{nonRetryableCodes:Array.from(f)}:{},...g.size>0?{retryableStatuses:Array.from(g)}:{},...E.size>0?{nonRetryableStatuses:Array.from(E)}:{},...l?{fallback:l}:{},...c?{retryAfterMs:c}:{}};return{policy:h.retryableCodes!==void 0||h.nonRetryableCodes!==void 0||h.retryableStatuses!==void 0||h.nonRetryableStatuses!==void 0||h.fallback!==void 0||h.retryAfterMs!==void 0?h:null,issues:n}}function qe(e,t={}){return ze(e,t).policy}function Mt(e,t={}){if(typeof e!=="string"||e.trim().length===0)return null;try{let r=JSON.parse(e);return qe(r,t)}catch{return null}}var le=(e,t)=>{let r=e.response;if(!T(r))return;return A(M(r,["status","statusCode","httpStatus"]),t)},Ge=(e,t)=>{if(e instanceof C&&Array.isArray(e.causeChain))return e.causeChain.slice();if(T(e)){let i=e.causeChain;if(Array.isArray(i))return i.slice();let s=e.details;if(t==="compat"&&T(s)){let d=s.causeChain;if(Array.isArray(d))return d.slice();if(d!==void 0)return[d]}}let r=[],n=new Set,o=e;for(let i=0;i<8;i+=1){if(!T(o))break;let s=o.cause;if(s===void 0||n.has(s))break;n.add(s),r.push(s),o=s}return r.length>0?r:void 0},Ye=(e)=>{if(e instanceof Error&&typeof e.message==="string")return e.message;if(T(e)&&typeof e.message==="string")return e.message;return typeof e==="string"?e:"Unknown error"},ce=(e,t)=>{let r=v(t,"compat");if(!e||!r)return;if(Object.hasOwn(e,r))return O(e[r]);for(let[n,o]of Object.entries(e)){if(v(n)!==r)continue;return O(o)}return},ge=(e,t)=>{let r=t?.retryAfterMs;if(typeof r==="function"){let d=O(r(e));if(d!==void 0)return{value:d,source:"policy"}}let n=O(e.retryAfterMs);if(n!==void 0)return{value:n,source:"input"};if(!r||typeof r==="function")return{};let o=[e.providerErrorCode,e.code];for(let d of o){let a=ce(r.byCode,d);if(a!==void 0)return{value:a,source:"policy"}}let i=ce(r.byStatus,e.httpStatus);if(i!==void 0)return{value:i,source:"policy"};let s=O(r.defaultMs);return s!==void 0?{value:s,source:"policy"}:{}};function Ot(e,t={}){let r=ue(t.mode),o=t.defaultCode??"UNKNOWN_ERROR",i={code:"fallback",classification:t.policy?"policy":"fallback"},s,d,a,l,c,y,f,g=(u)=>{if(u.providerErrorCode!==void 0)s=u.providerErrorCode,i.providerErrorCode="metadata";if(u.providerErrorText!==void 0)d=u.providerErrorText,i.providerErrorText="metadata";if(u.httpStatus!==void 0)a=u.httpStatus,i.httpStatus="metadata";if(u.requestId!==void 0)l=u.requestId,i.requestId="metadata";if(u.retryAfterMs!==void 0)c=O(u.retryAfterMs),i.retryAfterMs="metadata";if(u.attempt!==void 0)y=A(u.attempt,r),i.attempt="metadata";if(Array.isArray(u.causeChain))f=u.causeChain.slice(),i.causeChain="metadata"},E=(u,b)=>{if(s===void 0){let m=Y(M(u,["providerErrorCode","errorCode","resultCode"]),r);if(m!==void 0)s=m,i.providerErrorCode=b}if(d===void 0){let m=Y(M(u,["providerErrorText","errorMessage","msg","message"]),r);if(m!==void 0)d=m,i.providerErrorText=b}if(a===void 0){let m=A(M(u,["httpStatus","statusCode","status"]),r)??le(u,r);if(m!==void 0)a=m,i.httpStatus=b==="details"?"details":"http"}if(l===void 0){let m=Y(M(u,["requestId","request_id","reqId","traceId"]),r);if(m!==void 0)l=m,i.requestId=b}if(c===void 0){let m=O(A(M(u,["retryAfterMs","retry_after_ms","retryAfter"]),r));if(m!==void 0)c=m,i.retryAfterMs=b}if(y===void 0){let m=A(u.attempt,r);if(m!==void 0&&m>0)y=m,i.attempt=b}};if(e instanceof C){if(o=e.code,i.code="input",g(e),r==="compat"&&T(e.details))E(e.details,"details")}else if(T(e)){let u=pe(M(e,["code","errorCode","resultCode"]));if(u!==void 0)o=u,i.code="input";else if(a===void 0){let b=A(M(e,["httpStatus","statusCode","status"]),r)??le(e,r);if(b!==void 0&&b>=500)o="PROVIDER_ERROR",i.code="http"}if(E(e,"input"),r==="compat"&&T(e.details))E(e.details,"details")}if(f===void 0){let u=Ge(e,r);if(u!==void 0)f=u,i.causeChain="input"}if(t.attempt!==void 0&&A(t.attempt,r)!==void 0){let u=A(t.attempt,r);if(u!==void 0&&u>0)y=u,i.attempt="input"}let h=new C(o,Ye(e),void 0,{providerErrorCode:s,providerErrorText:d,httpStatus:a,requestId:l,retryAfterMs:c,attempt:y,causeChain:f}),S=ge(h,t.policy);if(S.value!==void 0){if(c=S.value,S.source==="policy")i.retryAfterMs="policy"}let p=F.classifyForRetry(h,t.policy);return{code:o,classification:p,...s!==void 0?{providerErrorCode:s}:{},...d!==void 0?{providerErrorText:d}:{},...a!==void 0?{httpStatus:a}:{},...l!==void 0?{requestId:l}:{},...c!==void 0?{retryAfterMs:c}:{},...y!==void 0?{attempt:y}:{},...f!==void 0?{causeChain:f}:{},sources:i}}var F={isRetryable(e,t={}){return F.classifyForRetry(e,t)==="retryable"},classifyForRetry(e,t={}){if(e instanceof C){let a=Ue(e.code,t);if(a)return a;let l=ne(e.httpStatus,t);if(l)return l;if(new Set(t.retryableCodes??Array.from(ee)).has(e.code))return"retryable";if(new Set(t.nonRetryableCodes??Array.from(te)).has(e.code))return"non_retryable";if(e.httpStatus!==void 0)return oe(e.httpStatus);let f=ie(e.message);if(f)return f;if(t.classifyByMessage&&e.message){let g=t.classifyByMessage(e.message);if(g)return g}if(t.fallback)return t.fallback;return"non_retryable"}let r=e&&typeof e==="object"?e:void 0,n=v(r?.status,"compat")??v(r?.statusCode,"compat")??v(r?.httpStatus,"compat")??v(r?.code,"compat"),o=G(r?.status)??G(r?.statusCode)??G(r?.code),i=x(r?.status)??x(r?.statusCode)??x(r?.httpStatus),s=ne(n,t);if(s)return s;if(o?.startsWith("5"))return"retryable";if(i!==void 0){if(t.classifyByStatusCode)return t.classifyByStatusCode(i);return oe(i)}let d=typeof r?.message==="string"?ie(r.message):void 0;if(d)return d;if(t.classifyByMessage&&typeof r?.message==="string"){let a=t.classifyByMessage(r.message);if(a)return a}return t.fallback??"non_retryable"},resolveRetryAfterMs(e,t){return ge(e,t).value},isUnknownStatus:(e)=>{if(e===void 0||Number.isNaN(e)||!Number.isFinite(e))return!1;return e<500},toRetryMetadata(e){return{providerErrorCode:e.providerErrorCode,providerErrorText:e.providerErrorText,httpStatus:e.httpStatus,requestId:e.requestId,retryAfterMs:e.retryAfterMs,attempt:e.attempt,causeChain:e.causeChain}},withAttempt(e,t){return new C(e.code,e.message,e.details,{...F.toRetryMetadata(e),attempt:x(t)})},DEFAULT_RETRYABLE_ERROR_CODES:ee,DEFAULT_NON_RETRYABLE_ERROR_CODES:te};function He(e){switch(e){case"config":return"CRYPTO_CONFIG_ERROR";case"encrypt":return"CRYPTO_ENCRYPT_FAILED";case"decrypt":return"CRYPTO_DECRYPT_FAILED";case"hash":return"CRYPTO_HASH_FAILED";case"policy":return"CRYPTO_POLICY_VIOLATION"}}class _ extends C{kind;fieldPath;failMode;openFallback;constructor(e,t,r,n={}){super(He(e),t,r,n);this.name="FieldCryptoError",this.kind=e,this.fieldPath=typeof n.fieldPath==="string"?n.fieldPath:void 0,this.failMode=n.failMode,this.openFallback=n.openFallback}toJSON(){return{...super.toJSON(),kind:this.kind,fieldPath:this.fieldPath,failMode:this.failMode,openFallback:this.openFallback}}}var je=["tenantId","providerId","messageId"];function N(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function We(e){if(typeof e!=="number"||!Number.isFinite(e))return;if(e<=0||e>100)return;return e}function me(e){let t=[];for(let r of e){let n=N(r.kid),o=We(r.percentage);if(!n||o===void 0)continue;t.push({kid:n,percentage:o})}return t}function Je(e,t,r){let n=t.map((o)=>{let i=e[o];return typeof i==="string"?i:""}).join("|");return`${r}::${n}`}function Qe(e){let t=2166136261;for(let r=0;r<e.length;r+=1)t^=e.charCodeAt(r),t=t*16777619>>>0;return t>>>0}function Xe(e,t){let r=0;for(let n of e)if(r+=n.percentage,t<r)return n.kid;return}function H(e,t,r){let n=me(t.buckets),o=N(t.defaultKid)??N(r);if(n.length===0)return o;let i=N(t.seed)??"kmsg-rollout-v1",s=t.stickyFields??je,d=Je(e,s,i),a=Qe(d)%100;return Xe(n,a)??o}function Ee(e){return me(e.buckets).map((t)=>t.kid)}function P(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function j(e){if(!Array.isArray(e))return[];return e.map((t)=>P(t)).filter((t)=>Boolean(t))}function W(e){let t=[],r=new Set;for(let n of e){let o=P(n);if(!o||r.has(o))continue;r.add(o),t.push(o)}return t}function Ze(e){return P(e.providerId)??"default"}function he(e){let t=P(e.activeKid)??"default",r=W([t,...j(e.decryptKids)]);return{async resolveEncryptKey(){return{kid:t}},async resolveDecryptKeys(){return r}}}function D(e){let t=typeof e.cacheTtlMs==="number"&&e.cacheTtlMs>=0?Math.trunc(e.cacheTtlMs):30000,r=P(e.fallback?.activeKid),n=j(e.fallback?.decryptKids),o;async function i(s){let d=Date.now();if(o&&d<o.expiresAt)return o.value;let a=await e.provider.loadKeySet(s),l=P(a.activeKid)??r??Ze(s),c=W([l,...j(a.decryptKids),...n]),y={activeKid:l,decryptKids:c,refreshedAt:Date.now()};return o={value:y,expiresAt:Date.now()+t},y}return{async resolveEncryptKey(s){return{kid:(await i(s)).activeKid}},async resolveDecryptKeys(s){let d=await i(s);return d.decryptKids??[d.activeKid]}}}function Lt(e,t){return{async resolveEncryptKey(r){let n=await e.resolveEncryptKey(r);return{kid:H(r,t,n.kid)??n.kid}},async resolveDecryptKeys(r){let n=await e.resolveEncryptKey(r),o=e.resolveDecryptKeys?await e.resolveDecryptKeys(r):[n.kid],i=H(r,t,n.kid),s=Ee(t);return W([...i?[i]:[],n.kid,...o??[],...s])}}}function Dt(e){return D({provider:{async loadKeySet(r){return e.client.getKeyState({...r,...e.keyAlias?{keyAlias:e.keyAlias}:{},...e.region?{region:e.region}:{}})}},cacheTtlMs:e.cacheTtlMs,fallback:{activeKid:e.fallbackActiveKid,decryptKids:e.fallbackDecryptKids}})}function U(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function Ce(e,t){return U(e[t])}function et(e,t){if(!e)return[];return e.split(t).map((r)=>U(r)).filter((r)=>Boolean(r))}function Vt(e={}){let t=globalThis.process?.env,r=e.env??t??{},n=U(e.delimiter)??",",o=e.activeKidEnv??"KMSG_ACTIVE_KID",i=e.decryptKidsEnv??"KMSG_DECRYPT_KIDS",s=Ce(r,o)??U(e.fallbackActiveKid)??"default",d=[s,...et(Ce(r,i),n),...e.fallbackDecryptKids??[]];return he({activeKid:s,decryptKids:d})}function qt(e){return D({provider:{async loadKeySet(r){return e.client.getKeyState({...r,...e.mountPath?{mountPath:e.mountPath}:{},...e.keyName?{keyName:e.keyName}:{},...e.namespace?{namespace:e.namespace}:{}})}},cacheTtlMs:e.cacheTtlMs,fallback:{activeKid:e.fallbackActiveKid,decryptKids:e.fallbackDecryptKids}})}function J(e){return typeof e==="function"}function Re(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function Se(e,t,r){let n=e.fields[t];if(n)return n;if(t.startsWith("metadata.")){let o=e.fields["metadata.*"];if(o)return o}return r}var tt=["closed","open"],be=["masked","plaintext","null"];function rt(e){return e.failMode==="open"?"open":"closed"}function nt(e){let t=e.openFallback;return t!==void 0&&be.includes(t)?t:"masked"}function ot(e,t={}){let r=[];if(!e||typeof e!=="object")return{valid:!1,issues:[{message:"fieldCrypto config must be an object",rule:"fieldCrypto.config.object",hint:"Provide a valid FieldCryptoConfig object"}]};if(!e.provider||typeof e.provider!=="object")r.push({message:"fieldCrypto provider is required",rule:"fieldCrypto.provider.required",path:"provider",hint:"Set provider with encrypt/decrypt/hash methods"});else{if(!J(e.provider.encrypt))r.push({message:"provider.encrypt must be a function",rule:"fieldCrypto.provider.encrypt.required",path:"provider.encrypt"});if(!J(e.provider.decrypt))r.push({message:"provider.decrypt must be a function",rule:"fieldCrypto.provider.decrypt.required",path:"provider.decrypt"});if(!J(e.provider.hash))r.push({message:"provider.hash must be a function",rule:"fieldCrypto.provider.hash.required",path:"provider.hash"})}if(!e.fields||typeof e.fields!=="object")r.push({message:"fieldCrypto.fields must be an object",rule:"fieldCrypto.fields.object",path:"fields",hint:"Define policies such as to, from, metadata.phoneNumber"});else{let i=Object.entries(e.fields);if(i.length===0)r.push({message:"fieldCrypto.fields must not be empty",rule:"fieldCrypto.fields.non_empty",path:"fields",hint:"Add at least one field mode mapping"});for(let[s,d]of i){if(!Re(s))r.push({message:"field path must be a non-empty string",rule:"fieldCrypto.fields.path.non_empty",path:"fields"});if(d!=="plain"&&d!=="encrypt"&&d!=="encrypt+hash"&&d!=="mask")r.push({message:`unsupported field mode: ${String(d)}`,rule:"fieldCrypto.fields.mode.supported",path:`fields.${s}`})}}if(e.failMode!==void 0&&!tt.includes(e.failMode))r.push({message:`unsupported failMode: ${String(e.failMode)}`,rule:"fieldCrypto.fail_mode.supported",path:"failMode",hint:'Use "closed" (default) or "open"'});if(e.openFallback!==void 0&&!be.includes(e.openFallback))r.push({message:`unsupported openFallback: ${String(e.openFallback)}`,rule:"fieldCrypto.open_fallback.supported",path:"openFallback",hint:'Use "masked" (default), "null", or "plaintext"'});let n=rt(e),o=nt(e);if(n==="open"&&o==="plaintext"&&e.unsafeAllowPlaintextStorage!==!0)r.push({message:"openFallback=plaintext requires unsafeAllowPlaintextStorage=true",rule:"fieldCrypto.fail_open.plaintext_guard",path:"openFallback",hint:"Use masked/null fallback, or explicitly enable unsafe plaintext"});if(Array.isArray(e.aadFields)){if(e.aadFields.length===0)r.push({message:"aadFields must not be empty when provided",rule:"fieldCrypto.aad_fields.non_empty",path:"aadFields"});for(let i=0;i<e.aadFields.length;i+=1){let s=e.aadFields[i];if(!Re(s))r.push({message:"aadFields cannot include empty key",rule:"fieldCrypto.aad_fields.no_empty_key",path:`aadFields[${i}]`})}}if(t.secureMode&&!t.compatPlainColumns){let i=Se(e,"to","encrypt+hash"),s=Se(e,"from","encrypt+hash");if(i==="plain")r.push({message:"secure mode requires non-plain policy for `to` when compatPlainColumns=false",rule:"fieldCrypto.secure_mode.to_non_plain",path:"fields.to",hint:"Use encrypt+hash for lookup fields"});if(s==="plain")r.push({message:"secure mode requires non-plain policy for `from` when compatPlainColumns=false",rule:"fieldCrypto.secure_mode.from_non_plain",path:"fields.from",hint:"Use encrypt+hash for lookup fields"})}return{valid:r.length===0,issues:r}}function Ht(e,t={}){let r=ot(e,t);if(r.valid)return;let n=r.issues[0];if(!n)throw new _("config","fieldCrypto config validation failed",{rule:"fieldCrypto.config.invalid",issues:r.issues});throw new _("config",n.message,{rule:n.rule,path:n.path,hint:n.hint,issues:r.issues},{fieldPath:n.path})}function B(e){let t=e instanceof Uint8Array?e:new Uint8Array(e),r=typeof globalThis<"u"?globalThis.Buffer:void 0;return(r?r.from(t).toString("base64"):btoa(String.fromCharCode(...t))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function V(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),r=t.length%4===0?t:`${t}${"=".repeat(4-t.length%4)}`,n=typeof globalThis<"u"?globalThis.Buffer:void 0;if(n)return new Uint8Array(n.from(r,"base64"));let o=atob(r),i=new Uint8Array(o.length);for(let s=0;s<o.length;s+=1)i[s]=o.charCodeAt(s);return i}function ve(e,t){if(e instanceof Uint8Array)return e;if(e instanceof ArrayBuffer)return new Uint8Array(e);if(t==="base64url")return V(e);return new TextEncoder().encode(e)}function it(e){let t=e instanceof Uint8Array?e:new Uint8Array(e);return Array.from(t).map((r)=>r.toString(16).padStart(2,"0")).join("")}function k(e){let t=new Uint8Array(e.byteLength);return t.set(e),t.buffer}function Te(e){let t=JSON.parse(e);if(!t||typeof t!=="object"||typeof t.v!=="number"||typeof t.alg!=="string"||typeof t.kid!=="string"||typeof t.iv!=="string"||typeof t.tag!=="string"||typeof t.ct!=="string")throw Error("Invalid ciphertext envelope");return t}function st(e){if(typeof e==="string")return e;return JSON.stringify(e)}function at(e){if(!e||typeof e!=="object")return!1;let t=e;return typeof t.v==="number"&&typeof t.alg==="string"&&typeof t.kid==="string"&&typeof t.iv==="string"&&typeof t.tag==="string"&&typeof t.ct==="string"}function dt(e){let t=String(e??"").trim();if(t.length===0)return"";let r=t.startsWith("+"),n=t.replace(/\D/g,"");return r?`+${n}`:n}function Ae(e=3,t=2){return(r)=>{let n=String(r??"");if(n.length<=e+t)return"*".repeat(Math.max(0,n.length));let o=n.slice(0,e),i=n.slice(-t);return`${o}${"*".repeat(n.length-e-t)}${i}`}}function Jt(e){let t=e.algorithm??"A256GCM",r=e.keyEncoding??"base64url",n=e.hashKeyEncoding??r,o=new Map,i=new Map,s=(a)=>{let l=o.get(a);if(l)return l;let c=e.keys[a];if(!c)throw Error(`Unknown encryption key id: ${a}`);let y=ve(c,r),f=crypto.subtle.importKey("raw",k(y),"AES-GCM",!1,["encrypt","decrypt"]);return o.set(a,f),f},d=(a)=>{let l=i.get(a);if(l)return l;let c=e.hashKeys?.[a]??e.keys[a];if(!c)throw Error(`Unknown hash key id: ${a}`);let y=ve(c,n),f=crypto.subtle.importKey("raw",k(y),{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return i.set(a,f),f};return{async encrypt(a){let l=a.kid??e.activeKid,c=await s(l),y=crypto.getRandomValues(new Uint8Array(12)),f=new TextEncoder().encode(JSON.stringify(a.aad??{})),g=new TextEncoder().encode(a.value),E=await crypto.subtle.encrypt({name:"AES-GCM",iv:k(y),additionalData:k(f),tagLength:128},c,k(g)),h=new Uint8Array(E),S=h.slice(h.length-16),p=h.slice(0,h.length-16);return{ciphertext:{v:1,alg:t,kid:l,iv:B(y),tag:B(S),ct:B(p)},kid:l}},async decrypt(a){let l=Te(a.ciphertext),c=a.candidateKids&&a.candidateKids.length>0?a.candidateKids:[l.kid],y=V(l.iv),f=V(l.tag),g=V(l.ct),E=new Uint8Array(g.length+f.length);E.set(g,0),E.set(f,g.length);let h=new TextEncoder().encode(JSON.stringify(a.aad??{})),S;for(let p of c)try{let u=await s(p),b=await crypto.subtle.decrypt({name:"AES-GCM",iv:k(y),additionalData:k(h),tagLength:128},u,k(E));return new TextDecoder().decode(new Uint8Array(b))}catch(u){S=u}throw Error(`Failed to decrypt ciphertext: ${S instanceof Error?S.message:String(S??"unknown")}`)},async hash(a){let l=a.kid??e.activeKid,c=await d(l),y=await crypto.subtle.sign("HMAC",c,k(new TextEncoder().encode(a.value)));return it(y)},mask(a){return Ae()(a.value)}}}function Qt(){return{encrypt(e){return{ciphertext:JSON.stringify({v:1,alg:"NOOP",kid:"noop",iv:"",tag:"",ct:e.value})}},decrypt(e){try{return Te(e.ciphertext).ct}catch{return e.ciphertext}},hash(e){let t=dt(e.value);return B(new TextEncoder().encode(t))},mask(e){return Ae()(e.value)}}}function lt(e){let t=at(e);if(t&&e.v===1&&e.alg==="A256GCM")return;let r=e&&typeof e==="object"?e:{};throw new _("policy","ciphertext envelope must be v1 A256GCM with string kid, iv, tag, and ct",{rule:"fieldCrypto.envelope.v1",shapeValid:t,v:r.v,alg:r.alg})}function Xt(e){if(typeof e==="string")return e;lt(e);let{v:t,alg:r,kid:n,iv:o,tag:i,ct:s}=e;return st({v:t,alg:r,kid:n,iv:o,tag:i,ct:s})}var ct;((o)=>{o.DEBUG="DEBUG";o.INFO="INFO";o.WARN="WARN";o.ERROR="ERROR"})(ct||={});var ut=["to","from","phone","phoneNumber","recipient","sender","secret","apiKey","apiSecret","authorization","auth","token","password","payload","message","content","text"],I=String.raw`\w.[\]"'-`,pt=new RegExp(String.raw`^[${I}]*(?:(?:secret|password|passwd|passphrase|token|credential|private[-_.]?key|api[-_.]?key)[${I}]*|auth(?:orization)?(?:[.[\]"'][${I}]*)?)$`,"i");function ke(e){return pt.test(e.replace(/\s+/g,"_"))}function yt(e){if(ke(e))return!0;let t=e.toLowerCase();return ut.some((r)=>t.includes(r.toLowerCase()))}function Me(e){let t=e.trim();if(t.length<=4)return"***";if(t.includes("@")){let[o,i]=t.split("@");return`${o.slice(0,2)}${"*".repeat(Math.max(1,o.length-2))}@${i}`}let r=t.slice(0,3),n=t.slice(-2);return`${r}${"*".repeat(Math.max(1,t.length-5))}${n}`}var ft=new RegExp([String.raw`(?:\+82[-.\s]?(?:\(0\)[-.\s]?|0)?|0)(?:1[016789]|2|70|80|50\d|[3-6]\d)[-.\s]?\d{3,4}[-.\s]?\d{4}`,String.raw`\(0\d{1,2}\)[-.\s]?\d{3,4}[-.\s]?\d{4}`,String.raw`1[5-9]\d{2}[-\s]\d{4}`].map((e)=>String.raw`(?<![\w+])${e}(?!\w)`).join("|"),"g"),gt=/(\b[a-z][\w+.-]{0,31}:\/\/[^\s/:@]*):[^\s/?#]*@/gi,mt=[String.raw`"(?:\\.|[^"\\\n])*"?`,String.raw`'(?:\\.|[^'\\\n])*'?`,String.raw`\\"(?:\\\\(?:\\.|[^\\\n])|\\[^"\\\n]|[^\\\n])*(?:\\")?`,String.raw`\\'(?:\\\\(?:\\.|[^\\\n])|\\[^'\\\n]|[^\\\n])*(?:\\')?`],Et=new RegExp(String.raw`(?<![${I}])((?:["']?(?:api|private)[ \t]+)?[${I}]+)((?:\\?["'])?\s*[:=]\s*)`,"gi"),xe=new RegExp(String.raw`${mt.join("|")}|((?:Bearer|Basic)\s+)?[^\s"',;&]+`,"iy");function ht(e){let t="",r=0;for(let n of e.matchAll(Et)){let[o,i=""]=n;if(n.index<r||!ke(i))continue;let s=n.index+o.length;xe.lastIndex=s;let d=xe.exec(e);if(!d)continue;let a=/^\\?["']/.exec(d[0])?.[0];t+=e.slice(r,s),t+=a?`${a}[REDACTED]${a}`:`${d[1]??""}[REDACTED]`,r=s+d[0].length}return t+e.slice(r)}function z(e){return ht(e.replace(gt,"$1:[REDACTED]@").replace(ft,(t)=>Me(t)))}function Q(e,t){if(t===void 0||t===null)return t;if(yt(e)){if(typeof t==="string")return Me(t);if(typeof t==="number"||typeof t==="boolean")return"***";if(Array.isArray(t))return"[REDACTED]";if(typeof t==="object")return"[REDACTED]"}if(Array.isArray(t))return t.map((r)=>Q(e,r));if(typeof t==="object"){let r={};for(let[n,o]of Object.entries(t))r[n]=Q(n,o);return r}if(typeof t==="string")return z(t);return t}function Ct(e){let t={};for(let[r,n]of Object.entries(e))t[r]=Q(r,n);return t}class X{config;context;constructor(e={},t={}){this.context=e,this.config={level:"INFO",enableConsole:!0,enableJson:!1,enableColors:!0,...t}}shouldLog(e){let t=["DEBUG","INFO","WARN","ERROR"];return t.indexOf(e)>=t.indexOf(this.config.level)}formatMessage(e){let t=Ct(e.context),r=z(e.message),n=e.error&&{name:e.error.name,message:z(e.error.message),stack:e.error.stack?z(e.error.stack):void 0};if(this.config.enableJson)return JSON.stringify({level:e.level,message:r,timestamp:e.timestamp.toISOString(),context:t,...n&&{error:n},...e.duration&&{duration:e.duration}});let o=e.timestamp.toISOString(),i=this.config.enableColors?this.colorizeLevel(e.level):e.level,s=Object.keys(t).length>0?` [${Object.entries(t).map(([a,l])=>`${a}=${l}`).join(", ")}]`:"",d=`${o} ${i}${s}: ${r}`;if(e.duration!==void 0)d+=` (${e.duration}ms)`;if(n)d+=`
2
+ ${n.stack??`${n.name}: ${n.message}`}`;return d}colorizeLevel(e){if(!this.config.enableColors)return e;return`${{["DEBUG"]:"\x1B[36m",["INFO"]:"\x1B[32m",["WARN"]:"\x1B[33m",["ERROR"]:"\x1B[31m"}[e]}${e}\x1B[0m`}writeLog(e){if(!this.shouldLog(e.level))return;let t=this.formatMessage(e);if(this.config.enableConsole)(e.level==="ERROR"?console.error:e.level==="WARN"?console.warn:console.log)(t);if(this.config.enableFile&&this.config.filePath);}debug(e,t={}){this.writeLog({level:"DEBUG",message:e,timestamp:new Date,context:{...this.context,...t}})}info(e,t={}){this.writeLog({level:"INFO",message:e,timestamp:new Date,context:{...this.context,...t}})}warn(e,t={},r){this.writeLog({level:"WARN",message:e,timestamp:new Date,context:{...this.context,...t},error:r})}error(e,t={},r){this.writeLog({level:"ERROR",message:e,timestamp:new Date,context:{...this.context,...t},error:r})}child(e){return new X({...this.context,...e},this.config)}time(e){let t=Date.now();return()=>{let r=Date.now()-t;this.info(`${e} completed`,{duration:r})}}async measure(e,t,r={}){let n=Date.now(),o={...r,operation:e};this.debug(`Starting ${e}`,o);try{let i=await t(),s=Date.now()-n;return this.info(`Completed ${e}`,{...o,duration:s}),i}catch(i){let s=Date.now()-n;throw this.error(`Failed ${e}`,{...o,duration:s},i instanceof Error?i:Error(String(i))),i}}}var q;function Oe(e,t){return new X(e,t)}function K(){if(!q)q=Oe();return q}function er(e){q=e}var tr={debug:(e,t)=>K().debug(e,t),info:(e,t)=>K().info(e,t),warn:(e,t,r)=>K().warn(e,t,r),error:(e,t,r)=>K().error(e,t,r),child:(e)=>K().child(e),time:(e)=>K().time(e),measure:(e,t,r)=>K().measure(e,t,r)};function rr(e){let t=Oe({},e);return async(r,n)=>{let o=Date.now(),s={requestId:Math.random().toString(36).substring(7),method:r.req.method,path:r.req.path,userAgent:r.req.header("user-agent")||"unknown"};t.info("Request started",s);try{await n();let d=Date.now()-o;t.info("Request completed",{...s,status:r.res.status,duration:d})}catch(d){let a=Date.now()-o;throw t.error("Request failed",{...s,duration:a},d instanceof Error?d:Error(String(d))),d}}}class w{static defaultOptions={maxAttempts:3,initialDelay:1000,maxDelay:30000,backoffMultiplier:2,jitter:!0,retryCondition:(e)=>F.isRetryable(e)};static async execute(e,t={}){let r={...w.defaultOptions,...t},n,o=r.initialDelay;for(let i=1;i<=r.maxAttempts;i++)try{return await e()}catch(s){if(n=s,i===r.maxAttempts||!r.retryCondition(n,i))throw n;let d=r.jitter?o+Math.random()*o*0.1:o;r.onRetry?.(n,i),await new Promise((a)=>setTimeout(a,d)),o=Math.min(o*r.backoffMultiplier,r.maxDelay)}throw n}static createRetryableFunction(e,t={}){return async(...r)=>w.execute(()=>e(...r),t)}}class Z{static async execute(e,t,r={}){let n={concurrency:5,retryOptions:{maxAttempts:3,initialDelay:1000,maxDelay:1e4,backoffMultiplier:2,jitter:!0},failFast:!1,...r},o=Date.now(),i=[],s=[],d=0,a=w.createRetryableFunction(t,n.retryOptions),l=Z.createBatches(e,n.concurrency);for(let y of l){let f=y.map(async(g)=>{try{let E=await a(g);i.push({item:g,result:E})}catch(E){if(s.push({item:g,error:E}),n.failFast)throw new C("MESSAGE_SEND_FAILED",`Bulk operation failed fast after ${s.length} failures`,{totalItems:e.length,failedCount:s.length})}finally{d++,n.onProgress?.(d,e.length,s.length)}});if(await Promise.allSettled(f),n.failFast&&s.length>0)break}let c=Date.now()-o;return{successful:i,failed:s,summary:{total:e.length,successful:i.length,failed:s.length,duration:c}}}static createBatches(e,t){let r=[];for(let n=0;n<e.length;n+=t)r.push(e.slice(n,n+t));return r}}class Ke{options;state="CLOSED";failureCount=0;lastFailureTime=0;nextAttemptTime=0;trial;constructor(e){this.options=e}async execute(e){let t=Date.now();switch(this.state){case"OPEN":if(t<this.nextAttemptTime)throw new C("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}let r;if(this.state==="HALF_OPEN"){if(this.trial)throw new C("NETWORK_SERVICE_UNAVAILABLE","Circuit breaker is HALF_OPEN and a trial call is in flight",{state:this.state});r=Symbol("trial"),this.trial=r}let n;try{let o=await Promise.race([e(),new Promise((i,s)=>{n=setTimeout(()=>s(new C("NETWORK_TIMEOUT","Circuit breaker timeout",{timeout:this.options.timeout})),this.options.timeout)})]);return this.recordSuccess(),o}catch(o){throw this.recordFailure(),o}finally{if(n!==void 0)clearTimeout(n);if(r&&this.trial===r)this.trial=void 0}}recordSuccess(){if(this.state==="HALF_OPEN"){this.state="CLOSED",this.failureCount=0,this.options.onClose?.();return}if(this.state==="CLOSED")this.failureCount=0}recordFailure(){if(this.failureCount++,this.lastFailureTime=Date.now(),this.state==="HALF_OPEN"||this.failureCount>=this.options.failureThreshold){let e=this.state==="OPEN";if(this.state="OPEN",this.nextAttemptTime=this.lastFailureTime+this.options.resetTimeout,!e)this.options.onOpen?.()}}getState(){return this.state}getFailureCount(){return this.failureCount}reset(){this.state="CLOSED",this.failureCount=0,this.lastFailureTime=0,this.nextAttemptTime=0,this.trial=void 0}}class _e{maxRequests;windowMs;requests=[];constructor(e,t){this.maxRequests=e;this.windowMs=t}async acquire(){let e=Date.now();if(this.requests=this.requests.filter((t)=>e-t<this.windowMs),this.requests.length>=this.maxRequests){let t=Math.min(...this.requests),r=this.windowMs-(e-t);if(r>0)return await new Promise((n)=>setTimeout(n,r)),this.acquire()}this.requests.push(e)}canMakeRequest(){let e=Date.now();return this.requests=this.requests.filter((t)=>e-t<this.windowMs),this.requests.length<this.maxRequests}getRemainingRequests(){let e=Date.now();return this.requests=this.requests.filter((t)=>e-t<this.windowMs),Math.max(0,this.maxRequests-this.requests.length)}}var Pe=(e)=>({isSuccess:!0,isFailure:!1,value:e}),we=(e)=>({isSuccess:!1,isFailure:!0,error:e}),Er={map(e,t){if(e.isSuccess)return Pe(t(e.value));return e},flatMap(e,t){if(e.isSuccess)return t(e.value);return e},mapError(e,t){if(e.isFailure)return we(t(e.error));return e},unwrap(e){if(e.isSuccess)return e.value;throw e.error},unwrapOr(e,t){if(e.isSuccess)return e.value;return t},unwrapOrElse(e,t){if(e.isSuccess)return e.value;return t(e.error)},match(e,t){if(e.isSuccess)return t.ok(e.value);return t.fail(e.error)},async fromPromise(e){try{let t=await e;return Pe(t)}catch(t){return we(t)}},isOk(e){return e.isSuccess},isFail(e){return e.isFailure},tap(e,t){return t(e),e},tapOk(e,t){if(e.isSuccess)t(e.value);return e},tapErr(e,t){if(e.isFailure)t(e.error);return e},expect(e,t){if(e.isSuccess)return e.value;throw Error(t,{cause:e.error})}};function Rt(){let e=globalThis;return e.__K_MSG_ENV__??e.__ENV__??e.process?.env??{}}function Cr(e){let t=Rt()[e];if(typeof t==="string")return t;if(t===void 0)return;return String(t)}var St=["PENDING","SENT","DELIVERED","FAILED","CANCELLED","UNKNOWN"],bt=["DELIVERED","FAILED","CANCELLED","UNKNOWN"],Fe=["PENDING","SENT"],vt=new Set(St),Le=new Set(bt),Tt=new Set(Fe);function Sr(e){return vt.has(e)}function br(e){return Le.has(e)}function vr(e){return Le.has(e)}function Tr(e){return Tt.has(e)}function Ar(){return Fe}var At=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS","NSA","VOICE","FAX","RCS_SMS","RCS_LMS","RCS_MMS","RCS_TPL","RCS_ITPL","RCS_LTPL"],xt=new Set(At);function kr(e){return xt.has(e)}var Mr=["PENDING","SENT","FAILED"],kt="PENDING",Or=(e)=>{let t=typeof e==="string"?e.trim().toUpperCase():"";if(t==="PENDING"||t==="SENT"||t==="FAILED")return t;return kt};export{Z as BulkOperationHandler,Ke as CircuitBreaker,F as ErrorUtils,_ as FieldCryptoError,St as KMSG_DELIVERY_STATUSES,At as KMSG_MESSAGE_TYPES,Fe as KMSG_POLLABLE_STATUSES,bt as KMSG_TERMINAL_STATUSES,C as KMsgError,L as KMsgErrorCode,Mr as KNOWN_MESSAGE_STATUSES,ct as LogLevel,X as Logger,kt as QUEUED_MESSAGE_STATUS,_e as RateLimiter,Er as Result,w as RetryHandler,lt as assertCryptoEnvelopeV1,Ht as assertFieldCryptoConfig,Jt as createAesGcmFieldCryptoProvider,Dt as createAwsKmsKeyResolver,Ae as createDefaultMasker,Vt as createEnvKeyResolver,Oe as createLogger,Qt as createNoopFieldCryptoProvider,D as createRefreshableKeyResolver,Lt as createRollingKeyResolver,he as createStaticKeyResolver,qt as createVaultTransitKeyResolver,we as fail,K as getLogger,Ar as getPollableStatuses,Ee as getRolloutKnownKids,Rt as getRuntimeEnvSource,at as isCryptoEnvelope,Sr as isKMsgDeliveryStatus,kr as isKMsgMessageType,br as isKMsgTerminalStatus,Tr as isPollableDeliveryStatus,vr as isTerminalDeliveryStatus,tr as logger,rr as loggerMiddleware,qe as normalizeErrorRetryPolicy,Or as normalizeMessageStatus,dt as normalizePhoneForHash,Ot as normalizeProviderError,O as normalizeRetryAfterMs,Pe as ok,Mt as parseErrorRetryPolicyFromJson,Cr as readRuntimeEnv,z as redactLogText,rt as resolveFieldCryptoFailMode,nt as resolveFieldCryptoOpenFallback,Se as resolveFieldMode,H as selectActiveKidByRollout,er as setGlobalLogger,Xt as toCiphertextEnvelopeString,ze as validateErrorRetryPolicy,ot as validateFieldCryptoConfig};
3
3
 
4
- //# debugId=AF5973A70384F7AB64756E2164756E21
4
+ //# debugId=3F2F71B1DDBCCBB664756E2164756E21
5
5
  //# sourceMappingURL=index.mjs.map
package/dist/logger.d.ts CHANGED
@@ -31,6 +31,22 @@ export interface LoggerConfig {
31
31
  enableJson?: boolean;
32
32
  enableColors?: boolean;
33
33
  }
34
+ export declare function redactLogText(text: string): string;
35
+ /**
36
+ * @evidence docs/security/field-crypto-v1.md#logging-policy
37
+ * Masks sensitive context keys and scrubs the message, error text, and
38
+ * string context values with redactLogText before output.
39
+ * @evidenceReview docs/security/field-crypto-v1.md#logging-policy #2665a06
40
+ * Read formatMessage, isSensitiveContextKey, sanitizeContextValue,
41
+ * redactLogText, and redactCredentials, and ran logger.test.ts: phone
42
+ * numbers, key/value credentials under any key containing a credential
43
+ * word (compound, quoted, AWS-style, spaced API key and private key
44
+ * labels, property paths of any length, auth segments but not author,
45
+ * and in JSON escaped once, including pairs nested in another key's
46
+ * value), URL passwords, and context values under snake, kebab, or
47
+ * spaced credential keys stay out of messages, errors, and context in
48
+ * JSON and text modes, with key scans in linear time.
49
+ */
34
50
  export declare class Logger {
35
51
  private config;
36
52
  private context;
@@ -5,9 +5,13 @@ import type { BalanceQuery, BalanceResult, DeliveryStatusQuery, DeliveryStatusRe
5
5
  * Fetch implementation used for a single provider operation.
6
6
  *
7
7
  * Callers can inject a compatible implementation for runtime-specific
8
- * transports, tracing, or deterministic tests.
8
+ * transports, tracing, or deterministic tests. It is a call signature rather
9
+ * than `typeof globalThis.fetch`, so a plain async function qualifies in every
10
+ * runtime (Bun's `fetch` type also declares `preconnect`, which providers never
11
+ * call); the global `fetch` still satisfies it. The input avoids the DOM-only
12
+ * `RequestInfo` alias so Node-only type setups can compile the declaration.
9
13
  */
10
- export type ProviderFetch = typeof globalThis.fetch;
14
+ export type ProviderFetch = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
11
15
  /**
12
16
  * Per-operation transport context passed to provider calls.
13
17
  *
@@ -2,6 +2,7 @@
2
2
  * Circuit breaker pattern implementation
3
3
  */
4
4
  export interface CircuitBreakerOptions {
5
+ /** Consecutive failures that open the circuit. */
5
6
  failureThreshold: number;
6
7
  timeout: number;
7
8
  resetTimeout: number;
@@ -15,8 +16,10 @@ export declare class CircuitBreaker {
15
16
  private failureCount;
16
17
  private lastFailureTime;
17
18
  private nextAttemptTime;
19
+ private trial;
18
20
  constructor(options: CircuitBreakerOptions);
19
21
  execute<T>(operation: () => Promise<T>): Promise<T>;
22
+ private recordSuccess;
20
23
  private recordFailure;
21
24
  getState(): string;
22
25
  getFailureCount(): number;
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@k-msg/core",
3
- "version": "0.30.0",
4
- "packageManager": "bun@1.3.9",
3
+ "version": "0.31.0",
4
+ "packageManager": "bun@1.4.2",
5
5
  "description": "Core types and interfaces for K-Message platform",
6
6
  "type": "module",
7
- "main": "./dist/index.js",
7
+ "main": "./dist/index.cjs",
8
8
  "module": "./dist/index.mjs",
9
9
  "types": "./dist/index.d.ts",
10
10
  "sideEffects": false,
@@ -12,7 +12,7 @@
12
12
  ".": {
13
13
  "types": "./dist/index.d.ts",
14
14
  "import": "./dist/index.mjs",
15
- "require": "./dist/index.js"
15
+ "require": "./dist/index.cjs"
16
16
  }
17
17
  },
18
18
  "publishConfig": {
@@ -21,13 +21,11 @@
21
21
  "scripts": {
22
22
  "build": "bun run clean && bun run build:esm && bun run build:cjs && bun run build:types",
23
23
  "build:esm": "bun build ./src/index.ts --outdir ./dist --format esm --minify --sourcemap --entry-naming '[name].mjs' --external 'bun:test' --external 'zod'",
24
- "build:cjs": "bun build ./src/index.ts --outdir ./dist --format cjs --minify --sourcemap --entry-naming '[name].js' --external 'bun:test' --external 'zod'",
24
+ "build:cjs": "bun build ./src/index.ts --outdir ./dist --format cjs --minify --sourcemap --entry-naming '[name].cjs' --external 'bun:test' --external 'zod'",
25
25
  "build:types": "tsc",
26
26
  "dev": "tsc --watch",
27
27
  "test": "bun run test:unit",
28
- "test:unit": "bun test --testPathPattern='.*\\.test\\.(ts|js)$' --testTimeout=5000",
29
- "test:integration": "bun test --testPathPattern='.*\\.integration\\.(ts|js)$' --testTimeout=10000",
30
- "test:e2e": "bun test --testPathPattern='.*\\.e2e\\.(ts|js)$' --testTimeout=30000",
28
+ "test:unit": "bun test",
31
29
  "test:coverage": "bun test --coverage",
32
30
  "test:watch": "bun test --watch",
33
31
  "typecheck": "ttsc --noEmit",
@@ -40,12 +38,12 @@
40
38
  },
41
39
  "devDependencies": {
42
40
  "@types/bun": "^1.3.14",
43
- "ttsc": "^0.18.4",
41
+ "ttsc": "^0.30.4",
44
42
  "typescript": "^7.0.2"
45
43
  },
46
44
  "peerDependencies": {},
47
45
  "files": [
48
- "dist/**/*.js",
46
+ "dist/**/*.cjs",
49
47
  "dist/**/*.mjs",
50
48
  "dist/**/*.d.ts",
51
49
  "README.md"
package/dist/index.js DELETED
@@ -1,5 +0,0 @@
1
- var{defineProperty:V,getOwnPropertyNames:Gt,getOwnPropertyDescriptor:Jt}=Object,Wt=Object.prototype.hasOwnProperty;var yt=new WeakMap,Yt=(t)=>{var n=yt.get(t),i;if(n)return n;if(n=V({},"__esModule",{value:!0}),t&&typeof t==="object"||typeof t==="function")Gt(t).map((e)=>!Wt.call(n,e)&&V(n,e,{get:()=>t[e],enumerable:!(i=Jt(t,e))||i.enumerable}));return yt.set(t,n),n};var Vt=(t,n)=>{for(var i in n)V(t,i,{get:n[i],enumerable:!0,configurable:!0,set:(e)=>n[i]=()=>e})};var Wn={};Vt(Wn,{validateFieldCryptoConfig:()=>Rt,validateErrorRetryPolicy:()=>Ot,toCiphertextEnvelopeString:()=>Dn,setGlobalLogger:()=>kn,selectActiveKidByRollout:()=>$,resolveFieldMode:()=>z,readRuntimeEnv:()=>Mn,parseErrorRetryPolicyFromJson:()=>zt,ok:()=>st,normalizeRetryAfterMs:()=>k,normalizeProviderError:()=>en,normalizePhoneForHash:()=>Nt,normalizeMessageStatus:()=>Jn,normalizeErrorRetryPolicy:()=>bt,loggerMiddleware:()=>xn,logger:()=>En,isTerminalDeliveryStatus:()=>qn,isPollableDeliveryStatus:()=>Bn,isKMsgTerminalStatus:()=>Un,isKMsgMessageType:()=>mn,isKMsgDeliveryStatus:()=>In,isCryptoEnvelope:()=>wn,getRuntimeEnvSource:()=>Ut,getRolloutKnownKids:()=>Z,getPollableStatuses:()=>$n,getLogger:()=>R,fail:()=>ft,createVaultTransitKeyResolver:()=>Fn,createStaticKeyResolver:()=>v,createRollingKeyResolver:()=>dn,createRefreshableKeyResolver:()=>q,createNoopFieldCryptoProvider:()=>Pn,createLogger:()=>it,createEnvKeyResolver:()=>gn,createDefaultMasker:()=>tt,createAwsKmsKeyResolver:()=>on,createAesGcmFieldCryptoProvider:()=>An,assertFieldCryptoConfig:()=>Cn,RetryHandler:()=>M,Result:()=>Rn,RateLimiter:()=>pt,QUEUED_MESSAGE_STATUS:()=>mt,Logger:()=>W,LogLevel:()=>It,KNOWN_MESSAGE_STATUSES:()=>Gn,KMsgErrorCode:()=>N,KMsgError:()=>w,KMSG_TERMINAL_STATUSES:()=>Bt,KMSG_POLLABLE_STATUSES:()=>rt,KMSG_MESSAGE_TYPES:()=>Ht,KMSG_DELIVERY_STATUSES:()=>qt,FieldCryptoError:()=>U,ErrorUtils:()=>_,CircuitBreaker:()=>et,BulkOperationHandler:()=>Y});module.exports=Yt(Wn);var N;((o)=>{o.INVALID_REQUEST="INVALID_REQUEST";o.AUTHENTICATION_FAILED="AUTHENTICATION_FAILED";o.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE";o.TEMPLATE_NOT_FOUND="TEMPLATE_NOT_FOUND";o.RATE_LIMIT_EXCEEDED="RATE_LIMIT_EXCEEDED";o.NETWORK_ERROR="NETWORK_ERROR";o.NETWORK_TIMEOUT="NETWORK_TIMEOUT";o.NETWORK_SERVICE_UNAVAILABLE="NETWORK_SERVICE_UNAVAILABLE";o.REQUEST_ABORTED="REQUEST_ABORTED";o.PROVIDER_ERROR="PROVIDER_ERROR";o.MESSAGE_SEND_FAILED="MESSAGE_SEND_FAILED";o.CRYPTO_CONFIG_ERROR="CRYPTO_CONFIG_ERROR";o.CRYPTO_ENCRYPT_FAILED="CRYPTO_ENCRYPT_FAILED";o.CRYPTO_DECRYPT_FAILED="CRYPTO_DECRYPT_FAILED";o.CRYPTO_HASH_FAILED="CRYPTO_HASH_FAILED";o.CRYPTO_POLICY_VIOLATION="CRYPTO_POLICY_VIOLATION";o.UNKNOWN_ERROR="UNKNOWN_ERROR"})(N||={});var jt={["INVALID_REQUEST"]:{ko:"잘못된 요청입니다",en:"Invalid request"},["AUTHENTICATION_FAILED"]:{ko:"인증에 실패했습니다",en:"Authentication failed"},["INSUFFICIENT_BALANCE"]:{ko:"잔액이 부족합니다",en:"Insufficient balance"},["TEMPLATE_NOT_FOUND"]:{ko:"템플릿을 찾을 수 없습니다",en:"Template not found"},["RATE_LIMIT_EXCEEDED"]:{ko:"요청 한도를 초과했습니다",en:"Rate limit exceeded"},["NETWORK_ERROR"]:{ko:"네트워크 오류가 발생했습니다",en:"Network error"},["NETWORK_TIMEOUT"]:{ko:"네트워크 요청 시간이 초과되었습니다",en:"Network timeout"},["NETWORK_SERVICE_UNAVAILABLE"]:{ko:"서비스를 일시적으로 사용할 수 없습니다",en:"Service temporarily unavailable"},["REQUEST_ABORTED"]:{ko:"요청이 취소되었습니다",en:"Request aborted"},["PROVIDER_ERROR"]:{ko:"제공자 오류가 발생했습니다",en:"Provider error"},["MESSAGE_SEND_FAILED"]:{ko:"메시지 전송에 실패했습니다",en:"Message send failed"},["CRYPTO_CONFIG_ERROR"]:{ko:"암호화 설정 오류가 발생했습니다",en:"Crypto configuration error"},["CRYPTO_ENCRYPT_FAILED"]:{ko:"암호화에 실패했습니다",en:"Encryption failed"},["CRYPTO_DECRYPT_FAILED"]:{ko:"복호화에 실패했습니다",en:"Decryption failed"},["CRYPTO_HASH_FAILED"]:{ko:"해시 생성에 실패했습니다",en:"Hash generation failed"},["CRYPTO_POLICY_VIOLATION"]:{ko:"암호화 정책 위반이 발생했습니다",en:"Crypto policy violation"},["UNKNOWN_ERROR"]:{ko:"알 수 없는 오류가 발생했습니다",en:"Unknown error"}},Qt=new Set(Object.values(N)),ct=new Set(["NETWORK_ERROR","RATE_LIMIT_EXCEEDED","NETWORK_TIMEOUT","NETWORK_SERVICE_UNAVAILABLE","PROVIDER_ERROR","UNKNOWN_ERROR"]),ht=new Set(["INVALID_REQUEST","AUTHENTICATION_FAILED","INSUFFICIENT_BALANCE","TEMPLATE_NOT_FOUND","MESSAGE_SEND_FAILED","REQUEST_ABORTED","CRYPTO_CONFIG_ERROR","CRYPTO_ENCRYPT_FAILED","CRYPTO_DECRYPT_FAILED","CRYPTO_HASH_FAILED","CRYPTO_POLICY_VIOLATION"]),S=(t)=>{if(typeof t!=="number"||Number.isNaN(t)||!Number.isFinite(t))return;return Math.trunc(t)},k=(t)=>{let n=S(t);if(n===void 0||n<0)return;return n},Zt=(t)=>{if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0},j=(t)=>{return typeof t==="string"?t.toLowerCase().trim():void 0},T=(t,n="safe")=>{if(typeof t==="string"){let i=t.trim().toUpperCase();return i.length>0?i:void 0}if(n==="compat"&&(typeof t==="number"||typeof t==="boolean"))return String(t).toUpperCase();return},dt=(t,n)=>t?.some((i)=>T(i)===n)??!1,Xt=(t,n)=>{if(n.nonRetryableCodes?.includes(t))return"non_retryable";if(n.retryableCodes?.includes(t))return"retryable";return},ot=(t,n)=>{let i=T(t,"compat");if(!i)return;if(dt(n.nonRetryableStatuses,i))return"non_retryable";if(dt(n.retryableStatuses,i))return"retryable";return},O=(t)=>{return typeof t==="object"&&t!==null&&!Array.isArray(t)},x=(t,n)=>{for(let i of n)if(i in t)return t[i];return},Lt=(t)=>{return t.length>0?t:"$"},At=(t)=>{return t==="compat"?"compat":"safe"},at=(t)=>{if(t>=500)return"retryable";if(t===408||t===425||t===429)return"retryable";return"non_retryable"},gt=(t)=>{let n=t.toLowerCase();if(n.includes("timeout")||n.includes("temporar")||n.includes("network")||n.includes("retry"))return"retryable";return};class w extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(t,n,i,e={}){super(n);if(this.name="KMsgError",this.code=t,this.details=i,this.providerErrorCode=e.providerErrorCode,this.providerErrorText=e.providerErrorText,this.httpStatus=S(e.httpStatus),this.requestId=typeof e.requestId==="string"?e.requestId:void 0,this.retryAfterMs=S(e.retryAfterMs),this.attempt=S(e.attempt),Array.isArray(e.causeChain))this.causeChain=e.causeChain;else if(e.causeChain!==void 0)this.causeChain=[e.causeChain];let p=Error.captureStackTrace;if(p)p(this,w)}getLocalizedMessage(t="ko"){let n=jt[this.code];if(n?.[t])return n[t];return this.message}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details,providerErrorCode:this.providerErrorCode,providerErrorText:this.providerErrorText,httpStatus:this.httpStatus,requestId:this.requestId,retryAfterMs:this.retryAfterMs,attempt:this.attempt,causeChain:this.causeChain}}}var b=(t,n)=>{let i=S(t);if(i!==void 0)return i;if(n==="compat"&&typeof t==="string"){let e=Number(t.trim());if(Number.isFinite(e))return Math.trunc(e)}return},Q=(t,n)=>{let i=Zt(t);if(i)return i;if(n==="compat"&&(typeof t==="number"||typeof t==="boolean"))return String(t);return},Pt=(t)=>{if(typeof t!=="string")return;let n=t.trim().toUpperCase();if(!Qt.has(n))return;return n},A=(t,n)=>{t.push({...n,path:Lt(n.path)})},Dt=(t,n,i,e,p)=>{if(t===void 0)return[];let s=(()=>{if(Array.isArray(t))return t;if(i==="compat"&&typeof t==="string")return t.split(",").map((r)=>r.trim()).filter((r)=>r.length>0);return A(e,{code:"invalid_type",message:`expected array of ${p.label} values`,path:n}),[]})(),f=[],y=new Set;for(let r=0;r<s.length;r+=1){let c=s[r],h=p.normalize(c);if(!h){A(e,{code:p.label==="code"?"unknown_code":"invalid_status",message:`invalid retry policy ${p.label}: ${String(c)}`,path:`${n}[${r}]`});continue}if(y.has(h)){A(e,{code:p.label==="code"?"duplicate_code":"duplicate_status",message:`duplicate retry policy ${p.label}: ${h}`,path:`${n}[${r}]`});continue}y.add(h),f.push(h)}return f},Ft=(t,n,i,e)=>Dt(t,n,i,e,{label:"code",normalize:(p)=>Pt(T(p,i))}),Ct=(t,n,i,e)=>Dt(t,n,i,e,{label:"status",normalize:(p)=>T(p,i)}),Tt=(t,n,i,e)=>{if(t===void 0)return;let p=k(b(t,i));if(p!==void 0)return p;A(e,{code:"invalid_retry_after",message:`invalid retry delay: ${String(t)}`,path:n});return},Kt=(t,n,i,e)=>{if(t===void 0)return;if(!O(t)){A(e,{code:"invalid_type",message:"expected retry delay map",path:n});return}let p={},s=new Set;for(let[f,y]of Object.entries(t)){let r=T(f,"safe"),c=`${n}.${f}`;if(!r){A(e,{code:"invalid_key",message:"retry delay map key must not be empty",path:c});continue}if(s.has(r)){A(e,{code:"duplicate_key",message:`duplicate retry delay map key: ${r}`,path:c});continue}let h=Tt(y,c,i,e);if(h===void 0)continue;s.add(r),p[r]=h}return Object.keys(p).length>0?p:void 0},vt=(t,n,i)=>{if(t===void 0)return;if(typeof t==="function")return t;if(!O(t)){A(i,{code:"invalid_type",message:"expected retry delay resolver or policy object",path:"retryAfterMs"});return}let e=new Set(["defaultMs","byCode","byStatus"]);for(let y of Object.keys(t)){if(e.has(y))continue;A(i,{code:"unknown_field",message:`unknown retry-after policy field: ${y}`,path:`retryAfterMs.${y}`})}let p=Tt(t.defaultMs,"retryAfterMs.defaultMs",n,i),s=Kt(t.byCode,"retryAfterMs.byCode",n,i),f=Kt(t.byStatus,"retryAfterMs.byStatus",n,i);if(p===void 0&&s===void 0&&f===void 0)return;return{...p!==void 0?{defaultMs:p}:{},...s!==void 0?{byCode:s}:{},...f!==void 0?{byStatus:f}:{}}},ut=(t,n,i)=>{if(t===void 0)return;if(typeof t==="string"){let e=t.trim().toLowerCase();if(e==="retryable")return"retryable";if(e==="non_retryable"||e==="non-retryable")return"non_retryable"}if(n==="compat"&&typeof t==="boolean")return t?"retryable":"non_retryable";A(i,{code:"invalid_fallback",message:`invalid fallback value: ${String(t)}`,path:"fallback"});return};function Ot(t,n={}){let i=At(n.mode),e=[];if(!O(t))return A(e,{code:"invalid_root",message:"retry policy must be an object",path:"$"}),{policy:null,issues:e};let p=new Set(["retryableCodes","nonRetryableCodes","retryableStatuses","nonRetryableStatuses","fallback","retryAfterMs"]);for(let o of Object.keys(t)){if(p.has(o))continue;A(e,{code:"unknown_field",message:`unknown retry policy field: ${o}`,path:o})}let s=Ft(t.retryableCodes,"retryableCodes",i,e),f=Ft(t.nonRetryableCodes,"nonRetryableCodes",i,e),y=Ct(t.retryableStatuses,"retryableStatuses",i,e),r=Ct(t.nonRetryableStatuses,"nonRetryableStatuses",i,e),c=ut(t.fallback,i,e),h=vt(t.retryAfterMs,i,e),a=new Set(s),g=new Set(f);for(let o of a){if(!g.has(o))continue;a.delete(o),A(e,{code:"conflicting_code",message:`code '${o}' is both retryable and nonRetryable; nonRetryable wins`,path:"retryableCodes"})}let F=new Set(y),K=new Set(r);for(let o of F){if(!K.has(o))continue;F.delete(o),A(e,{code:"conflicting_status",message:`status '${o}' is both retryable and nonRetryable; nonRetryable wins`,path:"retryableStatuses"})}let l={...a.size>0?{retryableCodes:Array.from(a)}:{},...g.size>0?{nonRetryableCodes:Array.from(g)}:{},...F.size>0?{retryableStatuses:Array.from(F)}:{},...K.size>0?{nonRetryableStatuses:Array.from(K)}:{},...c?{fallback:c}:{},...h?{retryAfterMs:h}:{}};return{policy:l.retryableCodes!==void 0||l.nonRetryableCodes!==void 0||l.retryableStatuses!==void 0||l.nonRetryableStatuses!==void 0||l.fallback!==void 0||l.retryAfterMs!==void 0?l:null,issues:e}}function bt(t,n={}){return Ot(t,n).policy}function zt(t,n={}){if(typeof t!=="string"||t.trim().length===0)return null;try{let i=JSON.parse(t);return bt(i,n)}catch{return null}}var lt=(t,n)=>{let i=t.response;if(!O(i))return;return b(x(i,["status","statusCode","httpStatus"]),n)},tn=(t,n)=>{if(t instanceof w&&Array.isArray(t.causeChain))return t.causeChain.slice();if(O(t)){let s=t.causeChain;if(Array.isArray(s))return s.slice();let f=t.details;if(n==="compat"&&O(f)){let y=f.causeChain;if(Array.isArray(y))return y.slice();if(y!==void 0)return[y]}}let i=[],e=new Set,p=t;for(let s=0;s<8;s+=1){if(!O(p))break;let f=p.cause;if(f===void 0||e.has(f))break;e.add(f),i.push(f),p=f}return i.length>0?i:void 0},nn=(t)=>{if(t instanceof Error&&typeof t.message==="string")return t.message;if(O(t)&&typeof t.message==="string")return t.message;return typeof t==="string"?t:"Unknown error"},wt=(t,n)=>{let i=T(n,"compat");if(!t||!i)return;if(Object.prototype.hasOwnProperty.call(t,i))return k(t[i]);for(let[e,p]of Object.entries(t)){if(T(e)!==i)continue;return k(p)}return},St=(t,n)=>{let i=n?.retryAfterMs;if(typeof i==="function"){let y=k(i(t));if(y!==void 0)return{value:y,source:"policy"}}let e=k(t.retryAfterMs);if(e!==void 0)return{value:e,source:"input"};if(!i||typeof i==="function")return{};let p=[t.providerErrorCode,t.code];for(let y of p){let r=wt(i.byCode,y);if(r!==void 0)return{value:r,source:"policy"}}let s=wt(i.byStatus,t.httpStatus);if(s!==void 0)return{value:s,source:"policy"};let f=k(i.defaultMs);return f!==void 0?{value:f,source:"policy"}:{}};function en(t,n={}){let i=At(n.mode),p=n.defaultCode??"UNKNOWN_ERROR",s={code:"fallback",classification:n.policy?"policy":"fallback"},f,y,r,c,h,a,g,F=(d)=>{if(d.providerErrorCode!==void 0)f=d.providerErrorCode,s.providerErrorCode="metadata";if(d.providerErrorText!==void 0)y=d.providerErrorText,s.providerErrorText="metadata";if(d.httpStatus!==void 0)r=d.httpStatus,s.httpStatus="metadata";if(d.requestId!==void 0)c=d.requestId,s.requestId="metadata";if(d.retryAfterMs!==void 0)h=k(d.retryAfterMs),s.retryAfterMs="metadata";if(d.attempt!==void 0)a=b(d.attempt,i),s.attempt="metadata";if(Array.isArray(d.causeChain))g=d.causeChain.slice(),s.causeChain="metadata"},K=(d,D)=>{if(f===void 0){let C=Q(x(d,["providerErrorCode","errorCode","resultCode"]),i);if(C!==void 0)f=C,s.providerErrorCode=D}if(y===void 0){let C=Q(x(d,["providerErrorText","errorMessage","msg","message"]),i);if(C!==void 0)y=C,s.providerErrorText=D}if(r===void 0){let C=b(x(d,["httpStatus","statusCode","status"]),i)??lt(d,i);if(C!==void 0)r=C,s.httpStatus=D==="details"?"details":"http"}if(c===void 0){let C=Q(x(d,["requestId","request_id","reqId","traceId"]),i);if(C!==void 0)c=C,s.requestId=D}if(h===void 0){let C=k(b(x(d,["retryAfterMs","retry_after_ms","retryAfter"]),i));if(C!==void 0)h=C,s.retryAfterMs=D}if(a===void 0){let C=b(d.attempt,i);if(C!==void 0&&C>0)a=C,s.attempt=D}};if(t instanceof w){if(p=t.code,s.code="input",F(t),i==="compat"&&O(t.details))K(t.details,"details")}else if(O(t)){let d=Pt(x(t,["code","errorCode","resultCode"]));if(d!==void 0)p=d,s.code="input";else if(r===void 0){let D=b(x(t,["httpStatus","statusCode","status"]),i)??lt(t,i);if(D!==void 0&&D>=500)p="PROVIDER_ERROR",s.code="http"}if(K(t,"input"),i==="compat"&&O(t.details))K(t.details,"details")}if(g===void 0){let d=tn(t,i);if(d!==void 0)g=d,s.causeChain="input"}if(n.attempt!==void 0&&b(n.attempt,i)!==void 0){let d=b(n.attempt,i);if(d!==void 0&&d>0)a=d,s.attempt="input"}let l=new w(p,nn(t),void 0,{providerErrorCode:f,providerErrorText:y,httpStatus:r,requestId:c,retryAfterMs:h,attempt:a,causeChain:g}),P=St(l,n.policy);if(P.value!==void 0){if(h=P.value,P.source==="policy")s.retryAfterMs="policy"}let o=_.classifyForRetry(l,n.policy);return{code:p,classification:o,...f!==void 0?{providerErrorCode:f}:{},...y!==void 0?{providerErrorText:y}:{},...r!==void 0?{httpStatus:r}:{},...c!==void 0?{requestId:c}:{},...h!==void 0?{retryAfterMs:h}:{},...a!==void 0?{attempt:a}:{},...g!==void 0?{causeChain:g}:{},sources:s}}var _={isRetryable(t,n={}){return _.classifyForRetry(t,n)==="retryable"},classifyForRetry(t,n={}){if(t instanceof w){let r=Xt(t.code,n);if(r)return r;let c=ot(t.httpStatus,n);if(c)return c;if(new Set(n.retryableCodes??Array.from(ct)).has(t.code))return"retryable";if(new Set(n.nonRetryableCodes??Array.from(ht)).has(t.code))return"non_retryable";if(t.httpStatus!==void 0)return at(t.httpStatus);let g=gt(t.message);if(g)return g;if(n.classifyByMessage&&t.message){let F=n.classifyByMessage(t.message);if(F)return F}if(n.fallback)return n.fallback;return"non_retryable"}let i=t&&typeof t==="object"?t:void 0,e=T(i?.status,"compat")??T(i?.statusCode,"compat")??T(i?.httpStatus,"compat")??T(i?.code,"compat"),p=j(i?.status)??j(i?.statusCode)??j(i?.code),s=S(i?.status)??S(i?.statusCode)??S(i?.httpStatus),f=ot(e,n);if(f)return f;if(p?.startsWith("5"))return"retryable";if(s!==void 0){if(n.classifyByStatusCode)return n.classifyByStatusCode(s);return at(s)}let y=typeof i?.message==="string"?gt(i.message):void 0;if(y)return y;if(n.classifyByMessage&&typeof i?.message==="string"){let r=n.classifyByMessage(i.message);if(r)return r}return n.fallback??"non_retryable"},resolveRetryAfterMs(t,n){return St(t,n).value},isUnknownStatus:(t)=>{if(t===void 0||Number.isNaN(t)||!Number.isFinite(t))return!1;return t<500},toRetryMetadata(t){return{providerErrorCode:t.providerErrorCode,providerErrorText:t.providerErrorText,httpStatus:t.httpStatus,requestId:t.requestId,retryAfterMs:t.retryAfterMs,attempt:t.attempt,causeChain:t.causeChain}},withAttempt(t,n){return new w(t.code,t.message,t.details,{..._.toRetryMetadata(t),attempt:S(n)})},DEFAULT_RETRYABLE_ERROR_CODES:ct,DEFAULT_NON_RETRYABLE_ERROR_CODES:ht};function pn(t){switch(t){case"config":return"CRYPTO_CONFIG_ERROR";case"encrypt":return"CRYPTO_ENCRYPT_FAILED";case"decrypt":return"CRYPTO_DECRYPT_FAILED";case"hash":return"CRYPTO_HASH_FAILED";case"policy":return"CRYPTO_POLICY_VIOLATION"}}class U extends w{kind;fieldPath;failMode;openFallback;constructor(t,n,i,e={}){super(pn(t),n,i,e);this.name="FieldCryptoError",this.kind=t,this.fieldPath=typeof e.fieldPath==="string"?e.fieldPath:void 0,this.failMode=e.failMode,this.openFallback=e.openFallback}toJSON(){return{...super.toJSON(),kind:this.kind,fieldPath:this.fieldPath,failMode:this.failMode,openFallback:this.openFallback}}}var sn=["tenantId","providerId","messageId"];function B(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function fn(t){if(typeof t!=="number"||!Number.isFinite(t))return;if(t<=0||t>100)return;return t}function kt(t){let n=[];for(let i of t){let e=B(i.kid),p=fn(i.percentage);if(!e||p===void 0)continue;n.push({kid:e,percentage:p})}return n}function rn(t,n,i){let e=n.map((p)=>{let s=t[p];return typeof s==="string"?s:""}).join("|");return`${i}::${e}`}function yn(t){let n=2166136261;for(let i=0;i<t.length;i+=1)n^=t.charCodeAt(i),n=n*16777619>>>0;return n>>>0}function cn(t,n){let i=0;for(let e of t)if(i+=e.percentage,n<i)return e.kid;return}function $(t,n,i){let e=kt(n.buckets),p=B(n.defaultKid)??B(i);if(e.length===0)return p;let s=B(n.seed)??"kmsg-rollout-v1",f=n.stickyFields??sn,y=rn(t,f,s),r=yn(y)%100;return cn(e,r)??p}function Z(t){return kt(t.buckets).map((n)=>n.kid)}function I(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function X(t){if(!Array.isArray(t))return[];return t.map((n)=>I(n)).filter((n)=>Boolean(n))}function L(t){let n=[],i=new Set;for(let e of t){let p=I(e);if(!p||i.has(p))continue;i.add(p),n.push(p)}return n}function hn(t){return I(t.providerId)??"default"}function v(t){let n=I(t.activeKid)??"default",i=L([n,...X(t.decryptKids)]);return{async resolveEncryptKey(){return{kid:n}},async resolveDecryptKeys(){return i}}}function q(t){let n=typeof t.cacheTtlMs==="number"&&t.cacheTtlMs>=0?Math.trunc(t.cacheTtlMs):30000,i=I(t.fallback?.activeKid),e=X(t.fallback?.decryptKids),p;async function s(f){let y=Date.now();if(p&&y<p.expiresAt)return p.value;let r=await t.provider.loadKeySet(f),c=I(r.activeKid)??i??hn(f),h=L([c,...X(r.decryptKids),...e]),a={activeKid:c,decryptKids:h,refreshedAt:Date.now()};return p={value:a,expiresAt:Date.now()+n},a}return{async resolveEncryptKey(f){return{kid:(await s(f)).activeKid}},async resolveDecryptKeys(f){let y=await s(f);return y.decryptKids??[y.activeKid]}}}function dn(t,n){return{async resolveEncryptKey(i){let e=await t.resolveEncryptKey(i);return{kid:$(i,n,e.kid)??e.kid}},async resolveDecryptKeys(i){let e=await t.resolveEncryptKey(i),p=t.resolveDecryptKeys?await t.resolveDecryptKeys(i):[e.kid],s=$(i,n,e.kid),f=Z(n);return L([...s?[s]:[],e.kid,...p??[],...f])}}}function on(t){return q({provider:{async loadKeySet(i){return t.client.getKeyState({...i,...t.keyAlias?{keyAlias:t.keyAlias}:{},...t.region?{region:t.region}:{}})}},cacheTtlMs:t.cacheTtlMs,fallback:{activeKid:t.fallbackActiveKid,decryptKids:t.fallbackDecryptKids}})}function H(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function Et(t,n){return H(t[n])}function an(t,n){if(!t)return[];return t.split(n).map((i)=>H(i)).filter((i)=>Boolean(i))}function gn(t={}){let n=globalThis.process?.env,i=t.env??n??{},e=H(t.delimiter)??",",p=t.activeKidEnv??"KMSG_ACTIVE_KID",s=t.decryptKidsEnv??"KMSG_DECRYPT_KIDS",f=Et(i,p)??H(t.fallbackActiveKid)??"default",y=[f,...an(Et(i,s),e),...t.fallbackDecryptKids??[]];return v({activeKid:f,decryptKids:y})}function Fn(t){return q({provider:{async loadKeySet(i){return t.client.getKeyState({...i,...t.mountPath?{mountPath:t.mountPath}:{},...t.keyName?{keyName:t.keyName}:{},...t.namespace?{namespace:t.namespace}:{}})}},cacheTtlMs:t.cacheTtlMs,fallback:{activeKid:t.fallbackActiveKid,decryptKids:t.fallbackDecryptKids}})}function u(t){return typeof t==="function"}function xt(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function z(t,n,i){let e=t.fields[n];if(e)return e;if(n.startsWith("metadata.")){let p=t.fields["metadata.*"];if(p)return p}return i}function Rt(t,n={}){let i=[];if(!t||typeof t!=="object")return{valid:!1,issues:[{message:"fieldCrypto config must be an object",rule:"fieldCrypto.config.object",hint:"Provide a valid FieldCryptoConfig object"}]};if(!t.provider||typeof t.provider!=="object")i.push({message:"fieldCrypto provider is required",rule:"fieldCrypto.provider.required",path:"provider",hint:"Set provider with encrypt/decrypt/hash methods"});else{if(!u(t.provider.encrypt))i.push({message:"provider.encrypt must be a function",rule:"fieldCrypto.provider.encrypt.required",path:"provider.encrypt"});if(!u(t.provider.decrypt))i.push({message:"provider.decrypt must be a function",rule:"fieldCrypto.provider.decrypt.required",path:"provider.decrypt"});if(!u(t.provider.hash))i.push({message:"provider.hash must be a function",rule:"fieldCrypto.provider.hash.required",path:"provider.hash"})}if(!t.fields||typeof t.fields!=="object")i.push({message:"fieldCrypto.fields must be an object",rule:"fieldCrypto.fields.object",path:"fields",hint:"Define policies such as to, from, metadata.phoneNumber"});else{let s=Object.entries(t.fields);if(s.length===0)i.push({message:"fieldCrypto.fields must not be empty",rule:"fieldCrypto.fields.non_empty",path:"fields",hint:"Add at least one field mode mapping"});for(let[f,y]of s){if(!xt(f))i.push({message:"field path must be a non-empty string",rule:"fieldCrypto.fields.path.non_empty",path:"fields"});if(y!=="plain"&&y!=="encrypt"&&y!=="encrypt+hash"&&y!=="mask")i.push({message:`unsupported field mode: ${String(y)}`,rule:"fieldCrypto.fields.mode.supported",path:`fields.${f}`})}}let e=t.failMode??"closed",p=t.openFallback??"masked";if(e==="open"&&p==="plaintext"&&t.unsafeAllowPlaintextStorage!==!0)i.push({message:"openFallback=plaintext requires unsafeAllowPlaintextStorage=true",rule:"fieldCrypto.fail_open.plaintext_guard",path:"openFallback",hint:"Use masked/null fallback, or explicitly enable unsafe plaintext"});if(Array.isArray(t.aadFields)){if(t.aadFields.length===0)i.push({message:"aadFields must not be empty when provided",rule:"fieldCrypto.aad_fields.non_empty",path:"aadFields"});for(let s=0;s<t.aadFields.length;s+=1){let f=t.aadFields[s];if(!xt(f))i.push({message:"aadFields cannot include empty key",rule:"fieldCrypto.aad_fields.no_empty_key",path:`aadFields[${s}]`})}}if(n.secureMode&&!n.compatPlainColumns){let s=z(t,"to","encrypt+hash"),f=z(t,"from","encrypt+hash");if(s==="plain")i.push({message:"secure mode requires non-plain policy for `to` when compatPlainColumns=false",rule:"fieldCrypto.secure_mode.to_non_plain",path:"fields.to",hint:"Use encrypt+hash for lookup fields"});if(f==="plain")i.push({message:"secure mode requires non-plain policy for `from` when compatPlainColumns=false",rule:"fieldCrypto.secure_mode.from_non_plain",path:"fields.from",hint:"Use encrypt+hash for lookup fields"})}return{valid:i.length===0,issues:i}}function Cn(t,n={}){let i=Rt(t,n);if(i.valid)return;let e=i.issues[0];if(!e)throw new U("config","fieldCrypto config validation failed",{rule:"fieldCrypto.config.invalid",issues:i.issues});throw new U("config",e.message,{rule:e.rule,path:e.path,hint:e.hint,issues:i.issues},{fieldPath:e.path})}function m(t){let n=t instanceof Uint8Array?t:new Uint8Array(t),i=typeof globalThis<"u"?globalThis.Buffer:void 0;return(i?i.from(n).toString("base64"):btoa(String.fromCharCode(...n))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function G(t){let n=t.replace(/-/g,"+").replace(/_/g,"/"),i=n.length%4===0?n:`${n}${"=".repeat(4-n.length%4)}`,e=typeof globalThis<"u"?globalThis.Buffer:void 0;if(e)return new Uint8Array(e.from(i,"base64"));let p=atob(i),s=new Uint8Array(p.length);for(let f=0;f<p.length;f+=1)s[f]=p.charCodeAt(f);return s}function Mt(t,n){if(t instanceof Uint8Array)return t;if(t instanceof ArrayBuffer)return new Uint8Array(t);if(n==="base64url")return G(t);return new TextEncoder().encode(t)}function Kn(t){let n=t instanceof Uint8Array?t:new Uint8Array(t);return Array.from(n).map((i)=>i.toString(16).padStart(2,"0")).join("")}function E(t){let n=new Uint8Array(t.byteLength);return n.set(t),n.buffer}function _t(t){let n=JSON.parse(t);if(!n||typeof n!=="object"||typeof n.v!=="number"||typeof n.alg!=="string"||typeof n.kid!=="string"||typeof n.iv!=="string"||typeof n.tag!=="string"||typeof n.ct!=="string")throw Error("Invalid ciphertext envelope");return n}function ln(t){if(typeof t==="string")return t;return JSON.stringify(t)}function wn(t){if(!t||typeof t!=="object")return!1;let n=t;return typeof n.v==="number"&&typeof n.alg==="string"&&typeof n.kid==="string"&&typeof n.iv==="string"&&typeof n.tag==="string"&&typeof n.ct==="string"}function Nt(t){let n=String(t??"").trim();if(n.length===0)return"";let i=n.startsWith("+"),e=n.replace(/\D/g,"");return i?`+${e}`:e}function tt(t=3,n=2){return(i)=>{let e=String(i??"");if(e.length<=t+n)return"*".repeat(Math.max(0,e.length));let p=e.slice(0,t),s=e.slice(-n);return`${p}${"*".repeat(e.length-t-n)}${s}`}}function An(t){let n=t.algorithm??"A256GCM",i=t.keyEncoding??"base64url",e=t.hashKeyEncoding??i,p=new Map,s=new Map,f=(r)=>{let c=p.get(r);if(c)return c;let h=t.keys[r];if(!h)throw Error(`Unknown encryption key id: ${r}`);let a=Mt(h,i),g=crypto.subtle.importKey("raw",E(a),"AES-GCM",!1,["encrypt","decrypt"]);return p.set(r,g),g},y=(r)=>{let c=s.get(r);if(c)return c;let h=t.hashKeys?.[r]??t.keys[r];if(!h)throw Error(`Unknown hash key id: ${r}`);let a=Mt(h,e),g=crypto.subtle.importKey("raw",E(a),{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return s.set(r,g),g};return{async encrypt(r){let c=r.kid??t.activeKid,h=await f(c),a=crypto.getRandomValues(new Uint8Array(12)),g=new TextEncoder().encode(JSON.stringify(r.aad??{})),F=new TextEncoder().encode(r.value),K=await crypto.subtle.encrypt({name:"AES-GCM",iv:E(a),additionalData:E(g),tagLength:128},h,E(F)),l=new Uint8Array(K),P=l.slice(l.length-16),o=l.slice(0,l.length-16);return{ciphertext:{v:1,alg:n,kid:c,iv:m(a),tag:m(P),ct:m(o)},kid:c}},async decrypt(r){let c=_t(r.ciphertext),h=r.candidateKids&&r.candidateKids.length>0?r.candidateKids:[c.kid],a=G(c.iv),g=G(c.tag),F=G(c.ct),K=new Uint8Array(F.length+g.length);K.set(F,0),K.set(g,F.length);let l=new TextEncoder().encode(JSON.stringify(r.aad??{})),P;for(let o of h)try{let d=await f(o),D=await crypto.subtle.decrypt({name:"AES-GCM",iv:E(a),additionalData:E(l),tagLength:128},d,E(K));return new TextDecoder().decode(new Uint8Array(D))}catch(d){P=d}throw Error(`Failed to decrypt ciphertext: ${P instanceof Error?P.message:String(P??"unknown")}`)},async hash(r){let c=r.kid??t.activeKid,h=await y(c),a=await crypto.subtle.sign("HMAC",h,E(new TextEncoder().encode(r.value)));return Kn(a)},mask(r){return tt()(r.value)}}}function Pn(){return{encrypt(t){return{ciphertext:JSON.stringify({v:1,alg:"NOOP",kid:"noop",iv:"",tag:"",ct:t.value})}},decrypt(t){try{return _t(t.ciphertext).ct}catch{return t.ciphertext}},hash(t){let n=Nt(t.value);return m(new TextEncoder().encode(n))},mask(t){return tt()(t.value)}}}function Dn(t){return ln(t)}var It;((p)=>{p.DEBUG="DEBUG";p.INFO="INFO";p.WARN="WARN";p.ERROR="ERROR"})(It||={});var Tn=["to","from","phone","phoneNumber","recipient","sender","secret","apiKey","apiSecret","authorization","auth","token","password","payload","message","content","text"];function On(t){let n=t.toLowerCase();return Tn.some((i)=>n.includes(i.toLowerCase()))}function bn(t){let n=t.trim();if(n.length<=4)return"***";if(n.includes("@")){let[p,s]=n.split("@");return`${p.slice(0,2)}${"*".repeat(Math.max(1,p.length-2))}@${s}`}let i=n.slice(0,3),e=n.slice(-2);return`${i}${"*".repeat(Math.max(1,n.length-5))}${e}`}function nt(t,n){if(n===void 0||n===null)return n;if(On(t)){if(typeof n==="string")return bn(n);if(typeof n==="number"||typeof n==="boolean")return"***";if(Array.isArray(n))return"[REDACTED]";if(typeof n==="object")return"[REDACTED]"}if(Array.isArray(n))return n.map((i)=>nt(t,i));if(typeof n==="object"){let i={};for(let[e,p]of Object.entries(n))i[e]=nt(e,p);return i}return n}function Sn(t){let n={};for(let[i,e]of Object.entries(t))n[i]=nt(i,e);return n}class W{config;context;constructor(t={},n={}){this.context=t,this.config={level:"INFO",enableConsole:!0,enableJson:!1,enableColors:!0,...n}}shouldLog(t){let n=["DEBUG","INFO","WARN","ERROR"];return n.indexOf(t)>=n.indexOf(this.config.level)}formatMessage(t){let n=Sn(t.context);if(this.config.enableJson)return JSON.stringify({level:t.level,message:t.message,timestamp:t.timestamp.toISOString(),context:n,...t.error&&{error:{name:t.error.name,message:t.error.message,stack:t.error.stack}},...t.duration&&{duration:t.duration}});let i=t.timestamp.toISOString(),e=this.config.enableColors?this.colorizeLevel(t.level):t.level,p=Object.keys(n).length>0?` [${Object.entries(n).map(([f,y])=>`${f}=${y}`).join(", ")}]`:"",s=`${i} ${e}${p}: ${t.message}`;if(t.duration!==void 0)s+=` (${t.duration}ms)`;if(t.error)s+=`
2
- ${t.error.stack}`;return s}colorizeLevel(t){if(!this.config.enableColors)return t;return`${{["DEBUG"]:"\x1B[36m",["INFO"]:"\x1B[32m",["WARN"]:"\x1B[33m",["ERROR"]:"\x1B[31m"}[t]}${t}\x1B[0m`}writeLog(t){if(!this.shouldLog(t.level))return;let n=this.formatMessage(t);if(this.config.enableConsole)(t.level==="ERROR"?console.error:t.level==="WARN"?console.warn:console.log)(n);if(this.config.enableFile&&this.config.filePath);}debug(t,n={}){this.writeLog({level:"DEBUG",message:t,timestamp:new Date,context:{...this.context,...n}})}info(t,n={}){this.writeLog({level:"INFO",message:t,timestamp:new Date,context:{...this.context,...n}})}warn(t,n={},i){this.writeLog({level:"WARN",message:t,timestamp:new Date,context:{...this.context,...n},error:i})}error(t,n={},i){this.writeLog({level:"ERROR",message:t,timestamp:new Date,context:{...this.context,...n},error:i})}child(t){return new W({...this.context,...t},this.config)}time(t){let n=Date.now();return()=>{let i=Date.now()-n;this.info(`${t} completed`,{duration:i})}}async measure(t,n,i={}){let e=Date.now(),p={...i,operation:t};this.debug(`Starting ${t}`,p);try{let s=await n(),f=Date.now()-e;return this.info(`Completed ${t}`,{...p,duration:f}),s}catch(s){let f=Date.now()-e;throw this.error(`Failed ${t}`,{...p,duration:f},s instanceof Error?s:Error(String(s))),s}}}var J;function it(t,n){return new W(t,n)}function R(){if(!J)J=it();return J}function kn(t){J=t}var En={debug:(t,n)=>R().debug(t,n),info:(t,n)=>R().info(t,n),warn:(t,n,i)=>R().warn(t,n,i),error:(t,n,i)=>R().error(t,n,i),child:(t)=>R().child(t),time:(t)=>R().time(t),measure:(t,n,i)=>R().measure(t,n,i)};function xn(t){let n=it({},t);return async(i,e)=>{let p=Date.now(),f={requestId:Math.random().toString(36).substring(7),method:i.req.method,path:i.req.path,userAgent:i.req.header("user-agent")||"unknown"};n.info("Request started",f);try{await e();let y=Date.now()-p;n.info("Request completed",{...f,status:i.res.status,duration:y})}catch(y){let r=Date.now()-p;throw n.error("Request failed",{...f,duration:r},y instanceof Error?y:Error(String(y))),y}}}class M{static defaultOptions={maxAttempts:3,initialDelay:1000,maxDelay:30000,backoffMultiplier:2,jitter:!0,retryCondition:(t)=>_.isRetryable(t)};static async execute(t,n={}){let i={...M.defaultOptions,...n},e,p=i.initialDelay;for(let s=1;s<=i.maxAttempts;s++)try{return await t()}catch(f){if(e=f,s===i.maxAttempts||!i.retryCondition(e,s))throw e;let y=i.jitter?p+Math.random()*p*0.1:p;i.onRetry?.(e,s),await new Promise((r)=>setTimeout(r,y)),p=Math.min(p*i.backoffMultiplier,i.maxDelay)}throw e}static createRetryableFunction(t,n={}){return async(...i)=>{return M.execute(()=>t(...i),n)}}}class Y{static async execute(t,n,i={}){let e={concurrency:5,retryOptions:{maxAttempts:3,initialDelay:1000,maxDelay:1e4,backoffMultiplier:2,jitter:!0},failFast:!1,...i},p=Date.now(),s=[],f=[],y=0,r=M.createRetryableFunction(n,e.retryOptions),c=Y.createBatches(t,e.concurrency);for(let a of c){let g=a.map(async(F)=>{try{let K=await r(F);s.push({item:F,result:K})}catch(K){if(f.push({item:F,error:K}),e.failFast)throw new w("MESSAGE_SEND_FAILED",`Bulk operation failed fast after ${f.length} failures`,{totalItems:t.length,failedCount:f.length})}finally{y++,e.onProgress?.(y,t.length,f.length)}});if(await Promise.allSettled(g),e.failFast&&f.length>0)break}let h=Date.now()-p;return{successful:s,failed:f,summary:{total:t.length,successful:s.length,failed:f.length,duration:h}}}static createBatches(t,n){let i=[];for(let e=0;e<t.length;e+=n)i.push(t.slice(e,e+n));return i}}class et{options;state="CLOSED";failureCount=0;lastFailureTime=0;nextAttemptTime=0;constructor(t){this.options=t}async execute(t){let n=Date.now();switch(this.state){case"OPEN":if(n<this.nextAttemptTime)throw new w("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 i=await Promise.race([t(),new Promise((e,p)=>setTimeout(()=>p(new w("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 i}catch(i){throw this.recordFailure(),i}}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 pt{maxRequests;windowMs;requests=[];constructor(t,n){this.maxRequests=t;this.windowMs=n}async acquire(){let t=Date.now();if(this.requests=this.requests.filter((n)=>t-n<this.windowMs),this.requests.length>=this.maxRequests){let n=Math.min(...this.requests),i=this.windowMs-(t-n);if(i>0)return await new Promise((e)=>setTimeout(e,i)),this.acquire()}this.requests.push(t)}canMakeRequest(){let t=Date.now();return this.requests=this.requests.filter((n)=>t-n<this.windowMs),this.requests.length<this.maxRequests}getRemainingRequests(){let t=Date.now();return this.requests=this.requests.filter((n)=>t-n<this.windowMs),Math.max(0,this.maxRequests-this.requests.length)}}var st=(t)=>({isSuccess:!0,isFailure:!1,value:t}),ft=(t)=>({isSuccess:!1,isFailure:!0,error:t}),Rn={map(t,n){if(t.isSuccess)return st(n(t.value));return t},flatMap(t,n){if(t.isSuccess)return n(t.value);return t},mapError(t,n){if(t.isFailure)return ft(n(t.error));return t},unwrap(t){if(t.isSuccess)return t.value;throw t.error},unwrapOr(t,n){if(t.isSuccess)return t.value;return n},unwrapOrElse(t,n){if(t.isSuccess)return t.value;return n(t.error)},match(t,n){if(t.isSuccess)return n.ok(t.value);return n.fail(t.error)},async fromPromise(t){try{let n=await t;return st(n)}catch(n){return ft(n)}},isOk(t){return t.isSuccess},isFail(t){return t.isFailure},tap(t,n){return n(t),t},tapOk(t,n){if(t.isSuccess)n(t.value);return t},tapErr(t,n){if(t.isFailure)n(t.error);return t},expect(t,n){if(t.isSuccess)return t.value;throw Error(n,{cause:t.error})}};function Ut(){let t=globalThis;return t.__K_MSG_ENV__??t.__ENV__??t.process?.env??{}}function Mn(t){let n=Ut()[t];if(typeof n==="string")return n;if(n===void 0)return;return String(n)}var qt=["PENDING","SENT","DELIVERED","FAILED","CANCELLED","UNKNOWN"],Bt=["DELIVERED","FAILED","CANCELLED","UNKNOWN"],rt=["PENDING","SENT"],_n=new Set(qt),$t=new Set(Bt),Nn=new Set(rt);function In(t){return _n.has(t)}function Un(t){return $t.has(t)}function qn(t){return $t.has(t)}function Bn(t){return Nn.has(t)}function $n(){return rt}var Ht=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS","NSA","VOICE","FAX","RCS_SMS","RCS_LMS","RCS_MMS","RCS_TPL","RCS_ITPL","RCS_LTPL"],Hn=new Set(Ht);function mn(t){return Hn.has(t)}var Gn=["PENDING","SENT","FAILED"],mt="PENDING",Jn=(t)=>{let n=typeof t==="string"?t.trim().toUpperCase():"";if(n==="PENDING"||n==="SENT"||n==="FAILED")return n;return mt};
3
-
4
- //# debugId=191B06DF7D93335864756E2164756E21
5
- //# sourceMappingURL=index.js.map