@k-msg/core 0.29.9 → 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.
- package/README.md +37 -0
- package/dist/crypto/policy.d.ts +22 -1
- package/dist/crypto/types.d.ts +65 -0
- package/dist/errors.d.ts +15 -2
- package/dist/index.cjs +5 -0
- package/dist/index.mjs +3 -3
- package/dist/logger.d.ts +16 -0
- package/dist/provider.d.ts +36 -2
- package/dist/resilience/circuit-breaker.d.ts +3 -0
- package/package.json +8 -10
- package/dist/index.js +0 -5
package/README.md
CHANGED
|
@@ -22,6 +22,43 @@ npm install @k-msg/core
|
|
|
22
22
|
bun add @k-msg/core
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
## Retry policy from JSON
|
|
26
|
+
|
|
27
|
+
Use the core parser for environment-backed provider policies instead of
|
|
28
|
+
reimplementing status and retry-delay normalization in each application:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import {
|
|
32
|
+
normalizeProviderError,
|
|
33
|
+
parseErrorRetryPolicyFromJson,
|
|
34
|
+
} from "@k-msg/core";
|
|
35
|
+
|
|
36
|
+
const policy = parseErrorRetryPolicyFromJson(
|
|
37
|
+
JSON.stringify({
|
|
38
|
+
retryableCodes: ["NETWORK_TIMEOUT"],
|
|
39
|
+
nonRetryableStatuses: ["400"],
|
|
40
|
+
retryableStatuses: ["429", "503"],
|
|
41
|
+
retryAfterMs: {
|
|
42
|
+
defaultMs: 1_000,
|
|
43
|
+
byCode: { VENDOR_BUSY: 2_000 },
|
|
44
|
+
byStatus: { "429": 3_000 },
|
|
45
|
+
},
|
|
46
|
+
}),
|
|
47
|
+
{ mode: "compat" },
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const normalized = normalizeProviderError(providerError, {
|
|
51
|
+
mode: "compat",
|
|
52
|
+
policy: policy ?? undefined,
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Policy keys are trimmed and normalized case-insensitively. In conflicts,
|
|
57
|
+
explicit non-retryable entries win. Declarative retry delays resolve in this
|
|
58
|
+
order: direct error metadata, provider error code, canonical `KMsgErrorCode`,
|
|
59
|
+
HTTP status, then `defaultMs`. Existing function-based `retryAfterMs(error)`
|
|
60
|
+
resolvers remain supported as overrides.
|
|
61
|
+
|
|
25
62
|
## Example: Implement a Provider
|
|
26
63
|
|
|
27
64
|
```ts
|
package/dist/crypto/policy.d.ts
CHANGED
|
@@ -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;
|
package/dist/crypto/types.d.ts
CHANGED
|
@@ -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/errors.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare enum KMsgErrorCode {
|
|
|
8
8
|
NETWORK_ERROR = "NETWORK_ERROR",
|
|
9
9
|
NETWORK_TIMEOUT = "NETWORK_TIMEOUT",
|
|
10
10
|
NETWORK_SERVICE_UNAVAILABLE = "NETWORK_SERVICE_UNAVAILABLE",
|
|
11
|
+
REQUEST_ABORTED = "REQUEST_ABORTED",
|
|
11
12
|
PROVIDER_ERROR = "PROVIDER_ERROR",
|
|
12
13
|
MESSAGE_SEND_FAILED = "MESSAGE_SEND_FAILED",
|
|
13
14
|
CRYPTO_CONFIG_ERROR = "CRYPTO_CONFIG_ERROR",
|
|
@@ -19,6 +20,14 @@ export declare enum KMsgErrorCode {
|
|
|
19
20
|
}
|
|
20
21
|
export type RetryPolicyErrorCode = KMsgErrorCode;
|
|
21
22
|
export type ProviderRetryHint = "retryable" | "non_retryable";
|
|
23
|
+
export interface RetryAfterPolicy {
|
|
24
|
+
/** Fallback delay when no code or status mapping matches. */
|
|
25
|
+
defaultMs?: number;
|
|
26
|
+
/** Delays keyed by provider error code or canonical KMsgErrorCode. */
|
|
27
|
+
byCode?: Readonly<Record<string, number>>;
|
|
28
|
+
/** Delays keyed by normalized HTTP status. */
|
|
29
|
+
byStatus?: Readonly<Record<string, number>>;
|
|
30
|
+
}
|
|
22
31
|
export interface KMsgErrorMetadata {
|
|
23
32
|
providerErrorCode?: string;
|
|
24
33
|
providerErrorText?: string;
|
|
@@ -31,6 +40,10 @@ export interface KMsgErrorMetadata {
|
|
|
31
40
|
export interface ErrorRetryPolicy {
|
|
32
41
|
retryableCodes?: readonly KMsgErrorCode[];
|
|
33
42
|
nonRetryableCodes?: readonly KMsgErrorCode[];
|
|
43
|
+
/** Explicit retryable HTTP statuses, normalized case-insensitively. */
|
|
44
|
+
retryableStatuses?: readonly string[];
|
|
45
|
+
/** Explicit non-retryable HTTP statuses; wins on conflicts. */
|
|
46
|
+
nonRetryableStatuses?: readonly string[];
|
|
34
47
|
classifyByStatusCode?: (status: number) => ProviderRetryHint;
|
|
35
48
|
classifyByMessage?: (message: string) => ProviderRetryHint | undefined;
|
|
36
49
|
/**
|
|
@@ -38,9 +51,9 @@ export interface ErrorRetryPolicy {
|
|
|
38
51
|
*/
|
|
39
52
|
fallback?: ProviderRetryHint;
|
|
40
53
|
/**
|
|
41
|
-
* Optional custom retry delay
|
|
54
|
+
* Optional custom retry delay resolver or declarative mapping.
|
|
42
55
|
*/
|
|
43
|
-
retryAfterMs?: (error: KMsgError) => number | undefined;
|
|
56
|
+
retryAfterMs?: RetryAfterPolicy | ((error: KMsgError) => number | undefined);
|
|
44
57
|
}
|
|
45
58
|
export type ErrorRetryPolicyMode = "safe" | "compat";
|
|
46
59
|
export interface ErrorRetryPolicyIssue {
|
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 E;((l)=>{l.INVALID_REQUEST="INVALID_REQUEST";l.AUTHENTICATION_FAILED="AUTHENTICATION_FAILED";l.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE";l.TEMPLATE_NOT_FOUND="TEMPLATE_NOT_FOUND";l.RATE_LIMIT_EXCEEDED="RATE_LIMIT_EXCEEDED";l.NETWORK_ERROR="NETWORK_ERROR";l.NETWORK_TIMEOUT="NETWORK_TIMEOUT";l.NETWORK_SERVICE_UNAVAILABLE="NETWORK_SERVICE_UNAVAILABLE";l.PROVIDER_ERROR="PROVIDER_ERROR";l.MESSAGE_SEND_FAILED="MESSAGE_SEND_FAILED";l.CRYPTO_CONFIG_ERROR="CRYPTO_CONFIG_ERROR";l.CRYPTO_ENCRYPT_FAILED="CRYPTO_ENCRYPT_FAILED";l.CRYPTO_DECRYPT_FAILED="CRYPTO_DECRYPT_FAILED";l.CRYPTO_HASH_FAILED="CRYPTO_HASH_FAILED";l.CRYPTO_POLICY_VIOLATION="CRYPTO_POLICY_VIOLATION";l.UNKNOWN_ERROR="UNKNOWN_ERROR"})(E||={});var At={["INVALID_REQUEST"]:{ko:"잘못된 요청입니다",en:"Invalid request"},["AUTHENTICATION_FAILED"]:{ko:"인증에 실패했습니다",en:"Authentication failed"},["INSUFFICIENT_BALANCE"]:{ko:"잔액이 부족합니다",en:"Insufficient balance"},["TEMPLATE_NOT_FOUND"]:{ko:"템플릿을 찾을 수 없습니다",en:"Template not found"},["RATE_LIMIT_EXCEEDED"]:{ko:"요청 한도를 초과했습니다",en:"Rate limit exceeded"},["NETWORK_ERROR"]:{ko:"네트워크 오류가 발생했습니다",en:"Network error"},["NETWORK_TIMEOUT"]:{ko:"네트워크 요청 시간이 초과되었습니다",en:"Network timeout"},["NETWORK_SERVICE_UNAVAILABLE"]:{ko:"서비스를 일시적으로 사용할 수 없습니다",en:"Service temporarily unavailable"},["PROVIDER_ERROR"]:{ko:"제공자 오류가 발생했습니다",en:"Provider error"},["MESSAGE_SEND_FAILED"]:{ko:"메시지 전송에 실패했습니다",en:"Message send failed"},["CRYPTO_CONFIG_ERROR"]:{ko:"암호화 설정 오류가 발생했습니다",en:"Crypto configuration error"},["CRYPTO_ENCRYPT_FAILED"]:{ko:"암호화에 실패했습니다",en:"Encryption failed"},["CRYPTO_DECRYPT_FAILED"]:{ko:"복호화에 실패했습니다",en:"Decryption failed"},["CRYPTO_HASH_FAILED"]:{ko:"해시 생성에 실패했습니다",en:"Hash generation failed"},["CRYPTO_POLICY_VIOLATION"]:{ko:"암호화 정책 위반이 발생했습니다",en:"Crypto policy violation"},["UNKNOWN_ERROR"]:{ko:"알 수 없는 오류가 발생했습니다",en:"Unknown error"}},Pt=new Set(Object.values(E)),Q=new Set(["NETWORK_ERROR","RATE_LIMIT_EXCEEDED","NETWORK_TIMEOUT","NETWORK_SERVICE_UNAVAILABLE","PROVIDER_ERROR","UNKNOWN_ERROR"]),Z=new Set(["INVALID_REQUEST","AUTHENTICATION_FAILED","INSUFFICIENT_BALANCE","TEMPLATE_NOT_FOUND","MESSAGE_SEND_FAILED","CRYPTO_CONFIG_ERROR","CRYPTO_ENCRYPT_FAILED","CRYPTO_DECRYPT_FAILED","CRYPTO_HASH_FAILED","CRYPTO_POLICY_VIOLATION"]),P=(t)=>{if(typeof t!=="number"||Number.isNaN(t)||!Number.isFinite(t))return;return Math.trunc(t)},x=(t)=>{let n=P(t);if(n===void 0||n<0)return;return n},q=(t)=>{if(typeof t!=="string")return;return t.toLowerCase().trim()},wt=(t)=>{if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0},w=(t)=>{return typeof t==="object"&&t!==null&&!Array.isArray(t)},u=(t,n)=>{for(let e of n)if(e in t)return t[e];return},St=(t)=>{return t.length>0?t:"$"},nt=(t)=>{return t==="compat"?"compat":"safe"},L=(t)=>{if(t>=500)return"retryable";if(t===408||t===425||t===429)return"retryable";return"non_retryable"},X=(t)=>{let n=t.toLowerCase();if(n.includes("timeout")||n.includes("temporar")||n.includes("network")||n.includes("retry"))return"retryable";return};class K extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(t,n,e,i={}){super(n);if(this.name="KMsgError",this.code=t,this.details=e,this.providerErrorCode=i.providerErrorCode,this.providerErrorText=i.providerErrorText,this.httpStatus=P(i.httpStatus),this.requestId=typeof i.requestId==="string"?i.requestId:void 0,this.retryAfterMs=P(i.retryAfterMs),this.attempt=P(i.attempt),Array.isArray(i.causeChain))this.causeChain=i.causeChain;else if(i.causeChain!==void 0)this.causeChain=[i.causeChain];let r=Error.captureStackTrace;if(r)r(this,K)}getLocalizedMessage(t="ko"){let n=At[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 D=(t,n)=>{let e=P(t);if(e!==void 0)return e;if(n==="compat"&&typeof t==="string"){let i=Number(t.trim());if(Number.isFinite(i))return Math.trunc(i)}return},$=(t,n)=>{let e=wt(t);if(e)return e;if(n==="compat"&&(typeof t==="number"||typeof t==="boolean"))return String(t);return},et=(t)=>{if(typeof t!=="string")return;let n=t.trim().toUpperCase();if(!Pt.has(n))return;return n},k=(t,n)=>{t.push({...n,path:St(n.path)})},z=(t,n,e,i)=>{if(t===void 0)return[];let r=(()=>{if(Array.isArray(t))return t;if(e==="compat"&&typeof t==="string")return t.split(",").map((f)=>f.trim()).filter((f)=>f.length>0);return k(i,{code:"invalid_type",message:"expected array of KMsgErrorCode values",path:n}),[]})(),s=[],p=new Set;for(let f=0;f<r.length;f+=1){let y=r[f],o=et(typeof y==="string"?y:e==="compat"?String(y):y);if(!o){k(i,{code:"unknown_code",message:`unknown retry policy code: ${String(y)}`,path:`${n}[${f}]`});continue}if(p.has(o)){k(i,{code:"duplicate_code",message:`duplicate retry policy code: ${o}`,path:`${n}[${f}]`});continue}p.add(o),s.push(o)}return s},bt=(t,n,e)=>{if(t===void 0)return;if(typeof t==="string"){let i=t.trim().toLowerCase();if(i==="retryable")return"retryable";if(i==="non_retryable"||i==="non-retryable")return"non_retryable"}if(n==="compat"&&typeof t==="boolean")return t?"retryable":"non_retryable";k(e,{code:"invalid_fallback",message:`invalid fallback value: ${String(t)}`,path:"fallback"});return};function ut(t,n={}){let e=nt(n.mode),i=[];if(!w(t))return k(i,{code:"invalid_root",message:"retry policy must be an object",path:"$"}),{policy:null,issues:i};let r=new Set(["retryableCodes","nonRetryableCodes","fallback"]);for(let d of Object.keys(t)){if(r.has(d))continue;k(i,{code:"unknown_field",message:`unknown retry policy field: ${d}`,path:d})}let s=z(t.retryableCodes,"retryableCodes",e,i),p=z(t.nonRetryableCodes,"nonRetryableCodes",e,i),f=bt(t.fallback,e,i),y=new Set(s),o=new Set(p);for(let d of y){if(!o.has(d))continue;y.delete(d),k(i,{code:"conflicting_code",message:`code '${d}' is both retryable and nonRetryable; nonRetryable wins`,path:"retryableCodes"})}let a={...y.size>0?{retryableCodes:Array.from(y)}:{},...o.size>0?{nonRetryableCodes:Array.from(o)}:{},...f?{fallback:f}:{}};return{policy:a.retryableCodes!==void 0||a.nonRetryableCodes!==void 0||a.fallback!==void 0?a:null,issues:i}}function Dt(t,n={}){return ut(t,n).policy}function zt(t,n={}){if(typeof t!=="string"||t.trim().length===0)return null;try{let e=JSON.parse(t);return Dt(e,n)}catch{return null}}var tt=(t,n)=>{let e=t.response;if(!w(e))return;return D(u(e,["status","statusCode","httpStatus"]),n)},kt=(t,n)=>{if(t instanceof K&&Array.isArray(t.causeChain))return t.causeChain.slice();if(w(t)){let s=t.causeChain;if(Array.isArray(s))return s.slice();let p=t.details;if(n==="compat"&&w(p)){let f=p.causeChain;if(Array.isArray(f))return f.slice();if(f!==void 0)return[f]}}let e=[],i=new Set,r=t;for(let s=0;s<8;s+=1){if(!w(r))break;let p=r.cause;if(p===void 0||i.has(p))break;i.add(p),e.push(p),r=p}return e.length>0?e:void 0},mt=(t)=>{if(t instanceof Error&&typeof t.message==="string")return t.message;if(w(t)&&typeof t.message==="string")return t.message;return typeof t==="string"?t:"Unknown error"};function tn(t,n={}){let e=nt(n.mode),r=n.defaultCode??"UNKNOWN_ERROR",s={code:"fallback",classification:n.policy?"policy":"fallback"},p,f,y,o,a,h,d,A=(c)=>{if(c.providerErrorCode!==void 0)p=c.providerErrorCode,s.providerErrorCode="metadata";if(c.providerErrorText!==void 0)f=c.providerErrorText,s.providerErrorText="metadata";if(c.httpStatus!==void 0)y=c.httpStatus,s.httpStatus="metadata";if(c.requestId!==void 0)o=c.requestId,s.requestId="metadata";if(c.retryAfterMs!==void 0)a=x(c.retryAfterMs),s.retryAfterMs="metadata";if(c.attempt!==void 0)h=D(c.attempt,e),s.attempt="metadata";if(Array.isArray(c.causeChain))d=c.causeChain.slice(),s.causeChain="metadata"},C=(c,F)=>{if(p===void 0){let g=$(u(c,["providerErrorCode","errorCode","resultCode"]),e);if(g!==void 0)p=g,s.providerErrorCode=F}if(f===void 0){let g=$(u(c,["providerErrorText","errorMessage","msg","message"]),e);if(g!==void 0)f=g,s.providerErrorText=F}if(y===void 0){let g=D(u(c,["httpStatus","statusCode","status"]),e)??tt(c,e);if(g!==void 0)y=g,s.httpStatus=F==="details"?"details":"http"}if(o===void 0){let g=$(u(c,["requestId","request_id","reqId","traceId"]),e);if(g!==void 0)o=g,s.requestId=F}if(a===void 0){let g=x(D(u(c,["retryAfterMs","retry_after_ms","retryAfter"]),e));if(g!==void 0)a=g,s.retryAfterMs=F}if(h===void 0){let g=D(c.attempt,e);if(g!==void 0&&g>0)h=g,s.attempt=F}};if(t instanceof K){if(r=t.code,s.code="input",A(t),e==="compat"&&w(t.details))C(t.details,"details")}else if(w(t)){let c=et(u(t,["code","errorCode","resultCode"]));if(c!==void 0)r=c,s.code="input";else if(y===void 0){let F=D(u(t,["httpStatus","statusCode","status"]),e)??tt(t,e);if(F!==void 0&&F>=500)r="PROVIDER_ERROR",s.code="http"}if(C(t,"input"),e==="compat"&&w(t.details))C(t.details,"details")}if(d===void 0){let c=kt(t,e);if(c!==void 0)d=c,s.causeChain="input"}if(n.attempt!==void 0&&D(n.attempt,e)!==void 0){let c=D(n.attempt,e);if(c!==void 0&&c>0)h=c,s.attempt="input"}let b=new K(r,mt(t),void 0,{providerErrorCode:p,providerErrorText:f,httpStatus:y,requestId:o,retryAfterMs:a,attempt:h,causeChain:d}),l=R.classifyForRetry(b,n.policy);return{code:r,classification:l,...p!==void 0?{providerErrorCode:p}:{},...f!==void 0?{providerErrorText:f}:{},...y!==void 0?{httpStatus:y}:{},...o!==void 0?{requestId:o}:{},...a!==void 0?{retryAfterMs:a}:{},...h!==void 0?{attempt:h}:{},...d!==void 0?{causeChain:d}:{},sources:s}}var R={isRetryable(t,n={}){return R.classifyForRetry(t,n)==="retryable"},classifyForRetry(t,n={}){if(t instanceof K){if(new Set(n.retryableCodes??Array.from(Q)).has(t.code))return"retryable";if(new Set(n.nonRetryableCodes??Array.from(Z)).has(t.code))return"non_retryable";if(t.httpStatus!==void 0)return L(t.httpStatus);let y=X(t.message);if(y)return y;if(n.classifyByMessage&&t.message){let o=n.classifyByMessage(t.message);if(o)return o}if(n.fallback)return n.fallback;return"non_retryable"}let e=t&&typeof t==="object"?t:void 0,i=q(e?.status)??q(e?.statusCode)??q(e?.code),r=P(e?.status)??P(e?.statusCode)??P(e?.httpStatus);if(typeof i==="string"&&i.startsWith("5"))return"retryable";if(r!==void 0){if(n.classifyByStatusCode)return n.classifyByStatusCode(r);return L(r)}let s=typeof e?.message==="string"?X(e.message):void 0;if(s)return s;if(n.classifyByMessage&&typeof e?.message==="string"){let p=n.classifyByMessage(e.message);if(p)return p}return n.fallback??"non_retryable"},resolveRetryAfterMs(t,n){if(n?.retryAfterMs){let e=n.retryAfterMs(t),i=x(e);if(i!==void 0)return i}if(t.retryAfterMs!==void 0)return x(t.retryAfterMs);if(t.code==="RATE_LIMIT_EXCEEDED"&&t.retryAfterMs===void 0)return;return},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 K(t.code,t.message,t.details,{...R.toRetryMetadata(t),attempt:P(n)})},DEFAULT_RETRYABLE_ERROR_CODES:Q,DEFAULT_NON_RETRYABLE_ERROR_CODES:Z};function Tt(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 M extends K{kind;fieldPath;failMode;openFallback;constructor(t,n,e,i={}){super(Tt(t),n,e,i);this.name="FieldCryptoError",this.kind=t,this.fieldPath=typeof i.fieldPath==="string"?i.fieldPath:void 0,this.failMode=i.failMode,this.openFallback=i.openFallback}toJSON(){return{...super.toJSON(),kind:this.kind,fieldPath:this.fieldPath,failMode:this.failMode,openFallback:this.openFallback}}}var Ot=["tenantId","providerId","messageId"];function v(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function Rt(t){if(typeof t!=="number"||!Number.isFinite(t))return;if(t<=0||t>100)return;return t}function it(t){let n=[];for(let e of t){let i=v(e.kid),r=Rt(e.percentage);if(!i||r===void 0)continue;n.push({kid:i,percentage:r})}return n}function Et(t,n,e){let i=n.map((r)=>{let s=t[r];return typeof s==="string"?s:""}).join("|");return`${e}::${i}`}function xt(t){let n=2166136261;for(let e=0;e<t.length;e+=1)n^=t.charCodeAt(e),n=n*16777619>>>0;return n>>>0}function Mt(t,n){let e=0;for(let i of t)if(e+=i.percentage,n<e)return i.kid;return}function H(t,n,e){let i=it(n.buckets),r=v(n.defaultKid)??v(e);if(i.length===0)return r;let s=v(n.seed)??"kmsg-rollout-v1",p=n.stickyFields??Ot,f=Et(t,p,s),y=xt(f)%100;return Mt(i,y)??r}function st(t){return it(t.buckets).map((n)=>n.kid)}function T(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)=>T(n)).filter((n)=>Boolean(n))}function G(t){let n=[],e=new Set;for(let i of t){let r=T(i);if(!r||e.has(r))continue;e.add(r),n.push(r)}return n}function vt(t){return T(t.providerId)??"default"}function rt(t){let n=T(t.activeKid)??"default",e=G([n,...V(t.decryptKids)]);return{async resolveEncryptKey(){return{kid:n}},async resolveDecryptKeys(){return e}}}function _(t){let n=typeof t.cacheTtlMs==="number"&&t.cacheTtlMs>=0?Math.trunc(t.cacheTtlMs):30000,e=T(t.fallback?.activeKid),i=V(t.fallback?.decryptKids),r;async function s(p){let f=Date.now();if(r&&f<r.expiresAt)return r.value;let y=await t.provider.loadKeySet(p),o=T(y.activeKid)??e??vt(p),a=G([o,...V(y.decryptKids),...i]),h={activeKid:o,decryptKids:a,refreshedAt:Date.now()};return r={value:h,expiresAt:Date.now()+n},h}return{async resolveEncryptKey(p){return{kid:(await s(p)).activeKid}},async resolveDecryptKeys(p){let f=await s(p);return f.decryptKids??[f.activeKid]}}}function yn(t,n){return{async resolveEncryptKey(e){let i=await t.resolveEncryptKey(e);return{kid:H(e,n,i.kid)??i.kid}},async resolveDecryptKeys(e){let i=await t.resolveEncryptKey(e),r=t.resolveDecryptKeys?await t.resolveDecryptKeys(e):[i.kid],s=H(e,n,i.kid),p=st(n);return G([...s?[s]:[],i.kid,...r??[],...p])}}}function cn(t){return _({provider:{async loadKeySet(e){return t.client.getKeyState({...e,...t.keyAlias?{keyAlias:t.keyAlias}:{},...t.region?{region:t.region}:{}})}},cacheTtlMs:t.cacheTtlMs,fallback:{activeKid:t.fallbackActiveKid,decryptKids:t.fallbackDecryptKids}})}function N(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function pt(t,n){return N(t[n])}function _t(t,n){if(!t)return[];return t.split(n).map((e)=>N(e)).filter((e)=>Boolean(e))}function ln(t={}){let n=globalThis.process?.env,e=t.env??n??{},i=N(t.delimiter)??",",r=t.activeKidEnv??"KMSG_ACTIVE_KID",s=t.decryptKidsEnv??"KMSG_DECRYPT_KIDS",p=pt(e,r)??N(t.fallbackActiveKid)??"default",f=[p,..._t(pt(e,s),i),...t.fallbackDecryptKids??[]];return rt({activeKid:p,decryptKids:f})}function Kn(t){return _({provider:{async loadKeySet(e){return t.client.getKeyState({...e,...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 J(t){return typeof t==="function"}function yt(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function ft(t,n,e){let i=t.fields[n];if(i)return i;if(n.startsWith("metadata.")){let r=t.fields["metadata.*"];if(r)return r}return e}function Nt(t,n={}){let e=[];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")e.push({message:"fieldCrypto provider is required",rule:"fieldCrypto.provider.required",path:"provider",hint:"Set provider with encrypt/decrypt/hash methods"});else{if(!J(t.provider.encrypt))e.push({message:"provider.encrypt must be a function",rule:"fieldCrypto.provider.encrypt.required",path:"provider.encrypt"});if(!J(t.provider.decrypt))e.push({message:"provider.decrypt must be a function",rule:"fieldCrypto.provider.decrypt.required",path:"provider.decrypt"});if(!J(t.provider.hash))e.push({message:"provider.hash must be a function",rule:"fieldCrypto.provider.hash.required",path:"provider.hash"})}if(!t.fields||typeof t.fields!=="object")e.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)e.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[p,f]of s){if(!yt(p))e.push({message:"field path must be a non-empty string",rule:"fieldCrypto.fields.path.non_empty",path:"fields"});if(f!=="plain"&&f!=="encrypt"&&f!=="encrypt+hash"&&f!=="mask")e.push({message:`unsupported field mode: ${String(f)}`,rule:"fieldCrypto.fields.mode.supported",path:`fields.${p}`})}}let i=t.failMode??"closed",r=t.openFallback??"masked";if(i==="open"&&r==="plaintext"&&t.unsafeAllowPlaintextStorage!==!0)e.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)e.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 p=t.aadFields[s];if(!yt(p))e.push({message:"aadFields cannot include empty key",rule:"fieldCrypto.aad_fields.no_empty_key",path:`aadFields[${s}]`})}}if(n.secureMode&&!n.compatPlainColumns){let s=ft(t,"to","encrypt+hash"),p=ft(t,"from","encrypt+hash");if(s==="plain")e.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(p==="plain")e.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:e.length===0,issues:e}}function An(t,n={}){let e=Nt(t,n);if(e.valid)return;let i=e.issues[0];if(!i)throw new M("config","fieldCrypto config validation failed",{rule:"fieldCrypto.config.invalid",issues:e.issues});throw new M("config",i.message,{rule:i.rule,path:i.path,hint:i.hint,issues:e.issues},{fieldPath:i.path})}function I(t){let n=t instanceof Uint8Array?t:new Uint8Array(t),e=typeof globalThis<"u"?globalThis.Buffer:void 0;return(e?e.from(n).toString("base64"):btoa(String.fromCharCode(...n))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function U(t){let n=t.replace(/-/g,"+").replace(/_/g,"/"),e=n.length%4===0?n:`${n}${"=".repeat(4-n.length%4)}`,i=typeof globalThis<"u"?globalThis.Buffer:void 0;if(i)return new Uint8Array(i.from(e,"base64"));let r=atob(e),s=new Uint8Array(r.length);for(let p=0;p<r.length;p+=1)s[p]=r.charCodeAt(p);return s}function ot(t,n){if(t instanceof Uint8Array)return t;if(t instanceof ArrayBuffer)return new Uint8Array(t);if(n==="base64url")return U(t);return new TextEncoder().encode(t)}function It(t){let n=t instanceof Uint8Array?t:new Uint8Array(t);return Array.from(n).map((e)=>e.toString(16).padStart(2,"0")).join("")}function S(t){let n=new Uint8Array(t.byteLength);return n.set(t),n.buffer}function ct(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 Ut(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 Bt(t){let n=String(t??"").trim();if(n.length===0)return"";let e=n.startsWith("+"),i=n.replace(/\D/g,"");return e?`+${i}`:i}function at(t=3,n=2){return(e)=>{let i=String(e??"");if(i.length<=t+n)return"*".repeat(Math.max(0,i.length));let r=i.slice(0,t),s=i.slice(-n);return`${r}${"*".repeat(i.length-t-n)}${s}`}}function Sn(t){let n=t.algorithm??"A256GCM",e=t.keyEncoding??"base64url",i=t.hashKeyEncoding??e,r=new Map,s=new Map,p=(y)=>{let o=r.get(y);if(o)return o;let a=t.keys[y];if(!a)throw Error(`Unknown encryption key id: ${y}`);let h=ot(a,e),d=crypto.subtle.importKey("raw",S(h),"AES-GCM",!1,["encrypt","decrypt"]);return r.set(y,d),d},f=(y)=>{let o=s.get(y);if(o)return o;let a=t.hashKeys?.[y]??t.keys[y];if(!a)throw Error(`Unknown hash key id: ${y}`);let h=ot(a,i),d=crypto.subtle.importKey("raw",S(h),{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return s.set(y,d),d};return{async encrypt(y){let o=y.kid??t.activeKid,a=await p(o),h=crypto.getRandomValues(new Uint8Array(12)),d=new TextEncoder().encode(JSON.stringify(y.aad??{})),A=new TextEncoder().encode(y.value),C=await crypto.subtle.encrypt({name:"AES-GCM",iv:S(h),additionalData:S(d),tagLength:128},a,S(A)),b=new Uint8Array(C),l=b.slice(b.length-16),c=b.slice(0,b.length-16);return{ciphertext:{v:1,alg:n,kid:o,iv:I(h),tag:I(l),ct:I(c)},kid:o}},async decrypt(y){let o=ct(y.ciphertext),a=y.candidateKids&&y.candidateKids.length>0?y.candidateKids:[o.kid],h=U(o.iv),d=U(o.tag),A=U(o.ct),C=new Uint8Array(A.length+d.length);C.set(A,0),C.set(d,A.length);let b=new TextEncoder().encode(JSON.stringify(y.aad??{})),l;for(let c of a)try{let F=await p(c),g=await crypto.subtle.decrypt({name:"AES-GCM",iv:S(h),additionalData:S(b),tagLength:128},F,S(C));return new TextDecoder().decode(new Uint8Array(g))}catch(F){l=F}throw Error(`Failed to decrypt ciphertext: ${l instanceof Error?l.message:String(l??"unknown")}`)},async hash(y){let o=y.kid??t.activeKid,a=await f(o),h=await crypto.subtle.sign("HMAC",a,S(new TextEncoder().encode(y.value)));return It(h)},mask(y){return at()(y.value)}}}function bn(){return{encrypt(t){return{ciphertext:JSON.stringify({v:1,alg:"NOOP",kid:"noop",iv:"",tag:"",ct:t.value})}},decrypt(t){try{return ct(t.ciphertext).ct}catch{return t.ciphertext}},hash(t){let n=Bt(t.value);return I(new TextEncoder().encode(n))},mask(t){return at()(t.value)}}}function un(t){return Ut(t)}var qt;((r)=>{r.DEBUG="DEBUG";r.INFO="INFO";r.WARN="WARN";r.ERROR="ERROR"})(qt||={});var $t=["to","from","phone","phoneNumber","recipient","sender","secret","apiKey","apiSecret","authorization","auth","token","password","payload","message","content","text"];function Ht(t){let n=t.toLowerCase();return $t.some((e)=>n.includes(e.toLowerCase()))}function Vt(t){let n=t.trim();if(n.length<=4)return"***";if(n.includes("@")){let[r,s]=n.split("@");return`${r.slice(0,2)}${"*".repeat(Math.max(1,r.length-2))}@${s}`}let e=n.slice(0,3),i=n.slice(-2);return`${e}${"*".repeat(Math.max(1,n.length-5))}${i}`}function W(t,n){if(n===void 0||n===null)return n;if(Ht(t)){if(typeof n==="string")return Vt(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((e)=>W(t,e));if(typeof n==="object"){let e={};for(let[i,r]of Object.entries(n))e[i]=W(i,r);return e}return n}function Gt(t){let n={};for(let[e,i]of Object.entries(t))n[e]=W(e,i);return n}class Y{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=Gt(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 e=t.timestamp.toISOString(),i=this.config.enableColors?this.colorizeLevel(t.level):t.level,r=Object.keys(n).length>0?` [${Object.entries(n).map(([p,f])=>`${p}=${f}`).join(", ")}]`:"",s=`${e} ${i}${r}: ${t.message}`;if(t.duration!==void 0)s+=` (${t.duration}ms)`;if(t.error)s+=`
|
|
2
|
-
${
|
|
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=
|
|
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;
|
package/dist/provider.d.ts
CHANGED
|
@@ -1,6 +1,35 @@
|
|
|
1
1
|
import type { KMsgError } from "./errors";
|
|
2
2
|
import type { Result } from "./result";
|
|
3
3
|
import type { BalanceQuery, BalanceResult, DeliveryStatusQuery, DeliveryStatusResult, KakaoChannel, KakaoChannelCategories, MessageType, ProviderOnboardingSpec, SendOptions, SendResult } from "./types/index";
|
|
4
|
+
/**
|
|
5
|
+
* Fetch implementation used for a single provider operation.
|
|
6
|
+
*
|
|
7
|
+
* Callers can inject a compatible implementation for runtime-specific
|
|
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.
|
|
13
|
+
*/
|
|
14
|
+
export type ProviderFetch = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
15
|
+
/**
|
|
16
|
+
* Per-operation transport context passed to provider calls.
|
|
17
|
+
*
|
|
18
|
+
* Providers that use fetch should forward `signal` unchanged to the
|
|
19
|
+
* underlying request and prefer `fetch` over the runtime global when supplied.
|
|
20
|
+
*/
|
|
21
|
+
export interface ProviderRequestContext {
|
|
22
|
+
/** Abort signal for the underlying provider transport. */
|
|
23
|
+
signal?: AbortSignal;
|
|
24
|
+
/** Optional fetch implementation for this operation. */
|
|
25
|
+
fetch?: ProviderFetch;
|
|
26
|
+
}
|
|
27
|
+
export type ProviderTransportSupport = "supported" | "unsupported";
|
|
28
|
+
/** Transport features a provider forwards to its underlying operation. */
|
|
29
|
+
export interface ProviderTransportCapabilities {
|
|
30
|
+
abortSignal: ProviderTransportSupport;
|
|
31
|
+
injectableFetch: ProviderTransportSupport;
|
|
32
|
+
}
|
|
4
33
|
/**
|
|
5
34
|
* Represents an AlimTalk template registered with a provider.
|
|
6
35
|
* Templates must be approved by Kakao before use.
|
|
@@ -182,6 +211,11 @@ export interface Provider {
|
|
|
182
211
|
* Messages of unsupported types will be rejected.
|
|
183
212
|
*/
|
|
184
213
|
readonly supportedTypes: readonly MessageType[];
|
|
214
|
+
/**
|
|
215
|
+
* Per-operation transport features supported by this provider.
|
|
216
|
+
* Missing declarations must be treated as unsupported.
|
|
217
|
+
*/
|
|
218
|
+
readonly transportCapabilities?: ProviderTransportCapabilities;
|
|
185
219
|
/**
|
|
186
220
|
* Check if the provider is operational.
|
|
187
221
|
* Used for health monitoring and circuit breaker decisions.
|
|
@@ -191,12 +225,12 @@ export interface Provider {
|
|
|
191
225
|
* Send a message through this provider.
|
|
192
226
|
* @returns Result with SendResult on success, KMsgError on failure.
|
|
193
227
|
*/
|
|
194
|
-
send(params: SendOptions): Promise<Result<SendResult, KMsgError>>;
|
|
228
|
+
send(params: SendOptions, context?: ProviderRequestContext): Promise<Result<SendResult, KMsgError>>;
|
|
195
229
|
/**
|
|
196
230
|
* Query delivery status for a previously sent message.
|
|
197
231
|
* Optional capability - not all providers support this.
|
|
198
232
|
*/
|
|
199
|
-
getDeliveryStatus?(query: DeliveryStatusQuery): Promise<Result<DeliveryStatusResult | null, KMsgError>>;
|
|
233
|
+
getDeliveryStatus?(query: DeliveryStatusQuery, context?: ProviderRequestContext): Promise<Result<DeliveryStatusResult | null, KMsgError>>;
|
|
200
234
|
/**
|
|
201
235
|
* Get the onboarding specification for this provider.
|
|
202
236
|
* Used by tooling to guide provider configuration.
|
|
@@ -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.
|
|
4
|
-
"packageManager": "bun@1.
|
|
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.
|
|
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.
|
|
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].
|
|
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
|
|
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.
|
|
41
|
+
"ttsc": "^0.30.4",
|
|
44
42
|
"typescript": "^7.0.2"
|
|
45
43
|
},
|
|
46
44
|
"peerDependencies": {},
|
|
47
45
|
"files": [
|
|
48
|
-
"dist/**/*.
|
|
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:Et,getOwnPropertyDescriptor:xt}=Object,Mt=Object.prototype.hasOwnProperty;var pt=new WeakMap,vt=(t)=>{var n=pt.get(t),e;if(n)return n;if(n=V({},"__esModule",{value:!0}),t&&typeof t==="object"||typeof t==="function")Et(t).map((i)=>!Mt.call(n,i)&&V(n,i,{get:()=>t[i],enumerable:!(e=xt(t,i))||e.enumerable}));return pt.set(t,n),n};var _t=(t,n)=>{for(var e in n)V(t,e,{get:n[e],enumerable:!0,configurable:!0,set:(i)=>n[e]=()=>i})};var En={};_t(En,{validateFieldCryptoConfig:()=>Pt,validateErrorRetryPolicy:()=>gt,toCiphertextEnvelopeString:()=>cn,setGlobalLogger:()=>gn,selectActiveKidByRollout:()=>N,resolveFieldMode:()=>L,readRuntimeEnv:()=>An,parseErrorRetryPolicyFromJson:()=>$t,ok:()=>it,normalizeRetryAfterMs:()=>x,normalizeProviderError:()=>Gt,normalizePhoneForHash:()=>bt,normalizeMessageStatus:()=>Rn,normalizeErrorRetryPolicy:()=>Kt,loggerMiddleware:()=>Cn,logger:()=>Kn,isTerminalDeliveryStatus:()=>un,isPollableDeliveryStatus:()=>Dn,isKMsgTerminalStatus:()=>bn,isKMsgMessageType:()=>Tn,isKMsgDeliveryStatus:()=>Sn,isCryptoEnvelope:()=>yn,getRuntimeEnvSource:()=>Dt,getRolloutKnownKids:()=>W,getPollableStatuses:()=>kn,getLogger:()=>k,fail:()=>st,createVaultTransitKeyResolver:()=>en,createStaticKeyResolver:()=>Q,createRollingKeyResolver:()=>Xt,createRefreshableKeyResolver:()=>v,createNoopFieldCryptoProvider:()=>on,createLogger:()=>tt,createEnvKeyResolver:()=>nn,createDefaultMasker:()=>X,createAwsKmsKeyResolver:()=>zt,createAesGcmFieldCryptoProvider:()=>fn,assertFieldCryptoConfig:()=>sn,RetryHandler:()=>T,Result:()=>Fn,RateLimiter:()=>et,QUEUED_MESSAGE_STATUS:()=>Rt,Logger:()=>$,LogLevel:()=>ut,KNOWN_MESSAGE_STATUSES:()=>On,KMsgErrorCode:()=>R,KMsgError:()=>K,KMSG_TERMINAL_STATUSES:()=>mt,KMSG_POLLABLE_STATUSES:()=>rt,KMSG_MESSAGE_TYPES:()=>Ot,KMSG_DELIVERY_STATUSES:()=>kt,FieldCryptoError:()=>M,ErrorUtils:()=>O,CircuitBreaker:()=>nt,BulkOperationHandler:()=>H});module.exports=vt(En);var R;((l)=>{l.INVALID_REQUEST="INVALID_REQUEST";l.AUTHENTICATION_FAILED="AUTHENTICATION_FAILED";l.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE";l.TEMPLATE_NOT_FOUND="TEMPLATE_NOT_FOUND";l.RATE_LIMIT_EXCEEDED="RATE_LIMIT_EXCEEDED";l.NETWORK_ERROR="NETWORK_ERROR";l.NETWORK_TIMEOUT="NETWORK_TIMEOUT";l.NETWORK_SERVICE_UNAVAILABLE="NETWORK_SERVICE_UNAVAILABLE";l.PROVIDER_ERROR="PROVIDER_ERROR";l.MESSAGE_SEND_FAILED="MESSAGE_SEND_FAILED";l.CRYPTO_CONFIG_ERROR="CRYPTO_CONFIG_ERROR";l.CRYPTO_ENCRYPT_FAILED="CRYPTO_ENCRYPT_FAILED";l.CRYPTO_DECRYPT_FAILED="CRYPTO_DECRYPT_FAILED";l.CRYPTO_HASH_FAILED="CRYPTO_HASH_FAILED";l.CRYPTO_POLICY_VIOLATION="CRYPTO_POLICY_VIOLATION";l.UNKNOWN_ERROR="UNKNOWN_ERROR"})(R||={});var Nt={["INVALID_REQUEST"]:{ko:"잘못된 요청입니다",en:"Invalid request"},["AUTHENTICATION_FAILED"]:{ko:"인증에 실패했습니다",en:"Authentication failed"},["INSUFFICIENT_BALANCE"]:{ko:"잔액이 부족합니다",en:"Insufficient balance"},["TEMPLATE_NOT_FOUND"]:{ko:"템플릿을 찾을 수 없습니다",en:"Template not found"},["RATE_LIMIT_EXCEEDED"]:{ko:"요청 한도를 초과했습니다",en:"Rate limit exceeded"},["NETWORK_ERROR"]:{ko:"네트워크 오류가 발생했습니다",en:"Network error"},["NETWORK_TIMEOUT"]:{ko:"네트워크 요청 시간이 초과되었습니다",en:"Network timeout"},["NETWORK_SERVICE_UNAVAILABLE"]:{ko:"서비스를 일시적으로 사용할 수 없습니다",en:"Service temporarily unavailable"},["PROVIDER_ERROR"]:{ko:"제공자 오류가 발생했습니다",en:"Provider error"},["MESSAGE_SEND_FAILED"]:{ko:"메시지 전송에 실패했습니다",en:"Message send failed"},["CRYPTO_CONFIG_ERROR"]:{ko:"암호화 설정 오류가 발생했습니다",en:"Crypto configuration error"},["CRYPTO_ENCRYPT_FAILED"]:{ko:"암호화에 실패했습니다",en:"Encryption failed"},["CRYPTO_DECRYPT_FAILED"]:{ko:"복호화에 실패했습니다",en:"Decryption failed"},["CRYPTO_HASH_FAILED"]:{ko:"해시 생성에 실패했습니다",en:"Hash generation failed"},["CRYPTO_POLICY_VIOLATION"]:{ko:"암호화 정책 위반이 발생했습니다",en:"Crypto policy violation"},["UNKNOWN_ERROR"]:{ko:"알 수 없는 오류가 발생했습니다",en:"Unknown error"}},It=new Set(Object.values(R)),yt=new Set(["NETWORK_ERROR","RATE_LIMIT_EXCEEDED","NETWORK_TIMEOUT","NETWORK_SERVICE_UNAVAILABLE","PROVIDER_ERROR","UNKNOWN_ERROR"]),ft=new Set(["INVALID_REQUEST","AUTHENTICATION_FAILED","INSUFFICIENT_BALANCE","TEMPLATE_NOT_FOUND","MESSAGE_SEND_FAILED","CRYPTO_CONFIG_ERROR","CRYPTO_ENCRYPT_FAILED","CRYPTO_DECRYPT_FAILED","CRYPTO_HASH_FAILED","CRYPTO_POLICY_VIOLATION"]),P=(t)=>{if(typeof t!=="number"||Number.isNaN(t)||!Number.isFinite(t))return;return Math.trunc(t)},x=(t)=>{let n=P(t);if(n===void 0||n<0)return;return n},G=(t)=>{if(typeof t!=="string")return;return t.toLowerCase().trim()},Ut=(t)=>{if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0},w=(t)=>{return typeof t==="object"&&t!==null&&!Array.isArray(t)},u=(t,n)=>{for(let e of n)if(e in t)return t[e];return},Bt=(t)=>{return t.length>0?t:"$"},lt=(t)=>{return t==="compat"?"compat":"safe"},ot=(t)=>{if(t>=500)return"retryable";if(t===408||t===425||t===429)return"retryable";return"non_retryable"},ct=(t)=>{let n=t.toLowerCase();if(n.includes("timeout")||n.includes("temporar")||n.includes("network")||n.includes("retry"))return"retryable";return};class K extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(t,n,e,i={}){super(n);if(this.name="KMsgError",this.code=t,this.details=e,this.providerErrorCode=i.providerErrorCode,this.providerErrorText=i.providerErrorText,this.httpStatus=P(i.httpStatus),this.requestId=typeof i.requestId==="string"?i.requestId:void 0,this.retryAfterMs=P(i.retryAfterMs),this.attempt=P(i.attempt),Array.isArray(i.causeChain))this.causeChain=i.causeChain;else if(i.causeChain!==void 0)this.causeChain=[i.causeChain];let r=Error.captureStackTrace;if(r)r(this,K)}getLocalizedMessage(t="ko"){let n=Nt[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 D=(t,n)=>{let e=P(t);if(e!==void 0)return e;if(n==="compat"&&typeof t==="string"){let i=Number(t.trim());if(Number.isFinite(i))return Math.trunc(i)}return},J=(t,n)=>{let e=Ut(t);if(e)return e;if(n==="compat"&&(typeof t==="number"||typeof t==="boolean"))return String(t);return},ht=(t)=>{if(typeof t!=="string")return;let n=t.trim().toUpperCase();if(!It.has(n))return;return n},m=(t,n)=>{t.push({...n,path:Bt(n.path)})},at=(t,n,e,i)=>{if(t===void 0)return[];let r=(()=>{if(Array.isArray(t))return t;if(e==="compat"&&typeof t==="string")return t.split(",").map((f)=>f.trim()).filter((f)=>f.length>0);return m(i,{code:"invalid_type",message:"expected array of KMsgErrorCode values",path:n}),[]})(),s=[],p=new Set;for(let f=0;f<r.length;f+=1){let y=r[f],o=ht(typeof y==="string"?y:e==="compat"?String(y):y);if(!o){m(i,{code:"unknown_code",message:`unknown retry policy code: ${String(y)}`,path:`${n}[${f}]`});continue}if(p.has(o)){m(i,{code:"duplicate_code",message:`duplicate retry policy code: ${o}`,path:`${n}[${f}]`});continue}p.add(o),s.push(o)}return s},qt=(t,n,e)=>{if(t===void 0)return;if(typeof t==="string"){let i=t.trim().toLowerCase();if(i==="retryable")return"retryable";if(i==="non_retryable"||i==="non-retryable")return"non_retryable"}if(n==="compat"&&typeof t==="boolean")return t?"retryable":"non_retryable";m(e,{code:"invalid_fallback",message:`invalid fallback value: ${String(t)}`,path:"fallback"});return};function gt(t,n={}){let e=lt(n.mode),i=[];if(!w(t))return m(i,{code:"invalid_root",message:"retry policy must be an object",path:"$"}),{policy:null,issues:i};let r=new Set(["retryableCodes","nonRetryableCodes","fallback"]);for(let d of Object.keys(t)){if(r.has(d))continue;m(i,{code:"unknown_field",message:`unknown retry policy field: ${d}`,path:d})}let s=at(t.retryableCodes,"retryableCodes",e,i),p=at(t.nonRetryableCodes,"nonRetryableCodes",e,i),f=qt(t.fallback,e,i),y=new Set(s),o=new Set(p);for(let d of y){if(!o.has(d))continue;y.delete(d),m(i,{code:"conflicting_code",message:`code '${d}' is both retryable and nonRetryable; nonRetryable wins`,path:"retryableCodes"})}let a={...y.size>0?{retryableCodes:Array.from(y)}:{},...o.size>0?{nonRetryableCodes:Array.from(o)}:{},...f?{fallback:f}:{}};return{policy:a.retryableCodes!==void 0||a.nonRetryableCodes!==void 0||a.fallback!==void 0?a:null,issues:i}}function Kt(t,n={}){return gt(t,n).policy}function $t(t,n={}){if(typeof t!=="string"||t.trim().length===0)return null;try{let e=JSON.parse(t);return Kt(e,n)}catch{return null}}var dt=(t,n)=>{let e=t.response;if(!w(e))return;return D(u(e,["status","statusCode","httpStatus"]),n)},Ht=(t,n)=>{if(t instanceof K&&Array.isArray(t.causeChain))return t.causeChain.slice();if(w(t)){let s=t.causeChain;if(Array.isArray(s))return s.slice();let p=t.details;if(n==="compat"&&w(p)){let f=p.causeChain;if(Array.isArray(f))return f.slice();if(f!==void 0)return[f]}}let e=[],i=new Set,r=t;for(let s=0;s<8;s+=1){if(!w(r))break;let p=r.cause;if(p===void 0||i.has(p))break;i.add(p),e.push(p),r=p}return e.length>0?e:void 0},Vt=(t)=>{if(t instanceof Error&&typeof t.message==="string")return t.message;if(w(t)&&typeof t.message==="string")return t.message;return typeof t==="string"?t:"Unknown error"};function Gt(t,n={}){let e=lt(n.mode),r=n.defaultCode??"UNKNOWN_ERROR",s={code:"fallback",classification:n.policy?"policy":"fallback"},p,f,y,o,a,h,d,A=(c)=>{if(c.providerErrorCode!==void 0)p=c.providerErrorCode,s.providerErrorCode="metadata";if(c.providerErrorText!==void 0)f=c.providerErrorText,s.providerErrorText="metadata";if(c.httpStatus!==void 0)y=c.httpStatus,s.httpStatus="metadata";if(c.requestId!==void 0)o=c.requestId,s.requestId="metadata";if(c.retryAfterMs!==void 0)a=x(c.retryAfterMs),s.retryAfterMs="metadata";if(c.attempt!==void 0)h=D(c.attempt,e),s.attempt="metadata";if(Array.isArray(c.causeChain))d=c.causeChain.slice(),s.causeChain="metadata"},C=(c,F)=>{if(p===void 0){let g=J(u(c,["providerErrorCode","errorCode","resultCode"]),e);if(g!==void 0)p=g,s.providerErrorCode=F}if(f===void 0){let g=J(u(c,["providerErrorText","errorMessage","msg","message"]),e);if(g!==void 0)f=g,s.providerErrorText=F}if(y===void 0){let g=D(u(c,["httpStatus","statusCode","status"]),e)??dt(c,e);if(g!==void 0)y=g,s.httpStatus=F==="details"?"details":"http"}if(o===void 0){let g=J(u(c,["requestId","request_id","reqId","traceId"]),e);if(g!==void 0)o=g,s.requestId=F}if(a===void 0){let g=x(D(u(c,["retryAfterMs","retry_after_ms","retryAfter"]),e));if(g!==void 0)a=g,s.retryAfterMs=F}if(h===void 0){let g=D(c.attempt,e);if(g!==void 0&&g>0)h=g,s.attempt=F}};if(t instanceof K){if(r=t.code,s.code="input",A(t),e==="compat"&&w(t.details))C(t.details,"details")}else if(w(t)){let c=ht(u(t,["code","errorCode","resultCode"]));if(c!==void 0)r=c,s.code="input";else if(y===void 0){let F=D(u(t,["httpStatus","statusCode","status"]),e)??dt(t,e);if(F!==void 0&&F>=500)r="PROVIDER_ERROR",s.code="http"}if(C(t,"input"),e==="compat"&&w(t.details))C(t.details,"details")}if(d===void 0){let c=Ht(t,e);if(c!==void 0)d=c,s.causeChain="input"}if(n.attempt!==void 0&&D(n.attempt,e)!==void 0){let c=D(n.attempt,e);if(c!==void 0&&c>0)h=c,s.attempt="input"}let b=new K(r,Vt(t),void 0,{providerErrorCode:p,providerErrorText:f,httpStatus:y,requestId:o,retryAfterMs:a,attempt:h,causeChain:d}),l=O.classifyForRetry(b,n.policy);return{code:r,classification:l,...p!==void 0?{providerErrorCode:p}:{},...f!==void 0?{providerErrorText:f}:{},...y!==void 0?{httpStatus:y}:{},...o!==void 0?{requestId:o}:{},...a!==void 0?{retryAfterMs:a}:{},...h!==void 0?{attempt:h}:{},...d!==void 0?{causeChain:d}:{},sources:s}}var O={isRetryable(t,n={}){return O.classifyForRetry(t,n)==="retryable"},classifyForRetry(t,n={}){if(t instanceof K){if(new Set(n.retryableCodes??Array.from(yt)).has(t.code))return"retryable";if(new Set(n.nonRetryableCodes??Array.from(ft)).has(t.code))return"non_retryable";if(t.httpStatus!==void 0)return ot(t.httpStatus);let y=ct(t.message);if(y)return y;if(n.classifyByMessage&&t.message){let o=n.classifyByMessage(t.message);if(o)return o}if(n.fallback)return n.fallback;return"non_retryable"}let e=t&&typeof t==="object"?t:void 0,i=G(e?.status)??G(e?.statusCode)??G(e?.code),r=P(e?.status)??P(e?.statusCode)??P(e?.httpStatus);if(typeof i==="string"&&i.startsWith("5"))return"retryable";if(r!==void 0){if(n.classifyByStatusCode)return n.classifyByStatusCode(r);return ot(r)}let s=typeof e?.message==="string"?ct(e.message):void 0;if(s)return s;if(n.classifyByMessage&&typeof e?.message==="string"){let p=n.classifyByMessage(e.message);if(p)return p}return n.fallback??"non_retryable"},resolveRetryAfterMs(t,n){if(n?.retryAfterMs){let e=n.retryAfterMs(t),i=x(e);if(i!==void 0)return i}if(t.retryAfterMs!==void 0)return x(t.retryAfterMs);if(t.code==="RATE_LIMIT_EXCEEDED"&&t.retryAfterMs===void 0)return;return},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 K(t.code,t.message,t.details,{...O.toRetryMetadata(t),attempt:P(n)})},DEFAULT_RETRYABLE_ERROR_CODES:yt,DEFAULT_NON_RETRYABLE_ERROR_CODES:ft};function Jt(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 M extends K{kind;fieldPath;failMode;openFallback;constructor(t,n,e,i={}){super(Jt(t),n,e,i);this.name="FieldCryptoError",this.kind=t,this.fieldPath=typeof i.fieldPath==="string"?i.fieldPath:void 0,this.failMode=i.failMode,this.openFallback=i.openFallback}toJSON(){return{...super.toJSON(),kind:this.kind,fieldPath:this.fieldPath,failMode:this.failMode,openFallback:this.openFallback}}}var Wt=["tenantId","providerId","messageId"];function _(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function Yt(t){if(typeof t!=="number"||!Number.isFinite(t))return;if(t<=0||t>100)return;return t}function Ct(t){let n=[];for(let e of t){let i=_(e.kid),r=Yt(e.percentage);if(!i||r===void 0)continue;n.push({kid:i,percentage:r})}return n}function jt(t,n,e){let i=n.map((r)=>{let s=t[r];return typeof s==="string"?s:""}).join("|");return`${e}::${i}`}function Qt(t){let n=2166136261;for(let e=0;e<t.length;e+=1)n^=t.charCodeAt(e),n=n*16777619>>>0;return n>>>0}function Zt(t,n){let e=0;for(let i of t)if(e+=i.percentage,n<e)return i.kid;return}function N(t,n,e){let i=Ct(n.buckets),r=_(n.defaultKid)??_(e);if(i.length===0)return r;let s=_(n.seed)??"kmsg-rollout-v1",p=n.stickyFields??Wt,f=jt(t,p,s),y=Qt(f)%100;return Zt(i,y)??r}function W(t){return Ct(t.buckets).map((n)=>n.kid)}function E(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function Y(t){if(!Array.isArray(t))return[];return t.map((n)=>E(n)).filter((n)=>Boolean(n))}function j(t){let n=[],e=new Set;for(let i of t){let r=E(i);if(!r||e.has(r))continue;e.add(r),n.push(r)}return n}function Lt(t){return E(t.providerId)??"default"}function Q(t){let n=E(t.activeKid)??"default",e=j([n,...Y(t.decryptKids)]);return{async resolveEncryptKey(){return{kid:n}},async resolveDecryptKeys(){return e}}}function v(t){let n=typeof t.cacheTtlMs==="number"&&t.cacheTtlMs>=0?Math.trunc(t.cacheTtlMs):30000,e=E(t.fallback?.activeKid),i=Y(t.fallback?.decryptKids),r;async function s(p){let f=Date.now();if(r&&f<r.expiresAt)return r.value;let y=await t.provider.loadKeySet(p),o=E(y.activeKid)??e??Lt(p),a=j([o,...Y(y.decryptKids),...i]),h={activeKid:o,decryptKids:a,refreshedAt:Date.now()};return r={value:h,expiresAt:Date.now()+n},h}return{async resolveEncryptKey(p){return{kid:(await s(p)).activeKid}},async resolveDecryptKeys(p){let f=await s(p);return f.decryptKids??[f.activeKid]}}}function Xt(t,n){return{async resolveEncryptKey(e){let i=await t.resolveEncryptKey(e);return{kid:N(e,n,i.kid)??i.kid}},async resolveDecryptKeys(e){let i=await t.resolveEncryptKey(e),r=t.resolveDecryptKeys?await t.resolveDecryptKeys(e):[i.kid],s=N(e,n,i.kid),p=W(n);return j([...s?[s]:[],i.kid,...r??[],...p])}}}function zt(t){return v({provider:{async loadKeySet(e){return t.client.getKeyState({...e,...t.keyAlias?{keyAlias:t.keyAlias}:{},...t.region?{region:t.region}:{}})}},cacheTtlMs:t.cacheTtlMs,fallback:{activeKid:t.fallbackActiveKid,decryptKids:t.fallbackDecryptKids}})}function I(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function Ft(t,n){return I(t[n])}function tn(t,n){if(!t)return[];return t.split(n).map((e)=>I(e)).filter((e)=>Boolean(e))}function nn(t={}){let n=globalThis.process?.env,e=t.env??n??{},i=I(t.delimiter)??",",r=t.activeKidEnv??"KMSG_ACTIVE_KID",s=t.decryptKidsEnv??"KMSG_DECRYPT_KIDS",p=Ft(e,r)??I(t.fallbackActiveKid)??"default",f=[p,...tn(Ft(e,s),i),...t.fallbackDecryptKids??[]];return Q({activeKid:p,decryptKids:f})}function en(t){return v({provider:{async loadKeySet(e){return t.client.getKeyState({...e,...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 Z(t){return typeof t==="function"}function At(t){if(typeof t!=="string")return;let n=t.trim();return n.length>0?n:void 0}function L(t,n,e){let i=t.fields[n];if(i)return i;if(n.startsWith("metadata.")){let r=t.fields["metadata.*"];if(r)return r}return e}function Pt(t,n={}){let e=[];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")e.push({message:"fieldCrypto provider is required",rule:"fieldCrypto.provider.required",path:"provider",hint:"Set provider with encrypt/decrypt/hash methods"});else{if(!Z(t.provider.encrypt))e.push({message:"provider.encrypt must be a function",rule:"fieldCrypto.provider.encrypt.required",path:"provider.encrypt"});if(!Z(t.provider.decrypt))e.push({message:"provider.decrypt must be a function",rule:"fieldCrypto.provider.decrypt.required",path:"provider.decrypt"});if(!Z(t.provider.hash))e.push({message:"provider.hash must be a function",rule:"fieldCrypto.provider.hash.required",path:"provider.hash"})}if(!t.fields||typeof t.fields!=="object")e.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)e.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[p,f]of s){if(!At(p))e.push({message:"field path must be a non-empty string",rule:"fieldCrypto.fields.path.non_empty",path:"fields"});if(f!=="plain"&&f!=="encrypt"&&f!=="encrypt+hash"&&f!=="mask")e.push({message:`unsupported field mode: ${String(f)}`,rule:"fieldCrypto.fields.mode.supported",path:`fields.${p}`})}}let i=t.failMode??"closed",r=t.openFallback??"masked";if(i==="open"&&r==="plaintext"&&t.unsafeAllowPlaintextStorage!==!0)e.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)e.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 p=t.aadFields[s];if(!At(p))e.push({message:"aadFields cannot include empty key",rule:"fieldCrypto.aad_fields.no_empty_key",path:`aadFields[${s}]`})}}if(n.secureMode&&!n.compatPlainColumns){let s=L(t,"to","encrypt+hash"),p=L(t,"from","encrypt+hash");if(s==="plain")e.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(p==="plain")e.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:e.length===0,issues:e}}function sn(t,n={}){let e=Pt(t,n);if(e.valid)return;let i=e.issues[0];if(!i)throw new M("config","fieldCrypto config validation failed",{rule:"fieldCrypto.config.invalid",issues:e.issues});throw new M("config",i.message,{rule:i.rule,path:i.path,hint:i.hint,issues:e.issues},{fieldPath:i.path})}function U(t){let n=t instanceof Uint8Array?t:new Uint8Array(t),e=typeof globalThis<"u"?globalThis.Buffer:void 0;return(e?e.from(n).toString("base64"):btoa(String.fromCharCode(...n))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function B(t){let n=t.replace(/-/g,"+").replace(/_/g,"/"),e=n.length%4===0?n:`${n}${"=".repeat(4-n.length%4)}`,i=typeof globalThis<"u"?globalThis.Buffer:void 0;if(i)return new Uint8Array(i.from(e,"base64"));let r=atob(e),s=new Uint8Array(r.length);for(let p=0;p<r.length;p+=1)s[p]=r.charCodeAt(p);return s}function wt(t,n){if(t instanceof Uint8Array)return t;if(t instanceof ArrayBuffer)return new Uint8Array(t);if(n==="base64url")return B(t);return new TextEncoder().encode(t)}function rn(t){let n=t instanceof Uint8Array?t:new Uint8Array(t);return Array.from(n).map((e)=>e.toString(16).padStart(2,"0")).join("")}function S(t){let n=new Uint8Array(t.byteLength);return n.set(t),n.buffer}function St(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 pn(t){if(typeof t==="string")return t;return JSON.stringify(t)}function yn(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 bt(t){let n=String(t??"").trim();if(n.length===0)return"";let e=n.startsWith("+"),i=n.replace(/\D/g,"");return e?`+${i}`:i}function X(t=3,n=2){return(e)=>{let i=String(e??"");if(i.length<=t+n)return"*".repeat(Math.max(0,i.length));let r=i.slice(0,t),s=i.slice(-n);return`${r}${"*".repeat(i.length-t-n)}${s}`}}function fn(t){let n=t.algorithm??"A256GCM",e=t.keyEncoding??"base64url",i=t.hashKeyEncoding??e,r=new Map,s=new Map,p=(y)=>{let o=r.get(y);if(o)return o;let a=t.keys[y];if(!a)throw Error(`Unknown encryption key id: ${y}`);let h=wt(a,e),d=crypto.subtle.importKey("raw",S(h),"AES-GCM",!1,["encrypt","decrypt"]);return r.set(y,d),d},f=(y)=>{let o=s.get(y);if(o)return o;let a=t.hashKeys?.[y]??t.keys[y];if(!a)throw Error(`Unknown hash key id: ${y}`);let h=wt(a,i),d=crypto.subtle.importKey("raw",S(h),{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return s.set(y,d),d};return{async encrypt(y){let o=y.kid??t.activeKid,a=await p(o),h=crypto.getRandomValues(new Uint8Array(12)),d=new TextEncoder().encode(JSON.stringify(y.aad??{})),A=new TextEncoder().encode(y.value),C=await crypto.subtle.encrypt({name:"AES-GCM",iv:S(h),additionalData:S(d),tagLength:128},a,S(A)),b=new Uint8Array(C),l=b.slice(b.length-16),c=b.slice(0,b.length-16);return{ciphertext:{v:1,alg:n,kid:o,iv:U(h),tag:U(l),ct:U(c)},kid:o}},async decrypt(y){let o=St(y.ciphertext),a=y.candidateKids&&y.candidateKids.length>0?y.candidateKids:[o.kid],h=B(o.iv),d=B(o.tag),A=B(o.ct),C=new Uint8Array(A.length+d.length);C.set(A,0),C.set(d,A.length);let b=new TextEncoder().encode(JSON.stringify(y.aad??{})),l;for(let c of a)try{let F=await p(c),g=await crypto.subtle.decrypt({name:"AES-GCM",iv:S(h),additionalData:S(b),tagLength:128},F,S(C));return new TextDecoder().decode(new Uint8Array(g))}catch(F){l=F}throw Error(`Failed to decrypt ciphertext: ${l instanceof Error?l.message:String(l??"unknown")}`)},async hash(y){let o=y.kid??t.activeKid,a=await f(o),h=await crypto.subtle.sign("HMAC",a,S(new TextEncoder().encode(y.value)));return rn(h)},mask(y){return X()(y.value)}}}function on(){return{encrypt(t){return{ciphertext:JSON.stringify({v:1,alg:"NOOP",kid:"noop",iv:"",tag:"",ct:t.value})}},decrypt(t){try{return St(t.ciphertext).ct}catch{return t.ciphertext}},hash(t){let n=bt(t.value);return U(new TextEncoder().encode(n))},mask(t){return X()(t.value)}}}function cn(t){return pn(t)}var ut;((r)=>{r.DEBUG="DEBUG";r.INFO="INFO";r.WARN="WARN";r.ERROR="ERROR"})(ut||={});var an=["to","from","phone","phoneNumber","recipient","sender","secret","apiKey","apiSecret","authorization","auth","token","password","payload","message","content","text"];function dn(t){let n=t.toLowerCase();return an.some((e)=>n.includes(e.toLowerCase()))}function ln(t){let n=t.trim();if(n.length<=4)return"***";if(n.includes("@")){let[r,s]=n.split("@");return`${r.slice(0,2)}${"*".repeat(Math.max(1,r.length-2))}@${s}`}let e=n.slice(0,3),i=n.slice(-2);return`${e}${"*".repeat(Math.max(1,n.length-5))}${i}`}function z(t,n){if(n===void 0||n===null)return n;if(dn(t)){if(typeof n==="string")return ln(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((e)=>z(t,e));if(typeof n==="object"){let e={};for(let[i,r]of Object.entries(n))e[i]=z(i,r);return e}return n}function hn(t){let n={};for(let[e,i]of Object.entries(t))n[e]=z(e,i);return n}class ${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=hn(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 e=t.timestamp.toISOString(),i=this.config.enableColors?this.colorizeLevel(t.level):t.level,r=Object.keys(n).length>0?` [${Object.entries(n).map(([p,f])=>`${p}=${f}`).join(", ")}]`:"",s=`${e} ${i}${r}: ${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={},e){this.writeLog({level:"WARN",message:t,timestamp:new Date,context:{...this.context,...n},error:e})}error(t,n={},e){this.writeLog({level:"ERROR",message:t,timestamp:new Date,context:{...this.context,...n},error:e})}child(t){return new $({...this.context,...t},this.config)}time(t){let n=Date.now();return()=>{let e=Date.now()-n;this.info(`${t} completed`,{duration:e})}}async measure(t,n,e={}){let i=Date.now(),r={...e,operation:t};this.debug(`Starting ${t}`,r);try{let s=await n(),p=Date.now()-i;return this.info(`Completed ${t}`,{...r,duration:p}),s}catch(s){let p=Date.now()-i;throw this.error(`Failed ${t}`,{...r,duration:p},s instanceof Error?s:Error(String(s))),s}}}var q;function tt(t,n){return new $(t,n)}function k(){if(!q)q=tt();return q}function gn(t){q=t}var Kn={debug:(t,n)=>k().debug(t,n),info:(t,n)=>k().info(t,n),warn:(t,n,e)=>k().warn(t,n,e),error:(t,n,e)=>k().error(t,n,e),child:(t)=>k().child(t),time:(t)=>k().time(t),measure:(t,n,e)=>k().measure(t,n,e)};function Cn(t){let n=tt({},t);return async(e,i)=>{let r=Date.now(),p={requestId:Math.random().toString(36).substring(7),method:e.req.method,path:e.req.path,userAgent:e.req.header("user-agent")||"unknown"};n.info("Request started",p);try{await i();let f=Date.now()-r;n.info("Request completed",{...p,status:e.res.status,duration:f})}catch(f){let y=Date.now()-r;throw n.error("Request failed",{...p,duration:y},f instanceof Error?f:Error(String(f))),f}}}class T{static defaultOptions={maxAttempts:3,initialDelay:1000,maxDelay:30000,backoffMultiplier:2,jitter:!0,retryCondition:(t)=>O.isRetryable(t)};static async execute(t,n={}){let e={...T.defaultOptions,...n},i,r=e.initialDelay;for(let s=1;s<=e.maxAttempts;s++)try{return await t()}catch(p){if(i=p,s===e.maxAttempts||!e.retryCondition(i,s))throw i;let f=e.jitter?r+Math.random()*r*0.1:r;e.onRetry?.(i,s),await new Promise((y)=>setTimeout(y,f)),r=Math.min(r*e.backoffMultiplier,e.maxDelay)}throw i}static createRetryableFunction(t,n={}){return async(...e)=>{return T.execute(()=>t(...e),n)}}}class H{static async execute(t,n,e={}){let i={concurrency:5,retryOptions:{maxAttempts:3,initialDelay:1000,maxDelay:1e4,backoffMultiplier:2,jitter:!0},failFast:!1,...e},r=Date.now(),s=[],p=[],f=0,y=T.createRetryableFunction(n,i.retryOptions),o=H.createBatches(t,i.concurrency);for(let h of o){let d=h.map(async(A)=>{try{let C=await y(A);s.push({item:A,result:C})}catch(C){if(p.push({item:A,error:C}),i.failFast)throw new K("MESSAGE_SEND_FAILED",`Bulk operation failed fast after ${p.length} failures`,{totalItems:t.length,failedCount:p.length})}finally{f++,i.onProgress?.(f,t.length,p.length)}});if(await Promise.allSettled(d),i.failFast&&p.length>0)break}let a=Date.now()-r;return{successful:s,failed:p,summary:{total:t.length,successful:s.length,failed:p.length,duration:a}}}static createBatches(t,n){let e=[];for(let i=0;i<t.length;i+=n)e.push(t.slice(i,i+n));return e}}class nt{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 K("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 e=await Promise.race([t(),new Promise((i,r)=>setTimeout(()=>r(new K("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 e}catch(e){throw this.recordFailure(),e}}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 et{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),e=this.windowMs-(t-n);if(e>0)return await new Promise((i)=>setTimeout(i,e)),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 it=(t)=>({isSuccess:!0,isFailure:!1,value:t}),st=(t)=>({isSuccess:!1,isFailure:!0,error:t}),Fn={map(t,n){if(t.isSuccess)return it(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 it(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 Dt(){let t=globalThis;return t.__K_MSG_ENV__??t.__ENV__??t.process?.env??{}}function An(t){let n=Dt()[t];if(typeof n==="string")return n;if(n===void 0)return;return String(n)}var kt=["PENDING","SENT","DELIVERED","FAILED","CANCELLED","UNKNOWN"],mt=["DELIVERED","FAILED","CANCELLED","UNKNOWN"],rt=["PENDING","SENT"],Pn=new Set(kt),Tt=new Set(mt),wn=new Set(rt);function Sn(t){return Pn.has(t)}function bn(t){return Tt.has(t)}function un(t){return Tt.has(t)}function Dn(t){return wn.has(t)}function kn(){return rt}var Ot=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS","NSA","VOICE","FAX","RCS_SMS","RCS_LMS","RCS_MMS","RCS_TPL","RCS_ITPL","RCS_LTPL"],mn=new Set(Ot);function Tn(t){return mn.has(t)}var On=["PENDING","SENT","FAILED"],Rt="PENDING",Rn=(t)=>{let n=typeof t==="string"?t.trim().toUpperCase():"";if(n==="PENDING"||n==="SENT"||n==="FAILED")return n;return Rt};
|
|
3
|
-
|
|
4
|
-
//# debugId=A5BAB2911583302264756E2164756E21
|
|
5
|
-
//# sourceMappingURL=index.js.map
|