@k-msg/core 0.23.1 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/crypto/key-adapters/aws-kms.d.ts +16 -0
- package/dist/crypto/key-adapters/env.d.ts +10 -0
- package/dist/crypto/key-adapters/vault-transit.d.ts +18 -0
- package/dist/crypto/key-resolver.d.ts +20 -0
- package/dist/crypto/rollout-policy.d.ts +26 -0
- package/dist/crypto/types.d.ts +21 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +3 -3
- package/dist/index.js.map +9 -4
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +9 -4
- package/package.json +1 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FieldCryptoKeyContext, KeyResolver, KeySetState } from "../types";
|
|
2
|
+
export interface AwsKmsKeyResolverClient {
|
|
3
|
+
getKeyState(context: FieldCryptoKeyContext & {
|
|
4
|
+
keyAlias?: string;
|
|
5
|
+
region?: string;
|
|
6
|
+
}): Promise<KeySetState>;
|
|
7
|
+
}
|
|
8
|
+
export interface AwsKmsKeyResolverOptions {
|
|
9
|
+
client: AwsKmsKeyResolverClient;
|
|
10
|
+
keyAlias?: string;
|
|
11
|
+
region?: string;
|
|
12
|
+
cacheTtlMs?: number;
|
|
13
|
+
fallbackActiveKid?: string;
|
|
14
|
+
fallbackDecryptKids?: readonly string[];
|
|
15
|
+
}
|
|
16
|
+
export declare function createAwsKmsKeyResolver(options: AwsKmsKeyResolverOptions): KeyResolver;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { KeyResolver } from "../types";
|
|
2
|
+
export interface EnvKeyResolverOptions {
|
|
3
|
+
env?: Record<string, string | undefined>;
|
|
4
|
+
activeKidEnv?: string;
|
|
5
|
+
decryptKidsEnv?: string;
|
|
6
|
+
fallbackActiveKid?: string;
|
|
7
|
+
fallbackDecryptKids?: readonly string[];
|
|
8
|
+
delimiter?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function createEnvKeyResolver(options?: EnvKeyResolverOptions): KeyResolver;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FieldCryptoKeyContext, KeyResolver, KeySetState } from "../types";
|
|
2
|
+
export interface VaultTransitKeyResolverClient {
|
|
3
|
+
getKeyState(context: FieldCryptoKeyContext & {
|
|
4
|
+
mountPath?: string;
|
|
5
|
+
keyName?: string;
|
|
6
|
+
namespace?: string;
|
|
7
|
+
}): Promise<KeySetState>;
|
|
8
|
+
}
|
|
9
|
+
export interface VaultTransitKeyResolverOptions {
|
|
10
|
+
client: VaultTransitKeyResolverClient;
|
|
11
|
+
mountPath?: string;
|
|
12
|
+
keyName?: string;
|
|
13
|
+
namespace?: string;
|
|
14
|
+
cacheTtlMs?: number;
|
|
15
|
+
fallbackActiveKid?: string;
|
|
16
|
+
fallbackDecryptKids?: readonly string[];
|
|
17
|
+
}
|
|
18
|
+
export declare function createVaultTransitKeyResolver(options: VaultTransitKeyResolverOptions): KeyResolver;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ActiveKidRolloutPolicy } from "./rollout-policy";
|
|
2
|
+
import type { FieldCryptoKeyContext, KeyResolver, KeySetState } from "./types";
|
|
3
|
+
export interface StaticKeyResolverOptions {
|
|
4
|
+
activeKid: string;
|
|
5
|
+
decryptKids?: readonly string[];
|
|
6
|
+
}
|
|
7
|
+
export interface KeySetStateProvider {
|
|
8
|
+
loadKeySet(context: FieldCryptoKeyContext): Promise<KeySetState>;
|
|
9
|
+
}
|
|
10
|
+
export interface RefreshableKeyResolverOptions {
|
|
11
|
+
provider: KeySetStateProvider;
|
|
12
|
+
cacheTtlMs?: number;
|
|
13
|
+
fallback?: {
|
|
14
|
+
activeKid?: string;
|
|
15
|
+
decryptKids?: readonly string[];
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export declare function createStaticKeyResolver(options: StaticKeyResolverOptions): KeyResolver;
|
|
19
|
+
export declare function createRefreshableKeyResolver(options: RefreshableKeyResolverOptions): KeyResolver;
|
|
20
|
+
export declare function createRollingKeyResolver(baseResolver: KeyResolver, policy: ActiveKidRolloutPolicy): KeyResolver;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { FieldCryptoKeyContext } from "./types";
|
|
2
|
+
export interface ActiveKidRolloutBucket {
|
|
3
|
+
kid: string;
|
|
4
|
+
percentage: number;
|
|
5
|
+
}
|
|
6
|
+
export interface ActiveKidRolloutPolicy {
|
|
7
|
+
/**
|
|
8
|
+
* Rollout targets in priority order.
|
|
9
|
+
* Example: [{ kid: "k-2026-02", percentage: 25 }]
|
|
10
|
+
*/
|
|
11
|
+
buckets: readonly ActiveKidRolloutBucket[];
|
|
12
|
+
/**
|
|
13
|
+
* Deterministic hash seed.
|
|
14
|
+
*/
|
|
15
|
+
seed?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Context keys used to build sticky rollout identity.
|
|
18
|
+
*/
|
|
19
|
+
stickyFields?: readonly (keyof FieldCryptoKeyContext)[];
|
|
20
|
+
/**
|
|
21
|
+
* Fallback kid when no bucket matches.
|
|
22
|
+
*/
|
|
23
|
+
defaultKid?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function selectActiveKidByRollout(context: FieldCryptoKeyContext, policy: ActiveKidRolloutPolicy, fallbackKid?: string): string | undefined;
|
|
26
|
+
export declare function getRolloutKnownKids(policy: ActiveKidRolloutPolicy): readonly string[];
|
package/dist/crypto/types.d.ts
CHANGED
|
@@ -21,6 +21,11 @@ export interface FieldCryptoKeyContext {
|
|
|
21
21
|
fieldPath?: string;
|
|
22
22
|
requestId?: string;
|
|
23
23
|
}
|
|
24
|
+
export interface KeySetState {
|
|
25
|
+
activeKid: string;
|
|
26
|
+
decryptKids?: readonly string[];
|
|
27
|
+
refreshedAt?: number;
|
|
28
|
+
}
|
|
24
29
|
export interface KeyResolver {
|
|
25
30
|
resolveEncryptKey(context: FieldCryptoKeyContext): MaybePromise<{
|
|
26
31
|
kid: string;
|
|
@@ -69,7 +74,22 @@ export interface FieldCryptoConfig {
|
|
|
69
74
|
keyResolver?: KeyResolver;
|
|
70
75
|
provider: FieldCryptoProvider;
|
|
71
76
|
}
|
|
72
|
-
export type FieldCryptoMetricName = "crypto_encrypt_ms" | "crypto_decrypt_ms" | "crypto_fail_count" | "key_kid_usage";
|
|
77
|
+
export type FieldCryptoMetricName = "crypto_encrypt_ms" | "crypto_decrypt_ms" | "crypto_fail_count" | "key_kid_usage" | "crypto_circuit_open_count" | "crypto_circuit_state";
|
|
78
|
+
export type FieldCryptoCircuitState = "closed" | "open" | "half-open";
|
|
79
|
+
export interface FieldCryptoControlScope {
|
|
80
|
+
tenantId?: string;
|
|
81
|
+
providerId?: string;
|
|
82
|
+
kid?: string;
|
|
83
|
+
}
|
|
84
|
+
export interface FieldCryptoControlSignalEvent {
|
|
85
|
+
state: FieldCryptoCircuitState;
|
|
86
|
+
reason: "threshold" | "cooldown" | "manual" | "recovered";
|
|
87
|
+
scope: string;
|
|
88
|
+
scopeParts: FieldCryptoControlScope;
|
|
89
|
+
operation: "encrypt" | "decrypt" | "hash";
|
|
90
|
+
at: number;
|
|
91
|
+
errorClass?: string;
|
|
92
|
+
}
|
|
73
93
|
export interface FieldCryptoMetricEvent {
|
|
74
94
|
name: FieldCryptoMetricName;
|
|
75
95
|
value?: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export * from "./crypto/errors";
|
|
2
|
+
export * from "./crypto/key-adapters/aws-kms";
|
|
3
|
+
export * from "./crypto/key-adapters/env";
|
|
4
|
+
export * from "./crypto/key-adapters/vault-transit";
|
|
5
|
+
export * from "./crypto/key-resolver";
|
|
2
6
|
export * from "./crypto/policy";
|
|
7
|
+
export * from "./crypto/rollout-policy";
|
|
3
8
|
export * from "./crypto/types";
|
|
4
9
|
export * from "./errors";
|
|
5
10
|
export * from "./logger";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var{defineProperty:S,getOwnPropertyNames:nt,getOwnPropertyDescriptor:rt}=Object,st=Object.prototype.hasOwnProperty;var G=new WeakMap,ot=(t)=>{var e=G.get(t),i;if(e)return e;if(e=S({},"__esModule",{value:!0}),t&&typeof t==="object"||typeof t==="function")nt(t).map((n)=>!st.call(e,n)&&S(e,n,{get:()=>t[n],enumerable:!(i=rt(t,n))||i.enumerable}));return G.set(t,e),e};var pt=(t,e)=>{for(var i in e)S(t,i,{get:e[i],enumerable:!0,configurable:!0,set:(n)=>e[i]=()=>n})};var Et={};pt(Et,{validateFieldCryptoConfig:()=>Z,toCiphertextEnvelopeString:()=>ut,setGlobalLogger:()=>bt,resolveFieldMode:()=>v,readRuntimeEnv:()=>xt,ok:()=>$,normalizeRetryAfterMs:()=>B,normalizePhoneForHash:()=>z,normalizeMessageStatus:()=>Mt,loggerMiddleware:()=>Pt,logger:()=>wt,isCryptoEnvelope:()=>lt,getRuntimeEnvSource:()=>et,getLogger:()=>F,fail:()=>j,createNoopFieldCryptoProvider:()=>yt,createLogger:()=>_,createDefaultMasker:()=>q,createAesGcmFieldCryptoProvider:()=>ht,assertFieldCryptoConfig:()=>dt,RetryHandler:()=>b,Result:()=>At,RateLimiter:()=>H,QUEUED_MESSAGE_STATUS:()=>Ot,Logger:()=>E,LogLevel:()=>tt,KNOWN_MESSAGE_STATUSES:()=>kt,KMsgErrorCode:()=>A,KMsgError:()=>y,FieldCryptoError:()=>x,ErrorUtils:()=>P,CircuitBreaker:()=>K,BulkOperationHandler:()=>T});module.exports=ot(Et);var A;((a)=>{a.INVALID_REQUEST="INVALID_REQUEST";a.AUTHENTICATION_FAILED="AUTHENTICATION_FAILED";a.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE";a.TEMPLATE_NOT_FOUND="TEMPLATE_NOT_FOUND";a.RATE_LIMIT_EXCEEDED="RATE_LIMIT_EXCEEDED";a.NETWORK_ERROR="NETWORK_ERROR";a.NETWORK_TIMEOUT="NETWORK_TIMEOUT";a.NETWORK_SERVICE_UNAVAILABLE="NETWORK_SERVICE_UNAVAILABLE";a.PROVIDER_ERROR="PROVIDER_ERROR";a.MESSAGE_SEND_FAILED="MESSAGE_SEND_FAILED";a.CRYPTO_CONFIG_ERROR="CRYPTO_CONFIG_ERROR";a.CRYPTO_ENCRYPT_FAILED="CRYPTO_ENCRYPT_FAILED";a.CRYPTO_DECRYPT_FAILED="CRYPTO_DECRYPT_FAILED";a.CRYPTO_HASH_FAILED="CRYPTO_HASH_FAILED";a.CRYPTO_POLICY_VIOLATION="CRYPTO_POLICY_VIOLATION";a.UNKNOWN_ERROR="UNKNOWN_ERROR"})(A||={});var J=new Set(["NETWORK_ERROR","RATE_LIMIT_EXCEEDED","NETWORK_TIMEOUT","NETWORK_SERVICE_UNAVAILABLE","PROVIDER_ERROR","UNKNOWN_ERROR"]),Y=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"]),g=(t)=>{if(typeof t!=="number"||Number.isNaN(t)||!Number.isFinite(t))return;return Math.trunc(t)},B=(t)=>{let e=g(t);if(e===void 0||e<0)return;return e},I=(t)=>{if(typeof t!=="string")return;return t.toLowerCase().trim()},W=(t)=>{if(t>=500)return"retryable";if(t===408||t===425||t===429)return"retryable";return"non_retryable"},Q=(t)=>{let e=t.toLowerCase();if(e.includes("timeout")||e.includes("temporar")||e.includes("network")||e.includes("retry"))return"retryable";return};class y extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(t,e,i,n={}){super(e);if(this.name="KMsgError",this.code=t,this.details=i,this.providerErrorCode=n.providerErrorCode,this.providerErrorText=n.providerErrorText,this.httpStatus=g(n.httpStatus),this.requestId=typeof n.requestId==="string"?n.requestId:void 0,this.retryAfterMs=g(n.retryAfterMs),this.attempt=g(n.attempt),Array.isArray(n.causeChain))this.causeChain=n.causeChain;else if(n.causeChain!==void 0)this.causeChain=[n.causeChain];if(Error.captureStackTrace)Error.captureStackTrace(this,y)}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 P={isRetryable(t,e={}){return P.classifyForRetry(t,e)==="retryable"},classifyForRetry(t,e={}){if(t instanceof y){if(new Set(e.retryableCodes??Array.from(J)).has(t.code))return"retryable";if(new Set(e.nonRetryableCodes??Array.from(Y)).has(t.code))return"non_retryable";if(t.httpStatus!==void 0)return W(t.httpStatus);let p=Q(t.message);if(p)return p;if(e.classifyByMessage&&t.message){let c=e.classifyByMessage(t.message);if(c)return c}if(e.fallback)return e.fallback;return"non_retryable"}let i=t&&typeof t==="object"?t:void 0,n=I(i?.status)??I(i?.statusCode)??I(i?.code),r=g(i?.status)??g(i?.statusCode)??g(i?.httpStatus);if(typeof n==="string"&&n.startsWith("5"))return"retryable";if(r!==void 0){if(e.classifyByStatusCode)return e.classifyByStatusCode(r);return W(r)}let s=typeof i?.message==="string"?Q(i.message):void 0;if(s)return s;if(e.classifyByMessage&&typeof i?.message==="string"){let o=e.classifyByMessage(i.message);if(o)return o}return e.fallback??"non_retryable"},resolveRetryAfterMs(t,e){if(e?.retryAfterMs){let i=e.retryAfterMs(t),n=B(i);if(n!==void 0)return n}if(t.retryAfterMs!==void 0)return B(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,e){return new y(t.code,t.message,t.details,{...P.toRetryMetadata(t),attempt:g(e)})},DEFAULT_RETRYABLE_ERROR_CODES:J,DEFAULT_NON_RETRYABLE_ERROR_CODES:Y};function at(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 x extends y{kind;fieldPath;failMode;openFallback;constructor(t,e,i,n={}){super(at(t),e,i,n);this.name="FieldCryptoError",this.kind=t,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}}}function U(t){return typeof t==="function"}function V(t){if(typeof t!=="string")return;let e=t.trim();return e.length>0?e:void 0}function v(t,e,i){let n=t.fields[e];if(n)return n;if(e.startsWith("metadata.")){let r=t.fields["metadata.*"];if(r)return r}return i}function Z(t,e={}){let i=[];if(!t||typeof t!=="object")return{valid:!1,issues:[{message:"fieldCrypto config must be an object",rule:"fieldCrypto.config.object",hint:"Provide a valid FieldCryptoConfig object"}]};if(!t.provider||typeof t.provider!=="object")i.push({message:"fieldCrypto provider is required",rule:"fieldCrypto.provider.required",path:"provider",hint:"Set provider with encrypt/decrypt/hash methods"});else{if(!U(t.provider.encrypt))i.push({message:"provider.encrypt must be a function",rule:"fieldCrypto.provider.encrypt.required",path:"provider.encrypt"});if(!U(t.provider.decrypt))i.push({message:"provider.decrypt must be a function",rule:"fieldCrypto.provider.decrypt.required",path:"provider.decrypt"});if(!U(t.provider.hash))i.push({message:"provider.hash must be a function",rule:"fieldCrypto.provider.hash.required",path:"provider.hash"})}if(!t.fields||typeof t.fields!=="object")i.push({message:"fieldCrypto.fields must be an object",rule:"fieldCrypto.fields.object",path:"fields",hint:"Define policies such as to, from, metadata.phoneNumber"});else{let s=Object.entries(t.fields);if(s.length===0)i.push({message:"fieldCrypto.fields must not be empty",rule:"fieldCrypto.fields.non_empty",path:"fields",hint:"Add at least one field mode mapping"});for(let[o,d]of s){if(!V(o))i.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")i.push({message:`unsupported field mode: ${String(d)}`,rule:"fieldCrypto.fields.mode.supported",path:`fields.${o}`})}}let n=t.failMode??"closed",r=t.openFallback??"masked";if(n==="open"&&r==="plaintext"&&t.unsafeAllowPlaintextStorage!==!0)i.push({message:"openFallback=plaintext requires unsafeAllowPlaintextStorage=true",rule:"fieldCrypto.fail_open.plaintext_guard",path:"openFallback",hint:"Use masked/null fallback, or explicitly enable unsafe plaintext"});if(Array.isArray(t.aadFields)){if(t.aadFields.length===0)i.push({message:"aadFields must not be empty when provided",rule:"fieldCrypto.aad_fields.non_empty",path:"aadFields"});for(let s=0;s<t.aadFields.length;s+=1){let o=t.aadFields[s];if(!V(o))i.push({message:"aadFields cannot include empty key",rule:"fieldCrypto.aad_fields.no_empty_key",path:`aadFields[${s}]`})}}if(e.secureMode&&!e.compatPlainColumns){let s=v(t,"to","encrypt+hash"),o=v(t,"from","encrypt+hash");if(s==="plain")i.push({message:"secure mode requires non-plain policy for `to` when compatPlainColumns=false",rule:"fieldCrypto.secure_mode.to_non_plain",path:"fields.to",hint:"Use encrypt+hash for lookup fields"});if(o==="plain")i.push({message:"secure mode requires non-plain policy for `from` when compatPlainColumns=false",rule:"fieldCrypto.secure_mode.from_non_plain",path:"fields.from",hint:"Use encrypt+hash for lookup fields"})}return{valid:i.length===0,issues:i}}function dt(t,e={}){let i=Z(t,e);if(i.valid)return;let n=i.issues[0];if(!n)throw new x("config","fieldCrypto config validation failed",{rule:"fieldCrypto.config.invalid",issues:i.issues});throw new x("config",n.message,{rule:n.rule,path:n.path,hint:n.hint,issues:i.issues},{fieldPath:n.path})}function k(t){let e=t instanceof Uint8Array?t:new Uint8Array(t),i=typeof globalThis<"u"?globalThis.Buffer:void 0;return(i?i.from(e).toString("base64"):btoa(String.fromCharCode(...e))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function O(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),i=e.length%4===0?e:`${e}${"=".repeat(4-e.length%4)}`,n=typeof globalThis<"u"?globalThis.Buffer:void 0;if(n)return new Uint8Array(n.from(i,"base64"));let r=atob(i),s=new Uint8Array(r.length);for(let o=0;o<r.length;o+=1)s[o]=r.charCodeAt(o);return s}function X(t,e){if(t instanceof Uint8Array)return t;if(t instanceof ArrayBuffer)return new Uint8Array(t);if(e==="base64url")return O(t);return new TextEncoder().encode(t)}function ct(t){let e=t instanceof Uint8Array?t:new Uint8Array(t);return Array.from(e).map((i)=>i.toString(16).padStart(2,"0")).join("")}function C(t){let e=new Uint8Array(t.byteLength);return e.set(t),e.buffer}function L(t){let e=JSON.parse(t);if(!e||typeof e!=="object"||typeof e.v!=="number"||typeof e.alg!=="string"||typeof e.kid!=="string"||typeof e.iv!=="string"||typeof e.tag!=="string"||typeof e.ct!=="string")throw Error("Invalid ciphertext envelope");return e}function ft(t){if(typeof t==="string")return t;return JSON.stringify(t)}function lt(t){if(!t||typeof t!=="object")return!1;let e=t;return typeof e.v==="number"&&typeof e.alg==="string"&&typeof e.kid==="string"&&typeof e.iv==="string"&&typeof e.tag==="string"&&typeof e.ct==="string"}function z(t){let e=String(t??"").trim();if(e.length===0)return"";let i=e.startsWith("+"),n=e.replace(/\D/g,"");return i?`+${n}`:n}function q(t=3,e=2){return(i)=>{let n=String(i??"");if(n.length<=t+e)return"*".repeat(Math.max(0,n.length));let r=n.slice(0,t),s=n.slice(-e);return`${r}${"*".repeat(n.length-t-e)}${s}`}}function ht(t){let e=t.algorithm??"A256GCM",i=t.keyEncoding??"base64url",n=t.hashKeyEncoding??i,r=new Map,s=new Map,o=(p)=>{let c=r.get(p);if(c)return c;let f=t.keys[p];if(!f)throw Error(`Unknown encryption key id: ${p}`);let l=X(f,i),h=crypto.subtle.importKey("raw",C(l),"AES-GCM",!1,["encrypt","decrypt"]);return r.set(p,h),h},d=(p)=>{let c=s.get(p);if(c)return c;let f=t.hashKeys?.[p]??t.keys[p];if(!f)throw Error(`Unknown hash key id: ${p}`);let l=X(f,n),h=crypto.subtle.importKey("raw",C(l),{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return s.set(p,h),h};return{async encrypt(p){let c=p.kid??t.activeKid,f=await o(c),l=crypto.getRandomValues(new Uint8Array(12)),h=new TextEncoder().encode(JSON.stringify(p.aad??{})),u=new TextEncoder().encode(p.value),m=await crypto.subtle.encrypt({name:"AES-GCM",iv:C(l),additionalData:C(h),tagLength:128},f,C(u)),w=new Uint8Array(m),a=w.slice(w.length-16),D=w.slice(0,w.length-16);return{ciphertext:{v:1,alg:e,kid:c,iv:k(l),tag:k(a),ct:k(D)},kid:c}},async decrypt(p){let c=L(p.ciphertext),f=p.candidateKids&&p.candidateKids.length>0?p.candidateKids:[c.kid],l=O(c.iv),h=O(c.tag),u=O(c.ct),m=new Uint8Array(u.length+h.length);m.set(u,0),m.set(h,u.length);let w=new TextEncoder().encode(JSON.stringify(p.aad??{})),a;for(let D of f)try{let R=await o(D),it=await crypto.subtle.decrypt({name:"AES-GCM",iv:C(l),additionalData:C(w),tagLength:128},R,C(m));return new TextDecoder().decode(new Uint8Array(it))}catch(R){a=R}throw Error(`Failed to decrypt ciphertext: ${a instanceof Error?a.message:String(a??"unknown")}`)},async hash(p){let c=p.kid??t.activeKid,f=await d(c),l=await crypto.subtle.sign("HMAC",f,C(new TextEncoder().encode(p.value)));return ct(l)},mask(p){return q()(p.value)}}}function yt(){return{encrypt(t){return{ciphertext:JSON.stringify({v:1,alg:"NOOP",kid:"noop",iv:"",tag:"",ct:t.value})}},decrypt(t){try{return L(t.ciphertext).ct}catch{return t.ciphertext}},hash(t){let e=z(t.value);return k(new TextEncoder().encode(e))},mask(t){return q()(t.value)}}}function ut(t){return ft(t)}var tt;((r)=>{r.DEBUG="DEBUG";r.INFO="INFO";r.WARN="WARN";r.ERROR="ERROR"})(tt||={});var mt=["to","from","phone","phoneNumber","recipient","sender","secret","apiKey","apiSecret","authorization","auth","token","password","payload","message","content","text"];function Ct(t){let e=t.toLowerCase();return mt.some((i)=>e.includes(i.toLowerCase()))}function gt(t){let e=t.trim();if(e.length<=4)return"***";if(e.includes("@")){let[r,s]=e.split("@");return`${r.slice(0,2)}${"*".repeat(Math.max(1,r.length-2))}@${s}`}let i=e.slice(0,3),n=e.slice(-2);return`${i}${"*".repeat(Math.max(1,e.length-5))}${n}`}function N(t,e){if(e===void 0||e===null)return e;if(Ct(t)){if(typeof e==="string")return gt(e);if(typeof e==="number"||typeof e==="boolean")return"***";if(Array.isArray(e))return"[REDACTED]";if(typeof e==="object")return"[REDACTED]"}if(Array.isArray(e))return e.map((i)=>N(t,i));if(typeof e==="object"){let i={};for(let[n,r]of Object.entries(e))i[n]=N(n,r);return i}return e}function Ft(t){let e={};for(let[i,n]of Object.entries(t))e[i]=N(i,n);return e}class E{config;context;constructor(t={},e={}){this.context=t,this.config={level:"INFO",enableConsole:!0,enableJson:!1,enableColors:!0,...e}}shouldLog(t){let e=["DEBUG","INFO","WARN","ERROR"];return e.indexOf(t)>=e.indexOf(this.config.level)}formatMessage(t){let e=Ft(t.context);if(this.config.enableJson)return JSON.stringify({level:t.level,message:t.message,timestamp:t.timestamp.toISOString(),context:e,...t.error&&{error:{name:t.error.name,message:t.error.message,stack:t.error.stack}},...t.duration&&{duration:t.duration}});let i=t.timestamp.toISOString(),n=this.config.enableColors?this.colorizeLevel(t.level):t.level,r=Object.keys(e).length>0?` [${Object.entries(e).map(([o,d])=>`${o}=${d}`).join(", ")}]`:"",s=`${i} ${n}${r}: ${t.message}`;if(t.duration!==void 0)s+=` (${t.duration}ms)`;if(t.error)s+=`
|
|
2
|
-
${
|
|
1
|
+
var{defineProperty:B,getOwnPropertyNames:ue,getOwnPropertyDescriptor:he}=Object,me=Object.prototype.hasOwnProperty;var z=new WeakMap,ge=(e)=>{var t=z.get(e),r;if(t)return t;if(t=B({},"__esModule",{value:!0}),e&&typeof e==="object"||typeof e==="function")ue(e).map((i)=>!me.call(t,i)&&B(t,i,{get:()=>e[i],enumerable:!(r=he(e,i))||r.enumerable}));return z.set(e,t),t};var Ce=(e,t)=>{for(var r in t)B(e,r,{get:t[r],enumerable:!0,configurable:!0,set:(i)=>t[r]=()=>i})};var Ze={};Ce(Ze,{validateFieldCryptoConfig:()=>ae,toCiphertextEnvelopeString:()=>Be,setGlobalLogger:()=>$e,selectActiveKidByRollout:()=>R,resolveFieldMode:()=>J,readRuntimeEnv:()=>Ve,ok:()=>X,normalizeRetryAfterMs:()=>U,normalizePhoneForHash:()=>de,normalizeMessageStatus:()=>Qe,loggerMiddleware:()=>Ge,logger:()=>je,isCryptoEnvelope:()=>De,getRuntimeEnvSource:()=>ye,getRolloutKnownKids:()=>q,getLogger:()=>K,fail:()=>L,createVaultTransitKeyResolver:()=>Oe,createStaticKeyResolver:()=>j,createRollingKeyResolver:()=>Se,createRefreshableKeyResolver:()=>S,createNoopFieldCryptoProvider:()=>_e,createLogger:()=>W,createEnvKeyResolver:()=>xe,createDefaultMasker:()=>V,createAwsKmsKeyResolver:()=>ke,createAesGcmFieldCryptoProvider:()=>Ie,assertFieldCryptoConfig:()=>Me,RetryHandler:()=>F,Result:()=>Je,RateLimiter:()=>Z,QUEUED_MESSAGE_STATUS:()=>We,Logger:()=>T,LogLevel:()=>le,KNOWN_MESSAGE_STATUSES:()=>Ye,KMsgErrorCode:()=>A,KMsgError:()=>u,FieldCryptoError:()=>P,ErrorUtils:()=>v,CircuitBreaker:()=>Q,BulkOperationHandler:()=>D});module.exports=ge(Ze);var A;((d)=>{d.INVALID_REQUEST="INVALID_REQUEST";d.AUTHENTICATION_FAILED="AUTHENTICATION_FAILED";d.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE";d.TEMPLATE_NOT_FOUND="TEMPLATE_NOT_FOUND";d.RATE_LIMIT_EXCEEDED="RATE_LIMIT_EXCEEDED";d.NETWORK_ERROR="NETWORK_ERROR";d.NETWORK_TIMEOUT="NETWORK_TIMEOUT";d.NETWORK_SERVICE_UNAVAILABLE="NETWORK_SERVICE_UNAVAILABLE";d.PROVIDER_ERROR="PROVIDER_ERROR";d.MESSAGE_SEND_FAILED="MESSAGE_SEND_FAILED";d.CRYPTO_CONFIG_ERROR="CRYPTO_CONFIG_ERROR";d.CRYPTO_ENCRYPT_FAILED="CRYPTO_ENCRYPT_FAILED";d.CRYPTO_DECRYPT_FAILED="CRYPTO_DECRYPT_FAILED";d.CRYPTO_HASH_FAILED="CRYPTO_HASH_FAILED";d.CRYPTO_POLICY_VIOLATION="CRYPTO_POLICY_VIOLATION";d.UNKNOWN_ERROR="UNKNOWN_ERROR"})(A||={});var 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","CRYPTO_CONFIG_ERROR","CRYPTO_ENCRYPT_FAILED","CRYPTO_DECRYPT_FAILED","CRYPTO_HASH_FAILED","CRYPTO_POLICY_VIOLATION"]),C=(e)=>{if(typeof e!=="number"||Number.isNaN(e)||!Number.isFinite(e))return;return Math.trunc(e)},U=(e)=>{let t=C(e);if(t===void 0||t<0)return;return t},N=(e)=>{if(typeof e!=="string")return;return e.toLowerCase().trim()},re=(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 u extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(e,t,r,i={}){super(t);if(this.name="KMsgError",this.code=e,this.details=r,this.providerErrorCode=i.providerErrorCode,this.providerErrorText=i.providerErrorText,this.httpStatus=C(i.httpStatus),this.requestId=typeof i.requestId==="string"?i.requestId:void 0,this.retryAfterMs=C(i.retryAfterMs),this.attempt=C(i.attempt),Array.isArray(i.causeChain))this.causeChain=i.causeChain;else if(i.causeChain!==void 0)this.causeChain=[i.causeChain];if(Error.captureStackTrace)Error.captureStackTrace(this,u)}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 v={isRetryable(e,t={}){return v.classifyForRetry(e,t)==="retryable"},classifyForRetry(e,t={}){if(e instanceof u){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 re(e.httpStatus);let a=ie(e.message);if(a)return a;if(t.classifyByMessage&&e.message){let c=t.classifyByMessage(e.message);if(c)return c}if(t.fallback)return t.fallback;return"non_retryable"}let r=e&&typeof e==="object"?e:void 0,i=N(r?.status)??N(r?.statusCode)??N(r?.code),n=C(r?.status)??C(r?.statusCode)??C(r?.httpStatus);if(typeof i==="string"&&i.startsWith("5"))return"retryable";if(n!==void 0){if(t.classifyByStatusCode)return t.classifyByStatusCode(n);return re(n)}let s=typeof r?.message==="string"?ie(r.message):void 0;if(s)return s;if(t.classifyByMessage&&typeof r?.message==="string"){let o=t.classifyByMessage(r.message);if(o)return o}return t.fallback??"non_retryable"},resolveRetryAfterMs(e,t){if(t?.retryAfterMs){let r=t.retryAfterMs(e),i=U(r);if(i!==void 0)return i}if(e.retryAfterMs!==void 0)return U(e.retryAfterMs);if(e.code==="RATE_LIMIT_EXCEEDED"&&e.retryAfterMs===void 0)return;return},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 u(e.code,e.message,e.details,{...v.toRetryMetadata(e),attempt:C(t)})},DEFAULT_RETRYABLE_ERROR_CODES:ee,DEFAULT_NON_RETRYABLE_ERROR_CODES:te};function Ke(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 P extends u{kind;fieldPath;failMode;openFallback;constructor(e,t,r,i={}){super(Ke(e),t,r,i);this.name="FieldCryptoError",this.kind=e,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 Fe=["tenantId","providerId","messageId"];function k(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function be(e){if(typeof e!=="number"||!Number.isFinite(e))return;if(e<=0||e>100)return;return e}function ne(e){let t=[];for(let r of e){let i=k(r.kid),n=be(r.percentage);if(!i||n===void 0)continue;t.push({kid:i,percentage:n})}return t}function we(e,t,r){let i=t.map((n)=>{let s=e[n];return typeof s==="string"?s:""}).join("|");return`${r}::${i}`}function ve(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 Ae(e,t){let r=0;for(let i of e)if(r+=i.percentage,t<r)return i.kid;return}function R(e,t,r){let i=ne(t.buckets),n=k(t.defaultKid)??k(r);if(i.length===0)return n;let s=k(t.seed)??"kmsg-rollout-v1",o=t.stickyFields??Fe,p=we(e,o,s),a=ve(p)%100;return Ae(i,a)??n}function q(e){return ne(e.buckets).map((t)=>t.kid)}function w(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function H(e){if(!Array.isArray(e))return[];return e.map((t)=>w(t)).filter((t)=>Boolean(t))}function $(e){let t=[],r=new Set;for(let i of e){let n=w(i);if(!n||r.has(n))continue;r.add(n),t.push(n)}return t}function Pe(e){return w(e.providerId)??"default"}function j(e){let t=w(e.activeKid)??"default",r=$([t,...H(e.decryptKids)]);return{async resolveEncryptKey(){return{kid:t}},async resolveDecryptKeys(){return r}}}function S(e){let t=typeof e.cacheTtlMs==="number"&&e.cacheTtlMs>=0?Math.trunc(e.cacheTtlMs):30000,r=w(e.fallback?.activeKid),i=H(e.fallback?.decryptKids),n;async function s(o){let p=Date.now();if(n&&p<n.expiresAt)return n.value;let a=await e.provider.loadKeySet(o),c=w(a.activeKid)??r??Pe(o),l=$([c,...H(a.decryptKids),...i]),y={activeKid:c,decryptKids:l,refreshedAt:Date.now()};return n={value:y,expiresAt:Date.now()+t},y}return{async resolveEncryptKey(o){return{kid:(await s(o)).activeKid}},async resolveDecryptKeys(o){let p=await s(o);return p.decryptKids??[p.activeKid]}}}function Se(e,t){return{async resolveEncryptKey(r){let i=await e.resolveEncryptKey(r);return{kid:R(r,t,i.kid)??i.kid}},async resolveDecryptKeys(r){let i=await e.resolveEncryptKey(r),n=e.resolveDecryptKeys?await e.resolveDecryptKeys(r):[i.kid],s=R(r,t,i.kid),o=q(t);return $([...s?[s]:[],i.kid,...n??[],...o])}}}function ke(e){return S({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 x(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function se(e,t){return x(e[t])}function Re(e,t){if(!e)return[];return e.split(t).map((r)=>x(r)).filter((r)=>Boolean(r))}function xe(e={}){let t=e.env??(typeof process<"u"?process.env:{}),r=x(e.delimiter)??",",i=e.activeKidEnv??"KMSG_ACTIVE_KID",n=e.decryptKidsEnv??"KMSG_DECRYPT_KIDS",s=se(t,i)??x(e.fallbackActiveKid)??"default",o=[s,...Re(se(t,n),r),...e.fallbackDecryptKids??[]];return j({activeKid:s,decryptKids:o})}function Oe(e){return S({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 G(e){return typeof e==="function"}function oe(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function J(e,t,r){let i=e.fields[t];if(i)return i;if(t.startsWith("metadata.")){let n=e.fields["metadata.*"];if(n)return n}return r}function ae(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(!G(e.provider.encrypt))r.push({message:"provider.encrypt must be a function",rule:"fieldCrypto.provider.encrypt.required",path:"provider.encrypt"});if(!G(e.provider.decrypt))r.push({message:"provider.decrypt must be a function",rule:"fieldCrypto.provider.decrypt.required",path:"provider.decrypt"});if(!G(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 s=Object.entries(e.fields);if(s.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[o,p]of s){if(!oe(o))r.push({message:"field path must be a non-empty string",rule:"fieldCrypto.fields.path.non_empty",path:"fields"});if(p!=="plain"&&p!=="encrypt"&&p!=="encrypt+hash"&&p!=="mask")r.push({message:`unsupported field mode: ${String(p)}`,rule:"fieldCrypto.fields.mode.supported",path:`fields.${o}`})}}let i=e.failMode??"closed",n=e.openFallback??"masked";if(i==="open"&&n==="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 s=0;s<e.aadFields.length;s+=1){let o=e.aadFields[s];if(!oe(o))r.push({message:"aadFields cannot include empty key",rule:"fieldCrypto.aad_fields.no_empty_key",path:`aadFields[${s}]`})}}if(t.secureMode&&!t.compatPlainColumns){let s=J(e,"to","encrypt+hash"),o=J(e,"from","encrypt+hash");if(s==="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(o==="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 Me(e,t={}){let r=ae(e,t);if(r.valid)return;let i=r.issues[0];if(!i)throw new P("config","fieldCrypto config validation failed",{rule:"fieldCrypto.config.invalid",issues:r.issues});throw new P("config",i.message,{rule:i.rule,path:i.path,hint:i.hint,issues:r.issues},{fieldPath:i.path})}function O(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 M(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),r=t.length%4===0?t:`${t}${"=".repeat(4-t.length%4)}`,i=typeof globalThis<"u"?globalThis.Buffer:void 0;if(i)return new Uint8Array(i.from(r,"base64"));let n=atob(r),s=new Uint8Array(n.length);for(let o=0;o<n.length;o+=1)s[o]=n.charCodeAt(o);return s}function pe(e,t){if(e instanceof Uint8Array)return e;if(e instanceof ArrayBuffer)return new Uint8Array(e);if(t==="base64url")return M(e);return new TextEncoder().encode(e)}function Ee(e){let t=e instanceof Uint8Array?e:new Uint8Array(e);return Array.from(t).map((r)=>r.toString(16).padStart(2,"0")).join("")}function g(e){let t=new Uint8Array(e.byteLength);return t.set(e),t.buffer}function ce(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 Te(e){if(typeof e==="string")return e;return JSON.stringify(e)}function De(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 de(e){let t=String(e??"").trim();if(t.length===0)return"";let r=t.startsWith("+"),i=t.replace(/\D/g,"");return r?`+${i}`:i}function V(e=3,t=2){return(r)=>{let i=String(r??"");if(i.length<=e+t)return"*".repeat(Math.max(0,i.length));let n=i.slice(0,e),s=i.slice(-t);return`${n}${"*".repeat(i.length-e-t)}${s}`}}function Ie(e){let t=e.algorithm??"A256GCM",r=e.keyEncoding??"base64url",i=e.hashKeyEncoding??r,n=new Map,s=new Map,o=(a)=>{let c=n.get(a);if(c)return c;let l=e.keys[a];if(!l)throw Error(`Unknown encryption key id: ${a}`);let y=pe(l,r),f=crypto.subtle.importKey("raw",g(y),"AES-GCM",!1,["encrypt","decrypt"]);return n.set(a,f),f},p=(a)=>{let c=s.get(a);if(c)return c;let l=e.hashKeys?.[a]??e.keys[a];if(!l)throw Error(`Unknown hash key id: ${a}`);let y=pe(l,i),f=crypto.subtle.importKey("raw",g(y),{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return s.set(a,f),f};return{async encrypt(a){let c=a.kid??e.activeKid,l=await o(c),y=crypto.getRandomValues(new Uint8Array(12)),f=new TextEncoder().encode(JSON.stringify(a.aad??{})),h=new TextEncoder().encode(a.value),m=await crypto.subtle.encrypt({name:"AES-GCM",iv:g(y),additionalData:g(f),tagLength:128},l,g(h)),b=new Uint8Array(m),d=b.slice(b.length-16),I=b.slice(0,b.length-16);return{ciphertext:{v:1,alg:t,kid:c,iv:O(y),tag:O(d),ct:O(I)},kid:c}},async decrypt(a){let c=ce(a.ciphertext),l=a.candidateKids&&a.candidateKids.length>0?a.candidateKids:[c.kid],y=M(c.iv),f=M(c.tag),h=M(c.ct),m=new Uint8Array(h.length+f.length);m.set(h,0),m.set(f,h.length);let b=new TextEncoder().encode(JSON.stringify(a.aad??{})),d;for(let I of l)try{let _=await o(I),fe=await crypto.subtle.decrypt({name:"AES-GCM",iv:g(y),additionalData:g(b),tagLength:128},_,g(m));return new TextDecoder().decode(new Uint8Array(fe))}catch(_){d=_}throw Error(`Failed to decrypt ciphertext: ${d instanceof Error?d.message:String(d??"unknown")}`)},async hash(a){let c=a.kid??e.activeKid,l=await p(c),y=await crypto.subtle.sign("HMAC",l,g(new TextEncoder().encode(a.value)));return Ee(y)},mask(a){return V()(a.value)}}}function _e(){return{encrypt(e){return{ciphertext:JSON.stringify({v:1,alg:"NOOP",kid:"noop",iv:"",tag:"",ct:e.value})}},decrypt(e){try{return ce(e.ciphertext).ct}catch{return e.ciphertext}},hash(e){let t=de(e.value);return O(new TextEncoder().encode(t))},mask(e){return V()(e.value)}}}function Be(e){return Te(e)}var le;((n)=>{n.DEBUG="DEBUG";n.INFO="INFO";n.WARN="WARN";n.ERROR="ERROR"})(le||={});var Ne=["to","from","phone","phoneNumber","recipient","sender","secret","apiKey","apiSecret","authorization","auth","token","password","payload","message","content","text"];function Ue(e){let t=e.toLowerCase();return Ne.some((r)=>t.includes(r.toLowerCase()))}function qe(e){let t=e.trim();if(t.length<=4)return"***";if(t.includes("@")){let[n,s]=t.split("@");return`${n.slice(0,2)}${"*".repeat(Math.max(1,n.length-2))}@${s}`}let r=t.slice(0,3),i=t.slice(-2);return`${r}${"*".repeat(Math.max(1,t.length-5))}${i}`}function Y(e,t){if(t===void 0||t===null)return t;if(Ue(e)){if(typeof t==="string")return qe(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)=>Y(e,r));if(typeof t==="object"){let r={};for(let[i,n]of Object.entries(t))r[i]=Y(i,n);return r}return t}function He(e){let t={};for(let[r,i]of Object.entries(e))t[r]=Y(r,i);return t}class T{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=He(e.context);if(this.config.enableJson)return JSON.stringify({level:e.level,message:e.message,timestamp:e.timestamp.toISOString(),context:t,...e.error&&{error:{name:e.error.name,message:e.error.message,stack:e.error.stack}},...e.duration&&{duration:e.duration}});let r=e.timestamp.toISOString(),i=this.config.enableColors?this.colorizeLevel(e.level):e.level,n=Object.keys(t).length>0?` [${Object.entries(t).map(([o,p])=>`${o}=${p}`).join(", ")}]`:"",s=`${r} ${i}${n}: ${e.message}`;if(e.duration!==void 0)s+=` (${e.duration}ms)`;if(e.error)s+=`
|
|
2
|
+
${e.error.stack}`;return s}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 T({...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 i=Date.now(),n={...r,operation:e};this.debug(`Starting ${e}`,n);try{let s=await t(),o=Date.now()-i;return this.info(`Completed ${e}`,{...n,duration:o}),s}catch(s){let o=Date.now()-i;throw this.error(`Failed ${e}`,{...n,duration:o},s instanceof Error?s:Error(String(s))),s}}}var E;function W(e,t){return new T(e,t)}function K(){if(!E)E=W();return E}function $e(e){E=e}var je={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 Ge(e){let t=W({},e);return async(r,i)=>{let n=Date.now(),o={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",o);try{await i();let p=Date.now()-n;t.info("Request completed",{...o,status:r.res.status,duration:p})}catch(p){let a=Date.now()-n;throw t.error("Request failed",{...o,duration:a},p instanceof Error?p:Error(String(p))),p}}}class F{static defaultOptions={maxAttempts:3,initialDelay:1000,maxDelay:30000,backoffMultiplier:2,jitter:!0,retryCondition:(e)=>v.isRetryable(e)};static async execute(e,t={}){let r={...F.defaultOptions,...t},i,n=r.initialDelay;for(let s=1;s<=r.maxAttempts;s++)try{return await e()}catch(o){if(i=o,s===r.maxAttempts||!r.retryCondition(i,s))throw i;let p=r.jitter?n+Math.random()*n*0.1:n;r.onRetry?.(i,s),await new Promise((a)=>setTimeout(a,p)),n=Math.min(n*r.backoffMultiplier,r.maxDelay)}throw i}static createRetryableFunction(e,t={}){return async(...r)=>{return F.execute(()=>e(...r),t)}}}class D{static async execute(e,t,r={}){let i={concurrency:5,retryOptions:{maxAttempts:3,initialDelay:1000,maxDelay:1e4,backoffMultiplier:2,jitter:!0},failFast:!1,...r},n=Date.now(),s=[],o=[],p=0,a=F.createRetryableFunction(t,i.retryOptions),c=D.createBatches(e,i.concurrency);for(let y of c){let f=y.map(async(h)=>{try{let m=await a(h);s.push({item:h,result:m})}catch(m){if(o.push({item:h,error:m}),i.failFast)throw new u("MESSAGE_SEND_FAILED",`Bulk operation failed fast after ${o.length} failures`,{totalItems:e.length,failedCount:o.length})}finally{p++,i.onProgress?.(p,e.length,o.length)}});if(await Promise.allSettled(f),i.failFast&&o.length>0)break}let l=Date.now()-n;return{successful:s,failed:o,summary:{total:e.length,successful:s.length,failed:o.length,duration:l}}}static createBatches(e,t){let r=[];for(let i=0;i<e.length;i+=t)r.push(e.slice(i,i+t));return r}}class Q{options;state="CLOSED";failureCount=0;lastFailureTime=0;nextAttemptTime=0;constructor(e){this.options=e}async execute(e){let t=Date.now();switch(this.state){case"OPEN":if(t<this.nextAttemptTime)throw new u("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 r=await Promise.race([e(),new Promise((i,n)=>setTimeout(()=>n(new u("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 r}catch(r){throw this.recordFailure(),r}}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 Z{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((i)=>setTimeout(i,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 X=(e)=>({isSuccess:!0,isFailure:!1,value:e}),L=(e)=>({isSuccess:!1,isFailure:!0,error:e}),Je={map(e,t){if(e.isSuccess)return X(t(e.value));return e},flatMap(e,t){if(e.isSuccess)return t(e.value);return e},mapError(e,t){if(e.isFailure)return L(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 X(t)}catch(t){return L(t)}},isOk(e){return e.isSuccess},isFail(e){return e.isFailure}};function ye(){let e=globalThis;return e.__K_MSG_ENV__??e.__ENV__??e.process?.env??{}}function Ve(e){let t=ye()[e];if(typeof t==="string")return t;if(t===void 0)return;return String(t)}var Ye=["PENDING","SENT","FAILED"],We="PENDING",Qe=(e)=>{let t=typeof e==="string"?e.trim().toUpperCase():"";if(t==="PENDING"||t==="SENT"||t==="FAILED")return t;return"PENDING"};
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
4
|
+
//# debugId=1C61B1E21374481464756E2164756E21
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/errors.ts", "../src/crypto/errors.ts", "../src/crypto/policy.ts", "../src/crypto/types.ts", "../src/logger.ts", "../src/resilience/retry-handler.ts", "../src/resilience/bulk-operation.ts", "../src/resilience/circuit-breaker.ts", "../src/resilience/rate-limiter.ts", "../src/result.ts", "../src/runtime/env.ts", "../src/types/message.ts"],
|
|
3
|
+
"sources": ["../src/errors.ts", "../src/crypto/errors.ts", "../src/crypto/rollout-policy.ts", "../src/crypto/key-resolver.ts", "../src/crypto/key-adapters/aws-kms.ts", "../src/crypto/key-adapters/env.ts", "../src/crypto/key-adapters/vault-transit.ts", "../src/crypto/policy.ts", "../src/crypto/types.ts", "../src/logger.ts", "../src/resilience/retry-handler.ts", "../src/resilience/bulk-operation.ts", "../src/resilience/circuit-breaker.ts", "../src/resilience/rate-limiter.ts", "../src/result.ts", "../src/runtime/env.ts", "../src/types/message.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"export enum KMsgErrorCode {\n INVALID_REQUEST = \"INVALID_REQUEST\",\n AUTHENTICATION_FAILED = \"AUTHENTICATION_FAILED\",\n INSUFFICIENT_BALANCE = \"INSUFFICIENT_BALANCE\",\n TEMPLATE_NOT_FOUND = \"TEMPLATE_NOT_FOUND\",\n RATE_LIMIT_EXCEEDED = \"RATE_LIMIT_EXCEEDED\",\n NETWORK_ERROR = \"NETWORK_ERROR\",\n NETWORK_TIMEOUT = \"NETWORK_TIMEOUT\",\n NETWORK_SERVICE_UNAVAILABLE = \"NETWORK_SERVICE_UNAVAILABLE\",\n PROVIDER_ERROR = \"PROVIDER_ERROR\",\n MESSAGE_SEND_FAILED = \"MESSAGE_SEND_FAILED\",\n CRYPTO_CONFIG_ERROR = \"CRYPTO_CONFIG_ERROR\",\n CRYPTO_ENCRYPT_FAILED = \"CRYPTO_ENCRYPT_FAILED\",\n CRYPTO_DECRYPT_FAILED = \"CRYPTO_DECRYPT_FAILED\",\n CRYPTO_HASH_FAILED = \"CRYPTO_HASH_FAILED\",\n CRYPTO_POLICY_VIOLATION = \"CRYPTO_POLICY_VIOLATION\",\n UNKNOWN_ERROR = \"UNKNOWN_ERROR\",\n}\n\nexport type RetryPolicyErrorCode = KMsgErrorCode;\n\nexport type ProviderRetryHint = \"retryable\" | \"non_retryable\";\n\nexport interface KMsgErrorMetadata {\n providerErrorCode?: string;\n providerErrorText?: string;\n httpStatus?: number;\n requestId?: string;\n retryAfterMs?: number;\n attempt?: number;\n causeChain?: unknown[];\n}\n\nexport interface ErrorRetryPolicy {\n retryableCodes?: readonly KMsgErrorCode[];\n nonRetryableCodes?: readonly KMsgErrorCode[];\n classifyByStatusCode?: (status: number) => ProviderRetryHint;\n classifyByMessage?: (message: string) => ProviderRetryHint | undefined;\n /**\n * Optional override for retry hint inference.\n */\n fallback?: ProviderRetryHint;\n /**\n * Optional custom retry delay in milliseconds.\n */\n retryAfterMs?: (error: KMsgError) => number | undefined;\n}\n\nconst DEFAULT_RETRYABLE_ERROR_CODES: ReadonlySet<RetryPolicyErrorCode> =\n new Set([\n KMsgErrorCode.NETWORK_ERROR,\n KMsgErrorCode.RATE_LIMIT_EXCEEDED,\n KMsgErrorCode.NETWORK_TIMEOUT,\n KMsgErrorCode.NETWORK_SERVICE_UNAVAILABLE,\n KMsgErrorCode.PROVIDER_ERROR,\n KMsgErrorCode.UNKNOWN_ERROR,\n ]);\n\nconst DEFAULT_NON_RETRYABLE_ERROR_CODES: ReadonlySet<RetryPolicyErrorCode> =\n new Set([\n KMsgErrorCode.INVALID_REQUEST,\n KMsgErrorCode.AUTHENTICATION_FAILED,\n KMsgErrorCode.INSUFFICIENT_BALANCE,\n KMsgErrorCode.TEMPLATE_NOT_FOUND,\n KMsgErrorCode.MESSAGE_SEND_FAILED,\n KMsgErrorCode.CRYPTO_CONFIG_ERROR,\n KMsgErrorCode.CRYPTO_ENCRYPT_FAILED,\n KMsgErrorCode.CRYPTO_DECRYPT_FAILED,\n KMsgErrorCode.CRYPTO_HASH_FAILED,\n KMsgErrorCode.CRYPTO_POLICY_VIOLATION,\n ]);\n\nconst normalizeNumber = (value: unknown): number | undefined => {\n if (\n typeof value !== \"number\" ||\n Number.isNaN(value) ||\n !Number.isFinite(value)\n ) {\n return undefined;\n }\n\n return Math.trunc(value);\n};\n\nexport const normalizeRetryAfterMs = (value: unknown): number | undefined => {\n const normalized = normalizeNumber(value);\n if (normalized === undefined || normalized < 0) {\n return undefined;\n }\n\n return normalized;\n};\n\nconst toLowerString = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n return value.toLowerCase().trim();\n};\n\nconst classifyByHttpStatus = (status: number): ProviderRetryHint => {\n if (status >= 500) {\n return \"retryable\";\n }\n\n if (status === 408 || status === 425 || status === 429) {\n return \"retryable\";\n }\n\n return \"non_retryable\";\n};\n\nconst classifyByMessage = (message: string): ProviderRetryHint | undefined => {\n const normalized = message.toLowerCase();\n\n if (\n normalized.includes(\"timeout\") ||\n normalized.includes(\"temporar\") ||\n normalized.includes(\"network\") ||\n normalized.includes(\"retry\")\n ) {\n return \"retryable\";\n }\n\n return undefined;\n};\n\nexport class KMsgError extends Error {\n public readonly code: KMsgErrorCode;\n public readonly details?: Record<string, unknown>;\n public readonly providerErrorCode?: string;\n public readonly providerErrorText?: string;\n public readonly httpStatus?: number;\n public readonly requestId?: string;\n public readonly retryAfterMs?: number;\n public readonly attempt?: number;\n public readonly causeChain?: unknown[];\n\n constructor(\n code: KMsgErrorCode,\n message: string,\n details?: Record<string, unknown>,\n metadata: KMsgErrorMetadata = {},\n ) {\n super(message);\n this.name = \"KMsgError\";\n this.code = code;\n this.details = details;\n\n this.providerErrorCode = metadata.providerErrorCode;\n this.providerErrorText = metadata.providerErrorText;\n this.httpStatus = normalizeNumber(metadata.httpStatus);\n this.requestId =\n typeof metadata.requestId === \"string\" ? metadata.requestId : undefined;\n this.retryAfterMs = normalizeNumber(metadata.retryAfterMs);\n this.attempt = normalizeNumber(metadata.attempt);\n\n if (Array.isArray(metadata.causeChain)) {\n this.causeChain = metadata.causeChain;\n } else if (metadata.causeChain !== undefined) {\n this.causeChain = [metadata.causeChain];\n }\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, KMsgError);\n }\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n details: this.details,\n providerErrorCode: this.providerErrorCode,\n providerErrorText: this.providerErrorText,\n httpStatus: this.httpStatus,\n requestId: this.requestId,\n retryAfterMs: this.retryAfterMs,\n attempt: this.attempt,\n causeChain: this.causeChain,\n };\n }\n}\n\nexport const ErrorUtils = {\n isRetryable(error: unknown, policy: ErrorRetryPolicy = {}): boolean {\n return ErrorUtils.classifyForRetry(error, policy) === \"retryable\";\n },\n\n classifyForRetry(\n error: unknown,\n policy: ErrorRetryPolicy = {},\n ): ProviderRetryHint {\n if (error instanceof KMsgError) {\n const retryableCodes = new Set(\n policy.retryableCodes ?? Array.from(DEFAULT_RETRYABLE_ERROR_CODES),\n );\n if (retryableCodes.has(error.code)) {\n return \"retryable\";\n }\n\n const nonRetryableCodes = new Set(\n policy.nonRetryableCodes ??\n Array.from(DEFAULT_NON_RETRYABLE_ERROR_CODES),\n );\n if (nonRetryableCodes.has(error.code)) {\n return \"non_retryable\";\n }\n\n if (error.httpStatus !== undefined) {\n return classifyByHttpStatus(error.httpStatus);\n }\n\n const classifiedByMessage = classifyByMessage(error.message);\n if (classifiedByMessage) {\n return classifiedByMessage;\n }\n\n if (policy.classifyByMessage && error.message) {\n const classified = policy.classifyByMessage(error.message);\n if (classified) {\n return classified;\n }\n }\n\n if (policy.fallback) {\n return policy.fallback;\n }\n\n return \"non_retryable\";\n }\n\n const candidate =\n error && typeof error === \"object\"\n ? (error as {\n status?: unknown;\n statusCode?: unknown;\n httpStatus?: unknown;\n code?: unknown;\n message?: unknown;\n })\n : undefined;\n\n const status =\n toLowerString(candidate?.status) ??\n toLowerString(candidate?.statusCode) ??\n toLowerString(candidate?.code);\n const statusCode =\n normalizeNumber(candidate?.status) ??\n normalizeNumber(candidate?.statusCode) ??\n normalizeNumber(candidate?.httpStatus);\n\n if (typeof status === \"string\" && status.startsWith(\"5\")) {\n return \"retryable\";\n }\n\n if (statusCode !== undefined) {\n if (policy.classifyByStatusCode) {\n return policy.classifyByStatusCode(statusCode);\n }\n\n return classifyByHttpStatus(statusCode);\n }\n\n const classifiedByMessage =\n typeof candidate?.message === \"string\"\n ? classifyByMessage(candidate.message)\n : undefined;\n\n if (classifiedByMessage) {\n return classifiedByMessage;\n }\n\n if (policy.classifyByMessage && typeof candidate?.message === \"string\") {\n const classified = policy.classifyByMessage(candidate.message);\n if (classified) {\n return classified;\n }\n }\n\n return policy.fallback ?? \"non_retryable\";\n },\n\n resolveRetryAfterMs(\n error: KMsgError,\n policy?: ErrorRetryPolicy,\n ): number | undefined {\n if (policy?.retryAfterMs) {\n const override = policy.retryAfterMs(error);\n const normalized = normalizeRetryAfterMs(override);\n if (normalized !== undefined) {\n return normalized;\n }\n }\n\n if (error.retryAfterMs !== undefined) {\n return normalizeRetryAfterMs(error.retryAfterMs);\n }\n\n if (\n error.code === KMsgErrorCode.RATE_LIMIT_EXCEEDED &&\n error.retryAfterMs === undefined\n ) {\n return undefined;\n }\n\n return undefined;\n },\n\n isUnknownStatus: (statusCode: number | undefined): boolean => {\n if (\n statusCode === undefined ||\n Number.isNaN(statusCode) ||\n !Number.isFinite(statusCode)\n ) {\n return false;\n }\n\n return statusCode < 500;\n },\n\n toRetryMetadata(error: KMsgError): KMsgErrorMetadata {\n return {\n providerErrorCode: error.providerErrorCode,\n providerErrorText: error.providerErrorText,\n httpStatus: error.httpStatus,\n requestId: error.requestId,\n retryAfterMs: error.retryAfterMs,\n attempt: error.attempt,\n causeChain: error.causeChain,\n };\n },\n\n withAttempt(error: KMsgError, attempt: number): KMsgError {\n return new KMsgError(error.code, error.message, error.details, {\n ...ErrorUtils.toRetryMetadata(error),\n attempt: normalizeNumber(attempt),\n });\n },\n\n DEFAULT_RETRYABLE_ERROR_CODES,\n DEFAULT_NON_RETRYABLE_ERROR_CODES,\n};\n",
|
|
6
6
|
"import { KMsgError, KMsgErrorCode, type KMsgErrorMetadata } from \"../errors\";\nimport type { FieldCryptoFailMode, FieldCryptoOpenFallback } from \"./types\";\n\nexport type FieldCryptoErrorKind =\n | \"config\"\n | \"encrypt\"\n | \"decrypt\"\n | \"hash\"\n | \"policy\";\n\nfunction resolveCode(kind: FieldCryptoErrorKind): KMsgErrorCode {\n switch (kind) {\n case \"config\":\n return KMsgErrorCode.CRYPTO_CONFIG_ERROR;\n case \"encrypt\":\n return KMsgErrorCode.CRYPTO_ENCRYPT_FAILED;\n case \"decrypt\":\n return KMsgErrorCode.CRYPTO_DECRYPT_FAILED;\n case \"hash\":\n return KMsgErrorCode.CRYPTO_HASH_FAILED;\n case \"policy\":\n return KMsgErrorCode.CRYPTO_POLICY_VIOLATION;\n }\n}\n\nexport interface FieldCryptoErrorMetadata extends KMsgErrorMetadata {\n fieldPath?: string;\n failMode?: FieldCryptoFailMode;\n openFallback?: FieldCryptoOpenFallback;\n}\n\nexport class FieldCryptoError extends KMsgError {\n readonly kind: FieldCryptoErrorKind;\n readonly fieldPath?: string;\n readonly failMode?: FieldCryptoFailMode;\n readonly openFallback?: FieldCryptoOpenFallback;\n\n constructor(\n kind: FieldCryptoErrorKind,\n message: string,\n details?: Record<string, unknown>,\n metadata: FieldCryptoErrorMetadata = {},\n ) {\n super(resolveCode(kind), message, details, metadata);\n this.name = \"FieldCryptoError\";\n this.kind = kind;\n this.fieldPath =\n typeof metadata.fieldPath === \"string\" ? metadata.fieldPath : undefined;\n this.failMode = metadata.failMode;\n this.openFallback = metadata.openFallback;\n }\n\n override toJSON() {\n return {\n ...super.toJSON(),\n kind: this.kind,\n fieldPath: this.fieldPath,\n failMode: this.failMode,\n openFallback: this.openFallback,\n };\n }\n}\n",
|
|
7
|
+
"import type { FieldCryptoKeyContext } from \"./types\";\n\nexport interface ActiveKidRolloutBucket {\n kid: string;\n percentage: number;\n}\n\nexport interface ActiveKidRolloutPolicy {\n /**\n * Rollout targets in priority order.\n * Example: [{ kid: \"k-2026-02\", percentage: 25 }]\n */\n buckets: readonly ActiveKidRolloutBucket[];\n /**\n * Deterministic hash seed.\n */\n seed?: string;\n /**\n * Context keys used to build sticky rollout identity.\n */\n stickyFields?: readonly (keyof FieldCryptoKeyContext)[];\n /**\n * Fallback kid when no bucket matches.\n */\n defaultKid?: string;\n}\n\nconst DEFAULT_STICKY_FIELDS: readonly (keyof FieldCryptoKeyContext)[] = [\n \"tenantId\",\n \"providerId\",\n \"messageId\",\n];\n\nfunction normalizeKid(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction toUnitPercentage(value: unknown): number | undefined {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return undefined;\n if (value <= 0 || value > 100) return undefined;\n return value;\n}\n\nfunction sanitizeBuckets(\n buckets: readonly ActiveKidRolloutBucket[],\n): ActiveKidRolloutBucket[] {\n const next: ActiveKidRolloutBucket[] = [];\n for (const bucket of buckets) {\n const kid = normalizeKid(bucket.kid);\n const percentage = toUnitPercentage(bucket.percentage);\n if (!kid || percentage === undefined) continue;\n next.push({ kid, percentage });\n }\n return next;\n}\n\nfunction toStickyKey(\n context: FieldCryptoKeyContext,\n fields: readonly (keyof FieldCryptoKeyContext)[],\n seed: string,\n): string {\n const payload = fields\n .map((field) => {\n const value = context[field];\n return typeof value === \"string\" ? value : \"\";\n })\n .join(\"|\");\n return `${seed}::${payload}`;\n}\n\n/**\n * Deterministic FNV-1a 32-bit hash.\n */\nfunction hash32(input: string): number {\n let hash = 0x811c9dc5;\n for (let index = 0; index < input.length; index += 1) {\n hash ^= input.charCodeAt(index);\n hash = (hash * 0x01000193) >>> 0;\n }\n return hash >>> 0;\n}\n\nfunction resolveBucketKid(\n buckets: readonly ActiveKidRolloutBucket[],\n percentile: number,\n): string | undefined {\n let cursor = 0;\n for (const bucket of buckets) {\n cursor += bucket.percentage;\n if (percentile < cursor) {\n return bucket.kid;\n }\n }\n return undefined;\n}\n\nexport function selectActiveKidByRollout(\n context: FieldCryptoKeyContext,\n policy: ActiveKidRolloutPolicy,\n fallbackKid?: string,\n): string | undefined {\n const buckets = sanitizeBuckets(policy.buckets);\n const defaultKid =\n normalizeKid(policy.defaultKid) ?? normalizeKid(fallbackKid);\n\n if (buckets.length === 0) {\n return defaultKid;\n }\n\n const seed = normalizeKid(policy.seed) ?? \"kmsg-rollout-v1\";\n const stickyFields = policy.stickyFields ?? DEFAULT_STICKY_FIELDS;\n const stickyKey = toStickyKey(context, stickyFields, seed);\n const percentile = hash32(stickyKey) % 100;\n return resolveBucketKid(buckets, percentile) ?? defaultKid;\n}\n\nexport function getRolloutKnownKids(\n policy: ActiveKidRolloutPolicy,\n): readonly string[] {\n return sanitizeBuckets(policy.buckets).map((bucket) => bucket.kid);\n}\n",
|
|
8
|
+
"import {\n type ActiveKidRolloutPolicy,\n getRolloutKnownKids,\n selectActiveKidByRollout,\n} from \"./rollout-policy\";\nimport type { FieldCryptoKeyContext, KeyResolver, KeySetState } from \"./types\";\n\nexport interface StaticKeyResolverOptions {\n activeKid: string;\n decryptKids?: readonly string[];\n}\n\nexport interface KeySetStateProvider {\n loadKeySet(context: FieldCryptoKeyContext): Promise<KeySetState>;\n}\n\nexport interface RefreshableKeyResolverOptions {\n provider: KeySetStateProvider;\n cacheTtlMs?: number;\n fallback?: {\n activeKid?: string;\n decryptKids?: readonly string[];\n };\n}\n\ninterface CachedKeySetState {\n value: KeySetState;\n expiresAt: number;\n}\n\nfunction normalizeKid(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction normalizeKidList(value: readonly string[] | undefined): string[] {\n if (!Array.isArray(value)) return [];\n return value\n .map((kid) => normalizeKid(kid))\n .filter((kid): kid is string => Boolean(kid));\n}\n\nfunction dedupeKids(values: readonly string[]): string[] {\n const next: string[] = [];\n const seen = new Set<string>();\n for (const value of values) {\n const normalized = normalizeKid(value);\n if (!normalized || seen.has(normalized)) continue;\n seen.add(normalized);\n next.push(normalized);\n }\n return next;\n}\n\nfunction fallbackKidFromContext(context: FieldCryptoKeyContext): string {\n return normalizeKid(context.providerId) ?? \"default\";\n}\n\nexport function createStaticKeyResolver(\n options: StaticKeyResolverOptions,\n): KeyResolver {\n const activeKid = normalizeKid(options.activeKid) ?? \"default\";\n const decryptKids = dedupeKids([\n activeKid,\n ...normalizeKidList(options.decryptKids),\n ]);\n\n return {\n async resolveEncryptKey() {\n return { kid: activeKid };\n },\n async resolveDecryptKeys() {\n return decryptKids;\n },\n };\n}\n\nexport function createRefreshableKeyResolver(\n options: RefreshableKeyResolverOptions,\n): KeyResolver {\n const cacheTtlMs =\n typeof options.cacheTtlMs === \"number\" && options.cacheTtlMs >= 0\n ? Math.trunc(options.cacheTtlMs)\n : 30_000;\n\n const fallbackActiveKid = normalizeKid(options.fallback?.activeKid);\n const fallbackDecryptKids = normalizeKidList(options.fallback?.decryptKids);\n let cache: CachedKeySetState | undefined;\n\n async function load(context: FieldCryptoKeyContext): Promise<KeySetState> {\n const now = Date.now();\n if (cache && now < cache.expiresAt) {\n return cache.value;\n }\n\n const loaded = await options.provider.loadKeySet(context);\n const activeKid =\n normalizeKid(loaded.activeKid) ??\n fallbackActiveKid ??\n fallbackKidFromContext(context);\n\n const decryptKids = dedupeKids([\n activeKid,\n ...normalizeKidList(loaded.decryptKids),\n ...fallbackDecryptKids,\n ]);\n\n const next: KeySetState = {\n activeKid,\n decryptKids,\n refreshedAt: Date.now(),\n };\n cache = {\n value: next,\n expiresAt: Date.now() + cacheTtlMs,\n };\n return next;\n }\n\n return {\n async resolveEncryptKey(context) {\n const state = await load(context);\n return { kid: state.activeKid };\n },\n async resolveDecryptKeys(context) {\n const state = await load(context);\n return state.decryptKids ?? [state.activeKid];\n },\n };\n}\n\nexport function createRollingKeyResolver(\n baseResolver: KeyResolver,\n policy: ActiveKidRolloutPolicy,\n): KeyResolver {\n return {\n async resolveEncryptKey(context) {\n const base = await baseResolver.resolveEncryptKey(context);\n const selected = selectActiveKidByRollout(context, policy, base.kid);\n return {\n kid: selected ?? base.kid,\n };\n },\n async resolveDecryptKeys(context) {\n const baseEncrypt = await baseResolver.resolveEncryptKey(context);\n const baseDecrypt = baseResolver.resolveDecryptKeys\n ? await baseResolver.resolveDecryptKeys(context)\n : [baseEncrypt.kid];\n const selected = selectActiveKidByRollout(\n context,\n policy,\n baseEncrypt.kid,\n );\n const rolloutKids = getRolloutKnownKids(policy);\n\n return dedupeKids([\n ...(selected ? [selected] : []),\n baseEncrypt.kid,\n ...(baseDecrypt ?? []),\n ...rolloutKids,\n ]);\n },\n };\n}\n",
|
|
9
|
+
"import {\n createRefreshableKeyResolver,\n type KeySetStateProvider,\n} from \"../key-resolver\";\nimport type { FieldCryptoKeyContext, KeyResolver, KeySetState } from \"../types\";\n\nexport interface AwsKmsKeyResolverClient {\n getKeyState(\n context: FieldCryptoKeyContext & {\n keyAlias?: string;\n region?: string;\n },\n ): Promise<KeySetState>;\n}\n\nexport interface AwsKmsKeyResolverOptions {\n client: AwsKmsKeyResolverClient;\n keyAlias?: string;\n region?: string;\n cacheTtlMs?: number;\n fallbackActiveKid?: string;\n fallbackDecryptKids?: readonly string[];\n}\n\nexport function createAwsKmsKeyResolver(\n options: AwsKmsKeyResolverOptions,\n): KeyResolver {\n const provider: KeySetStateProvider = {\n async loadKeySet(context) {\n return options.client.getKeyState({\n ...context,\n ...(options.keyAlias ? { keyAlias: options.keyAlias } : {}),\n ...(options.region ? { region: options.region } : {}),\n });\n },\n };\n\n return createRefreshableKeyResolver({\n provider,\n cacheTtlMs: options.cacheTtlMs,\n fallback: {\n activeKid: options.fallbackActiveKid,\n decryptKids: options.fallbackDecryptKids,\n },\n });\n}\n",
|
|
10
|
+
"import { createStaticKeyResolver } from \"../key-resolver\";\nimport type { KeyResolver } from \"../types\";\n\nexport interface EnvKeyResolverOptions {\n env?: Record<string, string | undefined>;\n activeKidEnv?: string;\n decryptKidsEnv?: string;\n fallbackActiveKid?: string;\n fallbackDecryptKids?: readonly string[];\n delimiter?: string;\n}\n\nfunction normalize(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction resolveEnv(\n env: Record<string, string | undefined>,\n key: string,\n): string | undefined {\n return normalize(env[key]);\n}\n\nfunction parseKids(raw: string | undefined, delimiter: string): string[] {\n if (!raw) return [];\n return raw\n .split(delimiter)\n .map((item) => normalize(item))\n .filter((item): item is string => Boolean(item));\n}\n\nexport function createEnvKeyResolver(\n options: EnvKeyResolverOptions = {},\n): KeyResolver {\n const envSource =\n options.env ??\n ((typeof process !== \"undefined\" ? process.env : {}) as Record<\n string,\n string | undefined\n >);\n const delimiter = normalize(options.delimiter) ?? \",\";\n const activeKidEnv = options.activeKidEnv ?? \"KMSG_ACTIVE_KID\";\n const decryptKidsEnv = options.decryptKidsEnv ?? \"KMSG_DECRYPT_KIDS\";\n\n const activeKid =\n resolveEnv(envSource, activeKidEnv) ??\n normalize(options.fallbackActiveKid) ??\n \"default\";\n const decryptKids = [\n activeKid,\n ...parseKids(resolveEnv(envSource, decryptKidsEnv), delimiter),\n ...(options.fallbackDecryptKids ?? []),\n ];\n\n return createStaticKeyResolver({\n activeKid,\n decryptKids,\n });\n}\n",
|
|
11
|
+
"import {\n createRefreshableKeyResolver,\n type KeySetStateProvider,\n} from \"../key-resolver\";\nimport type { FieldCryptoKeyContext, KeyResolver, KeySetState } from \"../types\";\n\nexport interface VaultTransitKeyResolverClient {\n getKeyState(\n context: FieldCryptoKeyContext & {\n mountPath?: string;\n keyName?: string;\n namespace?: string;\n },\n ): Promise<KeySetState>;\n}\n\nexport interface VaultTransitKeyResolverOptions {\n client: VaultTransitKeyResolverClient;\n mountPath?: string;\n keyName?: string;\n namespace?: string;\n cacheTtlMs?: number;\n fallbackActiveKid?: string;\n fallbackDecryptKids?: readonly string[];\n}\n\nexport function createVaultTransitKeyResolver(\n options: VaultTransitKeyResolverOptions,\n): KeyResolver {\n const provider: KeySetStateProvider = {\n async loadKeySet(context) {\n return options.client.getKeyState({\n ...context,\n ...(options.mountPath ? { mountPath: options.mountPath } : {}),\n ...(options.keyName ? { keyName: options.keyName } : {}),\n ...(options.namespace ? { namespace: options.namespace } : {}),\n });\n },\n };\n\n return createRefreshableKeyResolver({\n provider,\n cacheTtlMs: options.cacheTtlMs,\n fallback: {\n activeKid: options.fallbackActiveKid,\n decryptKids: options.fallbackDecryptKids,\n },\n });\n}\n",
|
|
7
12
|
"import { FieldCryptoError } from \"./errors\";\nimport type { FieldCryptoConfig, FieldMode } from \"./types\";\n\nexport interface FieldCryptoPolicyValidationIssue {\n message: string;\n rule: string;\n path?: string;\n hint?: string;\n}\n\nexport interface FieldCryptoPolicyOptions {\n secureMode?: boolean;\n compatPlainColumns?: boolean;\n}\n\nexport interface FieldCryptoPolicyValidationResult {\n valid: boolean;\n issues: FieldCryptoPolicyValidationIssue[];\n}\n\nfunction isFunction(value: unknown): value is (...args: unknown[]) => unknown {\n return typeof value === \"function\";\n}\n\nfunction normalizeString(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nexport function resolveFieldMode(\n config: FieldCryptoConfig,\n path: string,\n fallback: FieldMode,\n): FieldMode {\n const exact = config.fields[path];\n if (exact) return exact;\n\n if (path.startsWith(\"metadata.\")) {\n const wildcard = config.fields[\"metadata.*\"];\n if (wildcard) return wildcard;\n }\n\n return fallback;\n}\n\nexport function validateFieldCryptoConfig(\n config: FieldCryptoConfig,\n options: FieldCryptoPolicyOptions = {},\n): FieldCryptoPolicyValidationResult {\n const issues: FieldCryptoPolicyValidationIssue[] = [];\n\n if (!config || typeof config !== \"object\") {\n return {\n valid: false,\n issues: [\n {\n message: \"fieldCrypto config must be an object\",\n rule: \"fieldCrypto.config.object\",\n hint: \"Provide a valid FieldCryptoConfig object\",\n },\n ],\n };\n }\n\n if (!config.provider || typeof config.provider !== \"object\") {\n issues.push({\n message: \"fieldCrypto provider is required\",\n rule: \"fieldCrypto.provider.required\",\n path: \"provider\",\n hint: \"Set provider with encrypt/decrypt/hash methods\",\n });\n } else {\n if (!isFunction(config.provider.encrypt)) {\n issues.push({\n message: \"provider.encrypt must be a function\",\n rule: \"fieldCrypto.provider.encrypt.required\",\n path: \"provider.encrypt\",\n });\n }\n if (!isFunction(config.provider.decrypt)) {\n issues.push({\n message: \"provider.decrypt must be a function\",\n rule: \"fieldCrypto.provider.decrypt.required\",\n path: \"provider.decrypt\",\n });\n }\n if (!isFunction(config.provider.hash)) {\n issues.push({\n message: \"provider.hash must be a function\",\n rule: \"fieldCrypto.provider.hash.required\",\n path: \"provider.hash\",\n });\n }\n }\n\n if (!config.fields || typeof config.fields !== \"object\") {\n issues.push({\n message: \"fieldCrypto.fields must be an object\",\n rule: \"fieldCrypto.fields.object\",\n path: \"fields\",\n hint: \"Define policies such as to, from, metadata.phoneNumber\",\n });\n } else {\n const entries = Object.entries(config.fields);\n if (entries.length === 0) {\n issues.push({\n message: \"fieldCrypto.fields must not be empty\",\n rule: \"fieldCrypto.fields.non_empty\",\n path: \"fields\",\n hint: \"Add at least one field mode mapping\",\n });\n }\n\n for (const [path, mode] of entries) {\n const normalizedPath = normalizeString(path);\n if (!normalizedPath) {\n issues.push({\n message: \"field path must be a non-empty string\",\n rule: \"fieldCrypto.fields.path.non_empty\",\n path: \"fields\",\n });\n }\n\n if (\n mode !== \"plain\" &&\n mode !== \"encrypt\" &&\n mode !== \"encrypt+hash\" &&\n mode !== \"mask\"\n ) {\n issues.push({\n message: `unsupported field mode: ${String(mode)}`,\n rule: \"fieldCrypto.fields.mode.supported\",\n path: `fields.${path}`,\n });\n }\n }\n }\n\n const failMode = config.failMode ?? \"closed\";\n const openFallback = config.openFallback ?? \"masked\";\n if (\n failMode === \"open\" &&\n openFallback === \"plaintext\" &&\n config.unsafeAllowPlaintextStorage !== true\n ) {\n issues.push({\n message:\n \"openFallback=plaintext requires unsafeAllowPlaintextStorage=true\",\n rule: \"fieldCrypto.fail_open.plaintext_guard\",\n path: \"openFallback\",\n hint: \"Use masked/null fallback, or explicitly enable unsafe plaintext\",\n });\n }\n\n if (Array.isArray(config.aadFields)) {\n if (config.aadFields.length === 0) {\n issues.push({\n message: \"aadFields must not be empty when provided\",\n rule: \"fieldCrypto.aad_fields.non_empty\",\n path: \"aadFields\",\n });\n }\n\n for (let index = 0; index < config.aadFields.length; index += 1) {\n const key = config.aadFields[index];\n if (!normalizeString(key)) {\n issues.push({\n message: \"aadFields cannot include empty key\",\n rule: \"fieldCrypto.aad_fields.no_empty_key\",\n path: `aadFields[${index}]`,\n });\n }\n }\n }\n\n if (options.secureMode && !options.compatPlainColumns) {\n const toMode = resolveFieldMode(config, \"to\", \"encrypt+hash\");\n const fromMode = resolveFieldMode(config, \"from\", \"encrypt+hash\");\n\n if (toMode === \"plain\") {\n issues.push({\n message:\n \"secure mode requires non-plain policy for `to` when compatPlainColumns=false\",\n rule: \"fieldCrypto.secure_mode.to_non_plain\",\n path: \"fields.to\",\n hint: \"Use encrypt+hash for lookup fields\",\n });\n }\n\n if (fromMode === \"plain\") {\n issues.push({\n message:\n \"secure mode requires non-plain policy for `from` when compatPlainColumns=false\",\n rule: \"fieldCrypto.secure_mode.from_non_plain\",\n path: \"fields.from\",\n hint: \"Use encrypt+hash for lookup fields\",\n });\n }\n }\n\n return {\n valid: issues.length === 0,\n issues,\n };\n}\n\nexport function assertFieldCryptoConfig(\n config: FieldCryptoConfig,\n options: FieldCryptoPolicyOptions = {},\n): void {\n const result = validateFieldCryptoConfig(config, options);\n if (result.valid) return;\n\n const first = result.issues[0];\n if (!first) {\n throw new FieldCryptoError(\n \"config\",\n \"fieldCrypto config validation failed\",\n {\n rule: \"fieldCrypto.config.invalid\",\n issues: result.issues,\n },\n );\n }\n\n throw new FieldCryptoError(\n \"config\",\n first.message,\n {\n rule: first.rule,\n path: first.path,\n hint: first.hint,\n issues: result.issues,\n },\n {\n fieldPath: first.path,\n },\n );\n}\n",
|
|
8
|
-
"export type FieldMode = \"plain\" | \"encrypt\" | \"encrypt+hash\" | \"mask\";\nexport type FieldCryptoFailMode = \"closed\" | \"open\";\nexport type FieldCryptoOpenFallback = \"masked\" | \"plaintext\" | \"null\";\nexport type MaybePromise<T> = T | Promise<T>;\n\nexport interface CryptoEnvelope {\n v: number;\n alg: string;\n kid: string;\n iv: string;\n tag: string;\n ct: string;\n}\n\nexport interface FieldCryptoAad {\n [key: string]: string;\n}\n\nexport interface FieldCryptoKeyContext {\n tenantId?: string;\n providerId?: string;\n messageId?: string;\n tableName?: string;\n fieldPath?: string;\n requestId?: string;\n}\n\nexport interface KeyResolver {\n resolveEncryptKey(\n context: FieldCryptoKeyContext,\n ): MaybePromise<{ kid: string }>;\n resolveDecryptKeys?(\n context: FieldCryptoKeyContext & {\n ciphertext?: string;\n },\n ): MaybePromise<readonly string[]>;\n}\n\nexport interface FieldCryptoEncryptInput {\n value: string;\n aad: FieldCryptoAad;\n path: string;\n kid?: string;\n}\n\nexport interface FieldCryptoDecryptInput {\n ciphertext: string;\n aad: FieldCryptoAad;\n path: string;\n candidateKids?: readonly string[];\n}\n\nexport interface FieldCryptoHashInput {\n value: string;\n path: string;\n kid?: string;\n}\n\nexport interface FieldCryptoMaskInput {\n value: string;\n path: string;\n}\n\nexport interface FieldCryptoProvider {\n encrypt(\n input: FieldCryptoEncryptInput,\n ): MaybePromise<{ ciphertext: string | CryptoEnvelope; kid?: string }>;\n decrypt(input: FieldCryptoDecryptInput): MaybePromise<string>;\n hash(input: FieldCryptoHashInput): MaybePromise<string>;\n mask?(input: FieldCryptoMaskInput): MaybePromise<string>;\n}\n\nexport interface FieldCryptoConfig {\n enabled?: boolean;\n fields: Record<string, FieldMode>;\n failMode?: FieldCryptoFailMode;\n openFallback?: FieldCryptoOpenFallback;\n unsafeAllowPlaintextStorage?: boolean;\n aadFields?: readonly string[];\n keyResolver?: KeyResolver;\n provider: FieldCryptoProvider;\n}\n\nexport type FieldCryptoMetricName =\n | \"crypto_encrypt_ms\"\n | \"crypto_decrypt_ms\"\n | \"crypto_fail_count\"\n | \"key_kid_usage\";\n\nexport interface FieldCryptoMetricEvent {\n name: FieldCryptoMetricName;\n value?: number;\n kid?: string;\n tags?: Record<string, string | number | boolean | undefined>;\n}\n\nfunction encodeBase64Url(buffer: ArrayBuffer | Uint8Array): string {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n const maybeBuffer =\n typeof globalThis !== \"undefined\"\n ? (\n globalThis as {\n Buffer?: {\n from: (input: Uint8Array) => {\n toString: (encoding: string) => string;\n };\n };\n }\n ).Buffer\n : undefined;\n const base64 = maybeBuffer\n ? maybeBuffer.from(bytes).toString(\"base64\")\n : btoa(String.fromCharCode(...bytes));\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/g, \"\");\n}\n\nfunction decodeBase64Url(value: string): Uint8Array {\n const normalized = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded =\n normalized.length % 4 === 0\n ? normalized\n : `${normalized}${\"=\".repeat(4 - (normalized.length % 4))}`;\n\n const maybeBuffer =\n typeof globalThis !== \"undefined\"\n ? (\n globalThis as {\n Buffer?: { from: (input: string, encoding: string) => Uint8Array };\n }\n ).Buffer\n : undefined;\n\n if (maybeBuffer) {\n return new Uint8Array(maybeBuffer.from(padded, \"base64\"));\n }\n\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n}\n\nfunction toUint8Array(\n value: string | ArrayBuffer | Uint8Array,\n encoding: \"utf8\" | \"base64url\",\n): Uint8Array {\n if (value instanceof Uint8Array) return value;\n if (value instanceof ArrayBuffer) return new Uint8Array(value);\n if (encoding === \"base64url\") return decodeBase64Url(value);\n return new TextEncoder().encode(value);\n}\n\nfunction toHex(buffer: ArrayBuffer | Uint8Array): string {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction toCryptoBufferSource(bytes: Uint8Array): ArrayBuffer {\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n return copy.buffer;\n}\n\nfunction parseEnvelope(ciphertext: string): CryptoEnvelope {\n const parsed = JSON.parse(ciphertext) as Partial<CryptoEnvelope>;\n if (\n !parsed ||\n typeof parsed !== \"object\" ||\n typeof parsed.v !== \"number\" ||\n typeof parsed.alg !== \"string\" ||\n typeof parsed.kid !== \"string\" ||\n typeof parsed.iv !== \"string\" ||\n typeof parsed.tag !== \"string\" ||\n typeof parsed.ct !== \"string\"\n ) {\n throw new Error(\"Invalid ciphertext envelope\");\n }\n\n return parsed as CryptoEnvelope;\n}\n\nfunction toCiphertextString(value: string | CryptoEnvelope): string {\n if (typeof value === \"string\") return value;\n return JSON.stringify(value);\n}\n\nexport function isCryptoEnvelope(value: unknown): value is CryptoEnvelope {\n if (!value || typeof value !== \"object\") return false;\n const candidate = value as Partial<CryptoEnvelope>;\n return (\n typeof candidate.v === \"number\" &&\n typeof candidate.alg === \"string\" &&\n typeof candidate.kid === \"string\" &&\n typeof candidate.iv === \"string\" &&\n typeof candidate.tag === \"string\" &&\n typeof candidate.ct === \"string\"\n );\n}\n\nexport function normalizePhoneForHash(value: string): string {\n const trimmed = String(value ?? \"\").trim();\n if (trimmed.length === 0) return \"\";\n\n const hasLeadingPlus = trimmed.startsWith(\"+\");\n const digitsOnly = trimmed.replace(/\\D/g, \"\");\n return hasLeadingPlus ? `+${digitsOnly}` : digitsOnly;\n}\n\nexport function createDefaultMasker(\n visibleStart = 3,\n visibleEnd = 2,\n): (value: string) => string {\n return (value: string): string => {\n const normalized = String(value ?? \"\");\n if (normalized.length <= visibleStart + visibleEnd) {\n return \"*\".repeat(Math.max(0, normalized.length));\n }\n const start = normalized.slice(0, visibleStart);\n const end = normalized.slice(-visibleEnd);\n return `${start}${\"*\".repeat(normalized.length - visibleStart - visibleEnd)}${end}`;\n };\n}\n\nexport interface AesGcmFieldCryptoProviderOptions {\n keys: Record<string, string | ArrayBuffer | Uint8Array>;\n activeKid: string;\n hashKeys?: Record<string, string | ArrayBuffer | Uint8Array>;\n keyEncoding?: \"utf8\" | \"base64url\";\n hashKeyEncoding?: \"utf8\" | \"base64url\";\n algorithm?: \"A256GCM\";\n}\n\nexport function createAesGcmFieldCryptoProvider(\n options: AesGcmFieldCryptoProviderOptions,\n): FieldCryptoProvider {\n const algorithm = options.algorithm ?? \"A256GCM\";\n const keyEncoding = options.keyEncoding ?? \"base64url\";\n const hashKeyEncoding = options.hashKeyEncoding ?? keyEncoding;\n const aesKeyCache = new Map<string, Promise<CryptoKey>>();\n const hashKeyCache = new Map<string, Promise<CryptoKey>>();\n\n const importAesKey = (kid: string): Promise<CryptoKey> => {\n const cached = aesKeyCache.get(kid);\n if (cached) return cached;\n\n const raw = options.keys[kid];\n if (!raw) {\n throw new Error(`Unknown encryption key id: ${kid}`);\n }\n const bytes = toUint8Array(raw, keyEncoding);\n const promise = crypto.subtle.importKey(\n \"raw\",\n toCryptoBufferSource(bytes),\n \"AES-GCM\",\n false,\n [\"encrypt\", \"decrypt\"],\n );\n aesKeyCache.set(kid, promise);\n return promise;\n };\n\n const importHashKey = (kid: string): Promise<CryptoKey> => {\n const cached = hashKeyCache.get(kid);\n if (cached) return cached;\n\n const raw = options.hashKeys?.[kid] ?? options.keys[kid];\n if (!raw) {\n throw new Error(`Unknown hash key id: ${kid}`);\n }\n const bytes = toUint8Array(raw, hashKeyEncoding);\n const promise = crypto.subtle.importKey(\n \"raw\",\n toCryptoBufferSource(bytes),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n hashKeyCache.set(kid, promise);\n return promise;\n };\n\n return {\n async encrypt(input) {\n const kid = input.kid ?? options.activeKid;\n const key = await importAesKey(kid);\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const additionalData = new TextEncoder().encode(\n JSON.stringify(input.aad ?? {}),\n );\n const plaintext = new TextEncoder().encode(input.value);\n\n const encrypted = await crypto.subtle.encrypt(\n {\n name: \"AES-GCM\",\n iv: toCryptoBufferSource(iv),\n additionalData: toCryptoBufferSource(additionalData),\n tagLength: 128,\n },\n key,\n toCryptoBufferSource(plaintext),\n );\n\n const encryptedBytes = new Uint8Array(encrypted);\n const tag = encryptedBytes.slice(encryptedBytes.length - 16);\n const ciphertext = encryptedBytes.slice(0, encryptedBytes.length - 16);\n\n return {\n ciphertext: {\n v: 1,\n alg: algorithm,\n kid,\n iv: encodeBase64Url(iv),\n tag: encodeBase64Url(tag),\n ct: encodeBase64Url(ciphertext),\n },\n kid,\n };\n },\n\n async decrypt(input) {\n const envelope = parseEnvelope(input.ciphertext);\n const candidateKids =\n input.candidateKids && input.candidateKids.length > 0\n ? input.candidateKids\n : [envelope.kid];\n const iv = decodeBase64Url(envelope.iv);\n const tag = decodeBase64Url(envelope.tag);\n const ciphertext = decodeBase64Url(envelope.ct);\n\n const encrypted = new Uint8Array(ciphertext.length + tag.length);\n encrypted.set(ciphertext, 0);\n encrypted.set(tag, ciphertext.length);\n\n const additionalData = new TextEncoder().encode(\n JSON.stringify(input.aad ?? {}),\n );\n\n let lastError: unknown;\n for (const kid of candidateKids) {\n try {\n const key = await importAesKey(kid);\n const decrypted = await crypto.subtle.decrypt(\n {\n name: \"AES-GCM\",\n iv: toCryptoBufferSource(iv),\n additionalData: toCryptoBufferSource(additionalData),\n tagLength: 128,\n },\n key,\n toCryptoBufferSource(encrypted),\n );\n return new TextDecoder().decode(new Uint8Array(decrypted));\n } catch (error) {\n lastError = error;\n }\n }\n\n throw new Error(\n `Failed to decrypt ciphertext: ${lastError instanceof Error ? lastError.message : String(lastError ?? \"unknown\")}`,\n );\n },\n\n async hash(input) {\n const kid = input.kid ?? options.activeKid;\n const key = await importHashKey(kid);\n const signature = await crypto.subtle.sign(\n \"HMAC\",\n key,\n toCryptoBufferSource(new TextEncoder().encode(input.value)),\n );\n return toHex(signature);\n },\n\n mask(input) {\n return createDefaultMasker()(input.value);\n },\n };\n}\n\nexport function createNoopFieldCryptoProvider(): FieldCryptoProvider {\n return {\n encrypt(input) {\n return {\n ciphertext: JSON.stringify({\n v: 1,\n alg: \"NOOP\",\n kid: \"noop\",\n iv: \"\",\n tag: \"\",\n ct: input.value,\n } satisfies CryptoEnvelope),\n };\n },\n decrypt(input) {\n try {\n const parsed = parseEnvelope(input.ciphertext);\n return parsed.ct;\n } catch {\n return input.ciphertext;\n }\n },\n hash(input) {\n const normalized = normalizePhoneForHash(input.value);\n return encodeBase64Url(new TextEncoder().encode(normalized));\n },\n mask(input) {\n return createDefaultMasker()(input.value);\n },\n };\n}\n\nexport function toCiphertextEnvelopeString(\n ciphertext: string | CryptoEnvelope,\n): string {\n return toCiphertextString(ciphertext);\n}\n",
|
|
13
|
+
"export type FieldMode = \"plain\" | \"encrypt\" | \"encrypt+hash\" | \"mask\";\nexport type FieldCryptoFailMode = \"closed\" | \"open\";\nexport type FieldCryptoOpenFallback = \"masked\" | \"plaintext\" | \"null\";\nexport type MaybePromise<T> = T | Promise<T>;\n\nexport interface CryptoEnvelope {\n v: number;\n alg: string;\n kid: string;\n iv: string;\n tag: string;\n ct: string;\n}\n\nexport interface FieldCryptoAad {\n [key: string]: string;\n}\n\nexport interface FieldCryptoKeyContext {\n tenantId?: string;\n providerId?: string;\n messageId?: string;\n tableName?: string;\n fieldPath?: string;\n requestId?: string;\n}\n\nexport interface KeySetState {\n activeKid: string;\n decryptKids?: readonly string[];\n refreshedAt?: number;\n}\n\nexport interface KeyResolver {\n resolveEncryptKey(\n context: FieldCryptoKeyContext,\n ): MaybePromise<{ kid: string }>;\n resolveDecryptKeys?(\n context: FieldCryptoKeyContext & {\n ciphertext?: string;\n },\n ): MaybePromise<readonly string[]>;\n}\n\nexport interface FieldCryptoEncryptInput {\n value: string;\n aad: FieldCryptoAad;\n path: string;\n kid?: string;\n}\n\nexport interface FieldCryptoDecryptInput {\n ciphertext: string;\n aad: FieldCryptoAad;\n path: string;\n candidateKids?: readonly string[];\n}\n\nexport interface FieldCryptoHashInput {\n value: string;\n path: string;\n kid?: string;\n}\n\nexport interface FieldCryptoMaskInput {\n value: string;\n path: string;\n}\n\nexport interface FieldCryptoProvider {\n encrypt(\n input: FieldCryptoEncryptInput,\n ): MaybePromise<{ ciphertext: string | CryptoEnvelope; kid?: string }>;\n decrypt(input: FieldCryptoDecryptInput): MaybePromise<string>;\n hash(input: FieldCryptoHashInput): MaybePromise<string>;\n mask?(input: FieldCryptoMaskInput): MaybePromise<string>;\n}\n\nexport interface FieldCryptoConfig {\n enabled?: boolean;\n fields: Record<string, FieldMode>;\n failMode?: FieldCryptoFailMode;\n openFallback?: FieldCryptoOpenFallback;\n unsafeAllowPlaintextStorage?: boolean;\n aadFields?: readonly string[];\n keyResolver?: KeyResolver;\n provider: FieldCryptoProvider;\n}\n\nexport type FieldCryptoMetricName =\n | \"crypto_encrypt_ms\"\n | \"crypto_decrypt_ms\"\n | \"crypto_fail_count\"\n | \"key_kid_usage\"\n | \"crypto_circuit_open_count\"\n | \"crypto_circuit_state\";\n\nexport type FieldCryptoCircuitState = \"closed\" | \"open\" | \"half-open\";\n\nexport interface FieldCryptoControlScope {\n tenantId?: string;\n providerId?: string;\n kid?: string;\n}\n\nexport interface FieldCryptoControlSignalEvent {\n state: FieldCryptoCircuitState;\n reason: \"threshold\" | \"cooldown\" | \"manual\" | \"recovered\";\n scope: string;\n scopeParts: FieldCryptoControlScope;\n operation: \"encrypt\" | \"decrypt\" | \"hash\";\n at: number;\n errorClass?: string;\n}\n\nexport interface FieldCryptoMetricEvent {\n name: FieldCryptoMetricName;\n value?: number;\n kid?: string;\n tags?: Record<string, string | number | boolean | undefined>;\n}\n\nfunction encodeBase64Url(buffer: ArrayBuffer | Uint8Array): string {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n const maybeBuffer =\n typeof globalThis !== \"undefined\"\n ? (\n globalThis as {\n Buffer?: {\n from: (input: Uint8Array) => {\n toString: (encoding: string) => string;\n };\n };\n }\n ).Buffer\n : undefined;\n const base64 = maybeBuffer\n ? maybeBuffer.from(bytes).toString(\"base64\")\n : btoa(String.fromCharCode(...bytes));\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/g, \"\");\n}\n\nfunction decodeBase64Url(value: string): Uint8Array {\n const normalized = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded =\n normalized.length % 4 === 0\n ? normalized\n : `${normalized}${\"=\".repeat(4 - (normalized.length % 4))}`;\n\n const maybeBuffer =\n typeof globalThis !== \"undefined\"\n ? (\n globalThis as {\n Buffer?: { from: (input: string, encoding: string) => Uint8Array };\n }\n ).Buffer\n : undefined;\n\n if (maybeBuffer) {\n return new Uint8Array(maybeBuffer.from(padded, \"base64\"));\n }\n\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n}\n\nfunction toUint8Array(\n value: string | ArrayBuffer | Uint8Array,\n encoding: \"utf8\" | \"base64url\",\n): Uint8Array {\n if (value instanceof Uint8Array) return value;\n if (value instanceof ArrayBuffer) return new Uint8Array(value);\n if (encoding === \"base64url\") return decodeBase64Url(value);\n return new TextEncoder().encode(value);\n}\n\nfunction toHex(buffer: ArrayBuffer | Uint8Array): string {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction toCryptoBufferSource(bytes: Uint8Array): ArrayBuffer {\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n return copy.buffer;\n}\n\nfunction parseEnvelope(ciphertext: string): CryptoEnvelope {\n const parsed = JSON.parse(ciphertext) as Partial<CryptoEnvelope>;\n if (\n !parsed ||\n typeof parsed !== \"object\" ||\n typeof parsed.v !== \"number\" ||\n typeof parsed.alg !== \"string\" ||\n typeof parsed.kid !== \"string\" ||\n typeof parsed.iv !== \"string\" ||\n typeof parsed.tag !== \"string\" ||\n typeof parsed.ct !== \"string\"\n ) {\n throw new Error(\"Invalid ciphertext envelope\");\n }\n\n return parsed as CryptoEnvelope;\n}\n\nfunction toCiphertextString(value: string | CryptoEnvelope): string {\n if (typeof value === \"string\") return value;\n return JSON.stringify(value);\n}\n\nexport function isCryptoEnvelope(value: unknown): value is CryptoEnvelope {\n if (!value || typeof value !== \"object\") return false;\n const candidate = value as Partial<CryptoEnvelope>;\n return (\n typeof candidate.v === \"number\" &&\n typeof candidate.alg === \"string\" &&\n typeof candidate.kid === \"string\" &&\n typeof candidate.iv === \"string\" &&\n typeof candidate.tag === \"string\" &&\n typeof candidate.ct === \"string\"\n );\n}\n\nexport function normalizePhoneForHash(value: string): string {\n const trimmed = String(value ?? \"\").trim();\n if (trimmed.length === 0) return \"\";\n\n const hasLeadingPlus = trimmed.startsWith(\"+\");\n const digitsOnly = trimmed.replace(/\\D/g, \"\");\n return hasLeadingPlus ? `+${digitsOnly}` : digitsOnly;\n}\n\nexport function createDefaultMasker(\n visibleStart = 3,\n visibleEnd = 2,\n): (value: string) => string {\n return (value: string): string => {\n const normalized = String(value ?? \"\");\n if (normalized.length <= visibleStart + visibleEnd) {\n return \"*\".repeat(Math.max(0, normalized.length));\n }\n const start = normalized.slice(0, visibleStart);\n const end = normalized.slice(-visibleEnd);\n return `${start}${\"*\".repeat(normalized.length - visibleStart - visibleEnd)}${end}`;\n };\n}\n\nexport interface AesGcmFieldCryptoProviderOptions {\n keys: Record<string, string | ArrayBuffer | Uint8Array>;\n activeKid: string;\n hashKeys?: Record<string, string | ArrayBuffer | Uint8Array>;\n keyEncoding?: \"utf8\" | \"base64url\";\n hashKeyEncoding?: \"utf8\" | \"base64url\";\n algorithm?: \"A256GCM\";\n}\n\nexport function createAesGcmFieldCryptoProvider(\n options: AesGcmFieldCryptoProviderOptions,\n): FieldCryptoProvider {\n const algorithm = options.algorithm ?? \"A256GCM\";\n const keyEncoding = options.keyEncoding ?? \"base64url\";\n const hashKeyEncoding = options.hashKeyEncoding ?? keyEncoding;\n const aesKeyCache = new Map<string, Promise<CryptoKey>>();\n const hashKeyCache = new Map<string, Promise<CryptoKey>>();\n\n const importAesKey = (kid: string): Promise<CryptoKey> => {\n const cached = aesKeyCache.get(kid);\n if (cached) return cached;\n\n const raw = options.keys[kid];\n if (!raw) {\n throw new Error(`Unknown encryption key id: ${kid}`);\n }\n const bytes = toUint8Array(raw, keyEncoding);\n const promise = crypto.subtle.importKey(\n \"raw\",\n toCryptoBufferSource(bytes),\n \"AES-GCM\",\n false,\n [\"encrypt\", \"decrypt\"],\n );\n aesKeyCache.set(kid, promise);\n return promise;\n };\n\n const importHashKey = (kid: string): Promise<CryptoKey> => {\n const cached = hashKeyCache.get(kid);\n if (cached) return cached;\n\n const raw = options.hashKeys?.[kid] ?? options.keys[kid];\n if (!raw) {\n throw new Error(`Unknown hash key id: ${kid}`);\n }\n const bytes = toUint8Array(raw, hashKeyEncoding);\n const promise = crypto.subtle.importKey(\n \"raw\",\n toCryptoBufferSource(bytes),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n hashKeyCache.set(kid, promise);\n return promise;\n };\n\n return {\n async encrypt(input) {\n const kid = input.kid ?? options.activeKid;\n const key = await importAesKey(kid);\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const additionalData = new TextEncoder().encode(\n JSON.stringify(input.aad ?? {}),\n );\n const plaintext = new TextEncoder().encode(input.value);\n\n const encrypted = await crypto.subtle.encrypt(\n {\n name: \"AES-GCM\",\n iv: toCryptoBufferSource(iv),\n additionalData: toCryptoBufferSource(additionalData),\n tagLength: 128,\n },\n key,\n toCryptoBufferSource(plaintext),\n );\n\n const encryptedBytes = new Uint8Array(encrypted);\n const tag = encryptedBytes.slice(encryptedBytes.length - 16);\n const ciphertext = encryptedBytes.slice(0, encryptedBytes.length - 16);\n\n return {\n ciphertext: {\n v: 1,\n alg: algorithm,\n kid,\n iv: encodeBase64Url(iv),\n tag: encodeBase64Url(tag),\n ct: encodeBase64Url(ciphertext),\n },\n kid,\n };\n },\n\n async decrypt(input) {\n const envelope = parseEnvelope(input.ciphertext);\n const candidateKids =\n input.candidateKids && input.candidateKids.length > 0\n ? input.candidateKids\n : [envelope.kid];\n const iv = decodeBase64Url(envelope.iv);\n const tag = decodeBase64Url(envelope.tag);\n const ciphertext = decodeBase64Url(envelope.ct);\n\n const encrypted = new Uint8Array(ciphertext.length + tag.length);\n encrypted.set(ciphertext, 0);\n encrypted.set(tag, ciphertext.length);\n\n const additionalData = new TextEncoder().encode(\n JSON.stringify(input.aad ?? {}),\n );\n\n let lastError: unknown;\n for (const kid of candidateKids) {\n try {\n const key = await importAesKey(kid);\n const decrypted = await crypto.subtle.decrypt(\n {\n name: \"AES-GCM\",\n iv: toCryptoBufferSource(iv),\n additionalData: toCryptoBufferSource(additionalData),\n tagLength: 128,\n },\n key,\n toCryptoBufferSource(encrypted),\n );\n return new TextDecoder().decode(new Uint8Array(decrypted));\n } catch (error) {\n lastError = error;\n }\n }\n\n throw new Error(\n `Failed to decrypt ciphertext: ${lastError instanceof Error ? lastError.message : String(lastError ?? \"unknown\")}`,\n );\n },\n\n async hash(input) {\n const kid = input.kid ?? options.activeKid;\n const key = await importHashKey(kid);\n const signature = await crypto.subtle.sign(\n \"HMAC\",\n key,\n toCryptoBufferSource(new TextEncoder().encode(input.value)),\n );\n return toHex(signature);\n },\n\n mask(input) {\n return createDefaultMasker()(input.value);\n },\n };\n}\n\nexport function createNoopFieldCryptoProvider(): FieldCryptoProvider {\n return {\n encrypt(input) {\n return {\n ciphertext: JSON.stringify({\n v: 1,\n alg: \"NOOP\",\n kid: \"noop\",\n iv: \"\",\n tag: \"\",\n ct: input.value,\n } satisfies CryptoEnvelope),\n };\n },\n decrypt(input) {\n try {\n const parsed = parseEnvelope(input.ciphertext);\n return parsed.ct;\n } catch {\n return input.ciphertext;\n }\n },\n hash(input) {\n const normalized = normalizePhoneForHash(input.value);\n return encodeBase64Url(new TextEncoder().encode(normalized));\n },\n mask(input) {\n return createDefaultMasker()(input.value);\n },\n };\n}\n\nexport function toCiphertextEnvelopeString(\n ciphertext: string | CryptoEnvelope,\n): string {\n return toCiphertextString(ciphertext);\n}\n",
|
|
9
14
|
"export enum LogLevel {\n DEBUG = \"DEBUG\",\n INFO = \"INFO\",\n WARN = \"WARN\",\n ERROR = \"ERROR\",\n}\n\nexport interface LogContext {\n component?: string;\n operation?: string;\n userId?: string;\n sessionId?: string;\n requestId?: string;\n traceId?: string;\n [key: string]: any;\n}\n\nexport interface LogEntry {\n level: LogLevel;\n message: string;\n timestamp: Date;\n context: LogContext;\n error?: Error;\n duration?: number;\n}\n\nexport interface LoggerConfig {\n level: LogLevel;\n enableConsole: boolean;\n enableFile?: boolean;\n filePath?: string;\n maxFileSize?: number;\n maxFiles?: number;\n enableJson?: boolean;\n enableColors?: boolean;\n}\n\nconst REDACTED_TOKEN = \"[REDACTED]\";\nconst MASKED_TOKEN = \"***\";\nconst SENSITIVE_CONTEXT_KEYS = [\n \"to\",\n \"from\",\n \"phone\",\n \"phoneNumber\",\n \"recipient\",\n \"sender\",\n \"secret\",\n \"apiKey\",\n \"apiSecret\",\n \"authorization\",\n \"auth\",\n \"token\",\n \"password\",\n \"payload\",\n \"message\",\n \"content\",\n \"text\",\n] as const;\n\nfunction isSensitiveContextKey(rawKey: string): boolean {\n const key = rawKey.toLowerCase();\n return SENSITIVE_CONTEXT_KEYS.some((candidate) =>\n key.includes(candidate.toLowerCase()),\n );\n}\n\nfunction maskStringValue(value: string): string {\n const trimmed = value.trim();\n if (trimmed.length <= 4) return MASKED_TOKEN;\n if (trimmed.includes(\"@\")) {\n const [local, domain] = trimmed.split(\"@\");\n const head = local.slice(0, 2);\n return `${head}${\"*\".repeat(Math.max(1, local.length - 2))}@${domain}`;\n }\n const head = trimmed.slice(0, 3);\n const tail = trimmed.slice(-2);\n return `${head}${\"*\".repeat(Math.max(1, trimmed.length - 5))}${tail}`;\n}\n\nfunction sanitizeContextValue(key: string, value: unknown): unknown {\n if (value === undefined || value === null) return value;\n\n if (isSensitiveContextKey(key)) {\n if (typeof value === \"string\") return maskStringValue(value);\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return MASKED_TOKEN;\n }\n if (Array.isArray(value)) return REDACTED_TOKEN;\n if (typeof value === \"object\") return REDACTED_TOKEN;\n }\n\n if (Array.isArray(value)) {\n return value.map((entry) => sanitizeContextValue(key, entry));\n }\n\n if (typeof value === \"object\") {\n const next: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n next[childKey] = sanitizeContextValue(childKey, childValue);\n }\n return next;\n }\n\n return value;\n}\n\nfunction sanitizeLogContext(context: LogContext): LogContext {\n const sanitized: LogContext = {};\n for (const [key, value] of Object.entries(context)) {\n sanitized[key] = sanitizeContextValue(key, value);\n }\n return sanitized;\n}\n\nexport class Logger {\n private config: LoggerConfig;\n private context: LogContext;\n\n constructor(context: LogContext = {}, config: Partial<LoggerConfig> = {}) {\n this.context = context;\n this.config = {\n level: LogLevel.INFO,\n enableConsole: true,\n enableJson: false,\n enableColors: true,\n ...config,\n };\n }\n\n private shouldLog(level: LogLevel): boolean {\n const levels = [\n LogLevel.DEBUG,\n LogLevel.INFO,\n LogLevel.WARN,\n LogLevel.ERROR,\n ];\n return levels.indexOf(level) >= levels.indexOf(this.config.level);\n }\n\n private formatMessage(entry: LogEntry): string {\n const context = sanitizeLogContext(entry.context);\n\n if (this.config.enableJson) {\n return JSON.stringify({\n level: entry.level,\n message: entry.message,\n timestamp: entry.timestamp.toISOString(),\n context,\n ...(entry.error && {\n error: {\n name: entry.error.name,\n message: entry.error.message,\n stack: entry.error.stack,\n },\n }),\n ...(entry.duration && { duration: entry.duration }),\n });\n }\n\n const timestamp = entry.timestamp.toISOString();\n const level = this.config.enableColors\n ? this.colorizeLevel(entry.level)\n : entry.level;\n const contextStr =\n Object.keys(context).length > 0\n ? ` [${Object.entries(context)\n .map(([k, v]) => `${k}=${v}`)\n .join(\", \")}]`\n : \"\";\n\n let message = `${timestamp} ${level}${contextStr}: ${entry.message}`;\n\n if (entry.duration !== undefined) {\n message += ` (${entry.duration}ms)`;\n }\n\n if (entry.error) {\n message += `\\n${entry.error.stack}`;\n }\n\n return message;\n }\n\n private colorizeLevel(level: LogLevel): string {\n if (!this.config.enableColors) return level;\n\n const colors = {\n [LogLevel.DEBUG]: \"\\x1b[36m\", // cyan\n [LogLevel.INFO]: \"\\x1b[32m\", // green\n [LogLevel.WARN]: \"\\x1b[33m\", // yellow\n [LogLevel.ERROR]: \"\\x1b[31m\", // red\n };\n\n return `${colors[level]}${level}\\x1b[0m`;\n }\n\n private writeLog(entry: LogEntry): void {\n if (!this.shouldLog(entry.level)) return;\n\n const message = this.formatMessage(entry);\n\n if (this.config.enableConsole) {\n const logFn =\n entry.level === LogLevel.ERROR\n ? console.error\n : entry.level === LogLevel.WARN\n ? console.warn\n : console.log;\n logFn(message);\n }\n\n // File logging would be implemented here if needed\n if (this.config.enableFile && this.config.filePath) {\n // Bun.write(this.config.filePath, message + '\\n', { createPath: true });\n }\n }\n\n debug(message: string, context: LogContext = {}): void {\n this.writeLog({\n level: LogLevel.DEBUG,\n message,\n timestamp: new Date(),\n context: { ...this.context, ...context },\n });\n }\n\n info(message: string, context: LogContext = {}): void {\n this.writeLog({\n level: LogLevel.INFO,\n message,\n timestamp: new Date(),\n context: { ...this.context, ...context },\n });\n }\n\n warn(message: string, context: LogContext = {}, error?: Error): void {\n this.writeLog({\n level: LogLevel.WARN,\n message,\n timestamp: new Date(),\n context: { ...this.context, ...context },\n error,\n });\n }\n\n error(message: string, context: LogContext = {}, error?: Error): void {\n this.writeLog({\n level: LogLevel.ERROR,\n message,\n timestamp: new Date(),\n context: { ...this.context, ...context },\n error,\n });\n }\n\n child(context: LogContext): Logger {\n return new Logger({ ...this.context, ...context }, this.config);\n }\n\n time(label: string): () => void {\n const start = Date.now();\n return () => {\n const duration = Date.now() - start;\n this.info(`${label} completed`, { duration });\n };\n }\n\n async measure<T>(\n operation: string,\n fn: () => Promise<T>,\n context: LogContext = {},\n ): Promise<T> {\n const start = Date.now();\n const operationContext = { ...context, operation };\n\n this.debug(`Starting ${operation}`, operationContext);\n\n try {\n const result = await fn();\n const duration = Date.now() - start;\n\n this.info(`Completed ${operation}`, { ...operationContext, duration });\n return result;\n } catch (error) {\n const duration = Date.now() - start;\n\n this.error(\n `Failed ${operation}`,\n { ...operationContext, duration },\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n }\n}\n\n// Global logger instance\nlet globalLogger: Logger;\n\nexport function createLogger(\n context?: LogContext,\n config?: Partial<LoggerConfig>,\n): Logger {\n return new Logger(context, config);\n}\n\nexport function getLogger(): Logger {\n if (!globalLogger) {\n globalLogger = createLogger();\n }\n return globalLogger;\n}\n\nexport function setGlobalLogger(logger: Logger): void {\n globalLogger = logger;\n}\n\n// Convenience functions\nexport const logger = {\n debug: (message: string, context?: LogContext) =>\n getLogger().debug(message, context),\n info: (message: string, context?: LogContext) =>\n getLogger().info(message, context),\n warn: (message: string, context?: LogContext, error?: Error) =>\n getLogger().warn(message, context, error),\n error: (message: string, context?: LogContext, error?: Error) =>\n getLogger().error(message, context, error),\n child: (context: LogContext) => getLogger().child(context),\n time: (label: string) => getLogger().time(label),\n measure: <T>(operation: string, fn: () => Promise<T>, context?: LogContext) =>\n getLogger().measure(operation, fn, context),\n};\n\n// Express-style middleware for Hono\nexport function loggerMiddleware(config?: Partial<LoggerConfig>) {\n const requestLogger = createLogger({}, config);\n\n return async (c: any, next: any) => {\n const start = Date.now();\n const requestId = Math.random().toString(36).substring(7);\n\n const context = {\n requestId,\n method: c.req.method,\n path: c.req.path,\n userAgent: c.req.header(\"user-agent\") || \"unknown\",\n };\n\n requestLogger.info(\"Request started\", context);\n\n try {\n await next();\n\n const duration = Date.now() - start;\n requestLogger.info(\"Request completed\", {\n ...context,\n status: c.res.status,\n duration,\n });\n } catch (error) {\n const duration = Date.now() - start;\n requestLogger.error(\n \"Request failed\",\n {\n ...context,\n duration,\n },\n error instanceof Error ? error : new Error(String(error)),\n );\n\n throw error;\n }\n };\n}\n",
|
|
10
15
|
"/**\n * Retry options and handler for K-Message Platform\n */\n\nimport { ErrorUtils } from \"../errors\";\n\nexport interface RetryOptions {\n maxAttempts?: number;\n initialDelay?: number;\n maxDelay?: number;\n backoffMultiplier?: number;\n jitter?: boolean;\n retryCondition?: (error: Error, attempt: number) => boolean;\n onRetry?: (error: Error, attempt: number) => void;\n}\n\n/**\n * Exponential backoff retry mechanism\n */\nexport class RetryHandler {\n private static defaultOptions: RetryOptions = {\n maxAttempts: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n backoffMultiplier: 2,\n jitter: true,\n retryCondition: (error) => ErrorUtils.isRetryable(error),\n };\n\n static async execute<T>(\n operation: () => Promise<T>,\n options: Partial<RetryOptions> = {},\n ): Promise<T> {\n const opts = {\n ...RetryHandler.defaultOptions,\n ...options,\n } as Required<RetryOptions>;\n let lastError: Error;\n let delay = opts.initialDelay;\n\n for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error as Error;\n\n if (\n attempt === opts.maxAttempts ||\n !opts.retryCondition!(lastError, attempt)\n ) {\n throw lastError;\n }\n\n const actualDelay = opts.jitter\n ? delay + Math.random() * delay * 0.1\n : delay;\n\n opts.onRetry?.(lastError, attempt);\n\n await new Promise((resolve) => setTimeout(resolve, actualDelay));\n\n delay = Math.min(delay * opts.backoffMultiplier, opts.maxDelay);\n }\n }\n\n throw lastError!;\n }\n\n static createRetryableFunction<T extends any[], R>(\n func: (...args: T) => Promise<R>,\n options: Partial<RetryOptions> = {},\n ): (...args: T) => Promise<R> {\n return async (...args: T) => {\n return RetryHandler.execute(() => func(...args), options);\n };\n }\n}\n",
|
|
11
16
|
"/**\n * Bulk operation handler with error recovery\n */\n\nimport { KMsgError, KMsgErrorCode } from \"../errors\";\nimport { RetryHandler, type RetryOptions } from \"./retry-handler\";\n\nexport interface BulkOperationOptions {\n concurrency: number;\n retryOptions: RetryOptions;\n failFast: boolean;\n onProgress?: (completed: number, total: number, failed: number) => void;\n}\n\nexport class BulkOperationHandler {\n static async execute<T, R>(\n items: T[],\n operation: (item: T) => Promise<R>,\n options: Partial<BulkOperationOptions> = {},\n ): Promise<{\n successful: { item: T; result: R }[];\n failed: { item: T; error: Error }[];\n summary: {\n total: number;\n successful: number;\n failed: number;\n duration: number;\n };\n }> {\n const opts: BulkOperationOptions = {\n concurrency: 5,\n retryOptions: {\n maxAttempts: 3,\n initialDelay: 1000,\n maxDelay: 10000,\n backoffMultiplier: 2,\n jitter: true,\n },\n failFast: false,\n ...options,\n };\n\n const startTime = Date.now();\n const successful: { item: T; result: R }[] = [];\n const failed: { item: T; error: Error }[] = [];\n let completed = 0;\n\n const retryableOperation = RetryHandler.createRetryableFunction(\n operation,\n opts.retryOptions,\n );\n\n const batches = BulkOperationHandler.createBatches(items, opts.concurrency);\n\n for (const batch of batches) {\n const batchPromises = batch.map(async (item) => {\n try {\n const result = await retryableOperation(item);\n successful.push({ item, result });\n } catch (error) {\n failed.push({ item, error: error as Error });\n\n if (opts.failFast) {\n throw new KMsgError(\n KMsgErrorCode.MESSAGE_SEND_FAILED,\n `Bulk operation failed fast after ${failed.length} failures`,\n { totalItems: items.length, failedCount: failed.length },\n );\n }\n } finally {\n completed++;\n opts.onProgress?.(completed, items.length, failed.length);\n }\n });\n\n await Promise.allSettled(batchPromises);\n\n if (opts.failFast && failed.length > 0) {\n break;\n }\n }\n\n const duration = Date.now() - startTime;\n\n return {\n successful,\n failed,\n summary: {\n total: items.length,\n successful: successful.length,\n failed: failed.length,\n duration,\n },\n };\n }\n\n private static createBatches<T>(items: T[], batchSize: number): T[][] {\n const batches: T[][] = [];\n for (let i = 0; i < items.length; i += batchSize) {\n batches.push(items.slice(i, i + batchSize));\n }\n return batches;\n }\n}\n",
|
|
@@ -15,7 +20,7 @@
|
|
|
15
20
|
"export type RuntimeEnvRecord = Record<string, string | undefined>;\n\ntype RuntimeGlobal = typeof globalThis & {\n __ENV__?: RuntimeEnvRecord;\n __K_MSG_ENV__?: RuntimeEnvRecord;\n process?: {\n env?: RuntimeEnvRecord;\n };\n};\n\n/**\n * Resolve environment variables in a runtime-neutral order.\n *\n * Priority:\n * 1. globalThis.__K_MSG_ENV__\n * 2. globalThis.__ENV__\n * 3. globalThis.process?.env\n */\nexport function getRuntimeEnvSource(): RuntimeEnvRecord {\n const runtimeGlobal = globalThis as RuntimeGlobal;\n return (\n runtimeGlobal.__K_MSG_ENV__ ??\n runtimeGlobal.__ENV__ ??\n runtimeGlobal.process?.env ??\n {}\n );\n}\n\nexport function readRuntimeEnv(key: string): string | undefined {\n const value = getRuntimeEnvSource()[key];\n if (typeof value === \"string\") {\n return value;\n }\n if (value === undefined) {\n return undefined;\n }\n return String(value);\n}\n",
|
|
16
21
|
"export type MessageType =\n | \"ALIMTALK\"\n | \"FRIENDTALK\"\n | \"SMS\"\n | \"LMS\"\n | \"MMS\"\n | \"NSA\"\n | \"VOICE\"\n | \"FAX\"\n | \"RCS_SMS\"\n | \"RCS_LMS\"\n | \"RCS_MMS\"\n | \"RCS_TPL\"\n | \"RCS_ITPL\"\n | \"RCS_LTPL\";\n\nexport type MessageStatus = \"PENDING\" | \"SENT\" | \"FAILED\";\n\nexport const KNOWN_MESSAGE_STATUSES: MessageStatus[] = [\n \"PENDING\",\n \"SENT\",\n \"FAILED\",\n];\n\nexport const QUEUED_MESSAGE_STATUS: MessageStatus = \"PENDING\";\n\nexport const normalizeMessageStatus = (status: unknown): MessageStatus => {\n const raw = typeof status === \"string\" ? status.trim().toUpperCase() : \"\";\n\n if (raw === \"PENDING\" || raw === \"SENT\" || raw === \"FAILED\") {\n return raw;\n }\n\n return QUEUED_MESSAGE_STATUS;\n};\n\nexport type MessageVariables = Record<\n string,\n string | number | boolean | Date | null | undefined\n>;\n\nexport interface MessageButton {\n name: string;\n /**\n * Provider-dependent. Common values: \"WL\" (web link), \"AL\" (app link), ...\n */\n type: string;\n urlPc?: string;\n urlMobile?: string;\n}\n\nexport type MessageBinaryInput =\n | {\n /**\n * URL or file path (provider-dependent).\n */\n ref: string;\n filename?: string;\n contentType?: string;\n }\n | {\n bytes: Uint8Array;\n filename?: string;\n contentType?: string;\n }\n | {\n blob: Blob;\n filename?: string;\n contentType?: string;\n };\n\nexport interface MessageMedia {\n /**\n * Image attachment (used by MMS, FriendTalk image, RCS_MMS, ...).\n */\n image?: MessageBinaryInput;\n}\n\nexport interface CommonSendOptions {\n /**\n * Correlation id generated by KMsg (or provided by the caller).\n * Providers must echo this value back in SendResult.messageId.\n */\n messageId?: string;\n /**\n * Optional routing hint to force a specific provider by id.\n */\n providerId?: string;\n to: string;\n /**\n * Sender number / sender id. Optional at KMsg layer; providers may require it.\n */\n from?: string;\n /**\n * Common delivery options understood by multiple providers.\n */\n options?: {\n scheduledAt?: Date;\n /**\n * Country code for providers that support it (e.g. SOLAPI).\n * Examples: \"82\", \"+82\".\n */\n country?: string;\n customFields?: Record<string, string>;\n };\n /**\n * Provider-specific escape hatch (use sparingly).\n */\n providerOptions?: Record<string, unknown>;\n}\n\nexport interface KakaoSendOptions {\n profileId?: string;\n plusId?: string;\n disableSms?: boolean;\n adFlag?: boolean;\n buttons?: unknown[];\n imageId?: string;\n /**\n * FriendTalk image upload link hint (SOLAPI).\n */\n imageLink?: string;\n // biome-ignore lint/suspicious/noExplicitAny: provider-specific extras\n [key: string]: any;\n}\n\nexport interface AlimTalkFailoverOptions {\n enabled?: boolean;\n fallbackChannel?: \"sms\" | \"lms\";\n fallbackContent?: string;\n fallbackTitle?: string;\n}\n\nexport type SendWarningCode =\n | \"FAILOVER_UNSUPPORTED_PROVIDER\"\n | \"FAILOVER_PARTIAL_PROVIDER\"\n | \"FALLBACK_CONTENT_MISSING\"\n | (string & {});\n\nexport interface SendWarning {\n code: SendWarningCode;\n message: string;\n details?: Record<string, unknown>;\n}\n\nexport interface NaverSendOptions {\n talkId?: string;\n /**\n * Override the template identifier for NSA (provider-specific).\n */\n templateId?: string;\n disableSms?: boolean;\n variables?: MessageVariables;\n buttons?: unknown[];\n // biome-ignore lint/suspicious/noExplicitAny: provider-specific extras\n [key: string]: any;\n}\n\nexport interface VoiceSendOptions {\n voiceType?: \"FEMALE\" | \"MALE\";\n headerMessage?: string;\n tailMessage?: string;\n replyRange?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;\n counselorNumber?: string;\n // biome-ignore lint/suspicious/noExplicitAny: provider-specific extras\n [key: string]: any;\n}\n\nexport interface FaxSendOptions {\n fileIds?: string[];\n fileUrls?: string[];\n // biome-ignore lint/suspicious/noExplicitAny: provider-specific extras\n [key: string]: any;\n}\n\nexport interface RcsSendOptions {\n brandId?: string;\n /**\n * Override template identifier for RCS_*TPL types.\n */\n templateId?: string;\n copyAllowed?: boolean;\n variables?: MessageVariables;\n mmsType?: \"M3\" | \"S3\" | \"M4\" | \"S4\" | \"M5\" | \"S5\" | \"M6\" | \"S6\";\n commercialType?: boolean;\n disableSms?: boolean;\n buttons?: unknown[];\n additionalBody?: {\n title?: string;\n description?: string;\n imageId?: string;\n buttons?: unknown[];\n // biome-ignore lint/suspicious/noExplicitAny: provider-specific extras\n [key: string]: any;\n };\n // biome-ignore lint/suspicious/noExplicitAny: provider-specific extras\n [key: string]: any;\n}\n\nexport interface SmsSendOptions extends CommonSendOptions {\n type: \"SMS\" | \"LMS\" | \"MMS\";\n text: string;\n /**\n * LMS/MMS subject.\n */\n subject?: string;\n /**\n * Media attachments. For backwards compatibility, `imageUrl` is treated as a legacy alias\n * for `media.image.ref` by some providers.\n */\n media?: MessageMedia;\n /**\n * Optional image URL for MMS (provider-specific).\n */\n imageUrl?: string;\n variables?: MessageVariables;\n}\n\nexport interface AlimTalkSendOptions extends CommonSendOptions {\n type: \"ALIMTALK\";\n templateId: string;\n variables: MessageVariables;\n kakao?: KakaoSendOptions;\n failover?: AlimTalkFailoverOptions;\n}\n\nexport interface FriendTalkSendOptions extends CommonSendOptions {\n type: \"FRIENDTALK\";\n text: string;\n media?: MessageMedia;\n imageUrl?: string;\n buttons?: MessageButton[];\n variables?: MessageVariables;\n kakao?: KakaoSendOptions;\n}\n\nexport interface NsaSendOptions extends CommonSendOptions {\n type: \"NSA\";\n templateId: string;\n variables: MessageVariables;\n naver?: NaverSendOptions;\n}\n\nexport interface VoiceMessageSendOptions extends CommonSendOptions {\n type: \"VOICE\";\n text: string;\n variables?: MessageVariables;\n voice?: VoiceSendOptions;\n}\n\nexport interface FaxMessageSendOptions extends CommonSendOptions {\n type: \"FAX\";\n fax: FaxSendOptions;\n}\n\nexport interface RcsTextSendOptions extends CommonSendOptions {\n type: \"RCS_SMS\" | \"RCS_LMS\" | \"RCS_MMS\";\n text: string;\n subject?: string;\n media?: MessageMedia;\n imageUrl?: string;\n variables?: MessageVariables;\n rcs?: RcsSendOptions;\n}\n\nexport interface RcsTemplateSendOptions extends CommonSendOptions {\n type: \"RCS_TPL\" | \"RCS_ITPL\" | \"RCS_LTPL\";\n templateId: string;\n variables: MessageVariables;\n rcs?: RcsSendOptions;\n}\n\nexport type SendOptions =\n | SmsSendOptions\n | AlimTalkSendOptions\n | FriendTalkSendOptions\n | NsaSendOptions\n | VoiceMessageSendOptions\n | FaxMessageSendOptions\n | RcsTextSendOptions\n | RcsTemplateSendOptions;\n\nexport type SmsDefaultSendInput = Omit<SmsSendOptions, \"type\" | \"text\"> & {\n type?: undefined;\n /**\n * SMS text. If omitted, `content` is used.\n */\n text?: string;\n /**\n * Alias for `text`.\n */\n content?: string;\n};\n\n/**\n * Developer-facing input type.\n * - SMS defaults allow omitting `type` and using `content`.\n * - Other channels are modeled as discriminated unions on `type`.\n */\nexport type SendInput = SendOptions | SmsDefaultSendInput;\n\nexport interface SendResult {\n /**\n * Correlation id (equals the request `messageId`).\n */\n messageId: string;\n providerId: string;\n providerMessageId?: string;\n status: MessageStatus;\n type: MessageType;\n to: string;\n warnings?: SendWarning[];\n raw?: unknown;\n}\n"
|
|
17
22
|
],
|
|
18
|
-
"mappings": "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",
|
|
19
|
-
"debugId": "
|
|
23
|
+
"mappings": "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",
|
|
24
|
+
"debugId": "1C61B1E21374481464756E2164756E21",
|
|
20
25
|
"names": []
|
|
21
26
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var A;((a)=>{a.INVALID_REQUEST="INVALID_REQUEST";a.AUTHENTICATION_FAILED="AUTHENTICATION_FAILED";a.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE";a.TEMPLATE_NOT_FOUND="TEMPLATE_NOT_FOUND";a.RATE_LIMIT_EXCEEDED="RATE_LIMIT_EXCEEDED";a.NETWORK_ERROR="NETWORK_ERROR";a.NETWORK_TIMEOUT="NETWORK_TIMEOUT";a.NETWORK_SERVICE_UNAVAILABLE="NETWORK_SERVICE_UNAVAILABLE";a.PROVIDER_ERROR="PROVIDER_ERROR";a.MESSAGE_SEND_FAILED="MESSAGE_SEND_FAILED";a.CRYPTO_CONFIG_ERROR="CRYPTO_CONFIG_ERROR";a.CRYPTO_ENCRYPT_FAILED="CRYPTO_ENCRYPT_FAILED";a.CRYPTO_DECRYPT_FAILED="CRYPTO_DECRYPT_FAILED";a.CRYPTO_HASH_FAILED="CRYPTO_HASH_FAILED";a.CRYPTO_POLICY_VIOLATION="CRYPTO_POLICY_VIOLATION";a.UNKNOWN_ERROR="UNKNOWN_ERROR"})(A||={});var U=new Set(["NETWORK_ERROR","RATE_LIMIT_EXCEEDED","NETWORK_TIMEOUT","NETWORK_SERVICE_UNAVAILABLE","PROVIDER_ERROR","UNKNOWN_ERROR"]),v=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"]),g=(t)=>{if(typeof t!=="number"||Number.isNaN(t)||!Number.isFinite(t))return;return Math.trunc(t)},q=(t)=>{let e=g(t);if(e===void 0||e<0)return;return e},D=(t)=>{if(typeof t!=="string")return;return t.toLowerCase().trim()},N=(t)=>{if(t>=500)return"retryable";if(t===408||t===425||t===429)return"retryable";return"non_retryable"},_=(t)=>{let e=t.toLowerCase();if(e.includes("timeout")||e.includes("temporar")||e.includes("network")||e.includes("retry"))return"retryable";return};class y extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(t,e,i,n={}){super(e);if(this.name="KMsgError",this.code=t,this.details=i,this.providerErrorCode=n.providerErrorCode,this.providerErrorText=n.providerErrorText,this.httpStatus=g(n.httpStatus),this.requestId=typeof n.requestId==="string"?n.requestId:void 0,this.retryAfterMs=g(n.retryAfterMs),this.attempt=g(n.attempt),Array.isArray(n.causeChain))this.causeChain=n.causeChain;else if(n.causeChain!==void 0)this.causeChain=[n.causeChain];if(Error.captureStackTrace)Error.captureStackTrace(this,y)}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 P={isRetryable(t,e={}){return P.classifyForRetry(t,e)==="retryable"},classifyForRetry(t,e={}){if(t instanceof y){if(new Set(e.retryableCodes??Array.from(U)).has(t.code))return"retryable";if(new Set(e.nonRetryableCodes??Array.from(v)).has(t.code))return"non_retryable";if(t.httpStatus!==void 0)return N(t.httpStatus);let p=_(t.message);if(p)return p;if(e.classifyByMessage&&t.message){let c=e.classifyByMessage(t.message);if(c)return c}if(e.fallback)return e.fallback;return"non_retryable"}let i=t&&typeof t==="object"?t:void 0,n=D(i?.status)??D(i?.statusCode)??D(i?.code),r=g(i?.status)??g(i?.statusCode)??g(i?.httpStatus);if(typeof n==="string"&&n.startsWith("5"))return"retryable";if(r!==void 0){if(e.classifyByStatusCode)return e.classifyByStatusCode(r);return N(r)}let s=typeof i?.message==="string"?_(i.message):void 0;if(s)return s;if(e.classifyByMessage&&typeof i?.message==="string"){let o=e.classifyByMessage(i.message);if(o)return o}return e.fallback??"non_retryable"},resolveRetryAfterMs(t,e){if(e?.retryAfterMs){let i=e.retryAfterMs(t),n=q(i);if(n!==void 0)return n}if(t.retryAfterMs!==void 0)return q(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,e){return new y(t.code,t.message,t.details,{...P.toRetryMetadata(t),attempt:g(e)})},DEFAULT_RETRYABLE_ERROR_CODES:U,DEFAULT_NON_RETRYABLE_ERROR_CODES:v};function X(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 x extends y{kind;fieldPath;failMode;openFallback;constructor(t,e,i,n={}){super(X(t),e,i,n);this.name="FieldCryptoError",this.kind=t,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}}}function R(t){return typeof t==="function"}function K(t){if(typeof t!=="string")return;let e=t.trim();return e.length>0?e:void 0}function H(t,e,i){let n=t.fields[e];if(n)return n;if(e.startsWith("metadata.")){let r=t.fields["metadata.*"];if(r)return r}return i}function L(t,e={}){let i=[];if(!t||typeof t!=="object")return{valid:!1,issues:[{message:"fieldCrypto config must be an object",rule:"fieldCrypto.config.object",hint:"Provide a valid FieldCryptoConfig object"}]};if(!t.provider||typeof t.provider!=="object")i.push({message:"fieldCrypto provider is required",rule:"fieldCrypto.provider.required",path:"provider",hint:"Set provider with encrypt/decrypt/hash methods"});else{if(!R(t.provider.encrypt))i.push({message:"provider.encrypt must be a function",rule:"fieldCrypto.provider.encrypt.required",path:"provider.encrypt"});if(!R(t.provider.decrypt))i.push({message:"provider.decrypt must be a function",rule:"fieldCrypto.provider.decrypt.required",path:"provider.decrypt"});if(!R(t.provider.hash))i.push({message:"provider.hash must be a function",rule:"fieldCrypto.provider.hash.required",path:"provider.hash"})}if(!t.fields||typeof t.fields!=="object")i.push({message:"fieldCrypto.fields must be an object",rule:"fieldCrypto.fields.object",path:"fields",hint:"Define policies such as to, from, metadata.phoneNumber"});else{let s=Object.entries(t.fields);if(s.length===0)i.push({message:"fieldCrypto.fields must not be empty",rule:"fieldCrypto.fields.non_empty",path:"fields",hint:"Add at least one field mode mapping"});for(let[o,d]of s){if(!K(o))i.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")i.push({message:`unsupported field mode: ${String(d)}`,rule:"fieldCrypto.fields.mode.supported",path:`fields.${o}`})}}let n=t.failMode??"closed",r=t.openFallback??"masked";if(n==="open"&&r==="plaintext"&&t.unsafeAllowPlaintextStorage!==!0)i.push({message:"openFallback=plaintext requires unsafeAllowPlaintextStorage=true",rule:"fieldCrypto.fail_open.plaintext_guard",path:"openFallback",hint:"Use masked/null fallback, or explicitly enable unsafe plaintext"});if(Array.isArray(t.aadFields)){if(t.aadFields.length===0)i.push({message:"aadFields must not be empty when provided",rule:"fieldCrypto.aad_fields.non_empty",path:"aadFields"});for(let s=0;s<t.aadFields.length;s+=1){let o=t.aadFields[s];if(!K(o))i.push({message:"aadFields cannot include empty key",rule:"fieldCrypto.aad_fields.no_empty_key",path:`aadFields[${s}]`})}}if(e.secureMode&&!e.compatPlainColumns){let s=H(t,"to","encrypt+hash"),o=H(t,"from","encrypt+hash");if(s==="plain")i.push({message:"secure mode requires non-plain policy for `to` when compatPlainColumns=false",rule:"fieldCrypto.secure_mode.to_non_plain",path:"fields.to",hint:"Use encrypt+hash for lookup fields"});if(o==="plain")i.push({message:"secure mode requires non-plain policy for `from` when compatPlainColumns=false",rule:"fieldCrypto.secure_mode.from_non_plain",path:"fields.from",hint:"Use encrypt+hash for lookup fields"})}return{valid:i.length===0,issues:i}}function lt(t,e={}){let i=L(t,e);if(i.valid)return;let n=i.issues[0];if(!n)throw new x("config","fieldCrypto config validation failed",{rule:"fieldCrypto.config.invalid",issues:i.issues});throw new x("config",n.message,{rule:n.rule,path:n.path,hint:n.hint,issues:i.issues},{fieldPath:n.path})}function k(t){let e=t instanceof Uint8Array?t:new Uint8Array(t),i=typeof globalThis<"u"?globalThis.Buffer:void 0;return(i?i.from(e).toString("base64"):btoa(String.fromCharCode(...e))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function O(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),i=e.length%4===0?e:`${e}${"=".repeat(4-e.length%4)}`,n=typeof globalThis<"u"?globalThis.Buffer:void 0;if(n)return new Uint8Array(n.from(i,"base64"));let r=atob(i),s=new Uint8Array(r.length);for(let o=0;o<r.length;o+=1)s[o]=r.charCodeAt(o);return s}function $(t,e){if(t instanceof Uint8Array)return t;if(t instanceof ArrayBuffer)return new Uint8Array(t);if(e==="base64url")return O(t);return new TextEncoder().encode(t)}function z(t){let e=t instanceof Uint8Array?t:new Uint8Array(t);return Array.from(e).map((i)=>i.toString(16).padStart(2,"0")).join("")}function C(t){let e=new Uint8Array(t.byteLength);return e.set(t),e.buffer}function j(t){let e=JSON.parse(t);if(!e||typeof e!=="object"||typeof e.v!=="number"||typeof e.alg!=="string"||typeof e.kid!=="string"||typeof e.iv!=="string"||typeof e.tag!=="string"||typeof e.ct!=="string")throw Error("Invalid ciphertext envelope");return e}function tt(t){if(typeof t==="string")return t;return JSON.stringify(t)}function yt(t){if(!t||typeof t!=="object")return!1;let e=t;return typeof e.v==="number"&&typeof e.alg==="string"&&typeof e.kid==="string"&&typeof e.iv==="string"&&typeof e.tag==="string"&&typeof e.ct==="string"}function et(t){let e=String(t??"").trim();if(e.length===0)return"";let i=e.startsWith("+"),n=e.replace(/\D/g,"");return i?`+${n}`:n}function G(t=3,e=2){return(i)=>{let n=String(i??"");if(n.length<=t+e)return"*".repeat(Math.max(0,n.length));let r=n.slice(0,t),s=n.slice(-e);return`${r}${"*".repeat(n.length-t-e)}${s}`}}function ut(t){let e=t.algorithm??"A256GCM",i=t.keyEncoding??"base64url",n=t.hashKeyEncoding??i,r=new Map,s=new Map,o=(p)=>{let c=r.get(p);if(c)return c;let f=t.keys[p];if(!f)throw Error(`Unknown encryption key id: ${p}`);let l=$(f,i),h=crypto.subtle.importKey("raw",C(l),"AES-GCM",!1,["encrypt","decrypt"]);return r.set(p,h),h},d=(p)=>{let c=s.get(p);if(c)return c;let f=t.hashKeys?.[p]??t.keys[p];if(!f)throw Error(`Unknown hash key id: ${p}`);let l=$(f,n),h=crypto.subtle.importKey("raw",C(l),{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return s.set(p,h),h};return{async encrypt(p){let c=p.kid??t.activeKid,f=await o(c),l=crypto.getRandomValues(new Uint8Array(12)),h=new TextEncoder().encode(JSON.stringify(p.aad??{})),u=new TextEncoder().encode(p.value),m=await crypto.subtle.encrypt({name:"AES-GCM",iv:C(l),additionalData:C(h),tagLength:128},f,C(u)),b=new Uint8Array(m),a=b.slice(b.length-16),E=b.slice(0,b.length-16);return{ciphertext:{v:1,alg:e,kid:c,iv:k(l),tag:k(a),ct:k(E)},kid:c}},async decrypt(p){let c=j(p.ciphertext),f=p.candidateKids&&p.candidateKids.length>0?p.candidateKids:[c.kid],l=O(c.iv),h=O(c.tag),u=O(c.ct),m=new Uint8Array(u.length+h.length);m.set(u,0),m.set(h,u.length);let b=new TextEncoder().encode(JSON.stringify(p.aad??{})),a;for(let E of f)try{let T=await o(E),Z=await crypto.subtle.decrypt({name:"AES-GCM",iv:C(l),additionalData:C(b),tagLength:128},T,C(m));return new TextDecoder().decode(new Uint8Array(Z))}catch(T){a=T}throw Error(`Failed to decrypt ciphertext: ${a instanceof Error?a.message:String(a??"unknown")}`)},async hash(p){let c=p.kid??t.activeKid,f=await d(c),l=await crypto.subtle.sign("HMAC",f,C(new TextEncoder().encode(p.value)));return z(l)},mask(p){return G()(p.value)}}}function mt(){return{encrypt(t){return{ciphertext:JSON.stringify({v:1,alg:"NOOP",kid:"noop",iv:"",tag:"",ct:t.value})}},decrypt(t){try{return j(t.ciphertext).ct}catch{return t.ciphertext}},hash(t){let e=et(t.value);return k(new TextEncoder().encode(e))},mask(t){return G()(t.value)}}}function Ct(t){return tt(t)}var it;((r)=>{r.DEBUG="DEBUG";r.INFO="INFO";r.WARN="WARN";r.ERROR="ERROR"})(it||={});var nt=["to","from","phone","phoneNumber","recipient","sender","secret","apiKey","apiSecret","authorization","auth","token","password","payload","message","content","text"];function rt(t){let e=t.toLowerCase();return nt.some((i)=>e.includes(i.toLowerCase()))}function st(t){let e=t.trim();if(e.length<=4)return"***";if(e.includes("@")){let[r,s]=e.split("@");return`${r.slice(0,2)}${"*".repeat(Math.max(1,r.length-2))}@${s}`}let i=e.slice(0,3),n=e.slice(-2);return`${i}${"*".repeat(Math.max(1,e.length-5))}${n}`}function S(t,e){if(e===void 0||e===null)return e;if(rt(t)){if(typeof e==="string")return st(e);if(typeof e==="number"||typeof e==="boolean")return"***";if(Array.isArray(e))return"[REDACTED]";if(typeof e==="object")return"[REDACTED]"}if(Array.isArray(e))return e.map((i)=>S(t,i));if(typeof e==="object"){let i={};for(let[n,r]of Object.entries(e))i[n]=S(n,r);return i}return e}function ot(t){let e={};for(let[i,n]of Object.entries(t))e[i]=S(i,n);return e}class I{config;context;constructor(t={},e={}){this.context=t,this.config={level:"INFO",enableConsole:!0,enableJson:!1,enableColors:!0,...e}}shouldLog(t){let e=["DEBUG","INFO","WARN","ERROR"];return e.indexOf(t)>=e.indexOf(this.config.level)}formatMessage(t){let e=ot(t.context);if(this.config.enableJson)return JSON.stringify({level:t.level,message:t.message,timestamp:t.timestamp.toISOString(),context:e,...t.error&&{error:{name:t.error.name,message:t.error.message,stack:t.error.stack}},...t.duration&&{duration:t.duration}});let i=t.timestamp.toISOString(),n=this.config.enableColors?this.colorizeLevel(t.level):t.level,r=Object.keys(e).length>0?` [${Object.entries(e).map(([o,d])=>`${o}=${d}`).join(", ")}]`:"",s=`${i} ${n}${r}: ${t.message}`;if(t.duration!==void 0)s+=` (${t.duration}ms)`;if(t.error)s+=`
|
|
2
|
-
${
|
|
1
|
+
var A;((d)=>{d.INVALID_REQUEST="INVALID_REQUEST";d.AUTHENTICATION_FAILED="AUTHENTICATION_FAILED";d.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE";d.TEMPLATE_NOT_FOUND="TEMPLATE_NOT_FOUND";d.RATE_LIMIT_EXCEEDED="RATE_LIMIT_EXCEEDED";d.NETWORK_ERROR="NETWORK_ERROR";d.NETWORK_TIMEOUT="NETWORK_TIMEOUT";d.NETWORK_SERVICE_UNAVAILABLE="NETWORK_SERVICE_UNAVAILABLE";d.PROVIDER_ERROR="PROVIDER_ERROR";d.MESSAGE_SEND_FAILED="MESSAGE_SEND_FAILED";d.CRYPTO_CONFIG_ERROR="CRYPTO_CONFIG_ERROR";d.CRYPTO_ENCRYPT_FAILED="CRYPTO_ENCRYPT_FAILED";d.CRYPTO_DECRYPT_FAILED="CRYPTO_DECRYPT_FAILED";d.CRYPTO_HASH_FAILED="CRYPTO_HASH_FAILED";d.CRYPTO_POLICY_VIOLATION="CRYPTO_POLICY_VIOLATION";d.UNKNOWN_ERROR="UNKNOWN_ERROR"})(A||={});var $=new Set(["NETWORK_ERROR","RATE_LIMIT_EXCEEDED","NETWORK_TIMEOUT","NETWORK_SERVICE_UNAVAILABLE","PROVIDER_ERROR","UNKNOWN_ERROR"]),j=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"]),C=(e)=>{if(typeof e!=="number"||Number.isNaN(e)||!Number.isFinite(e))return;return Math.trunc(e)},G=(e)=>{let t=C(e);if(t===void 0||t<0)return;return t},D=(e)=>{if(typeof e!=="string")return;return e.toLowerCase().trim()},J=(e)=>{if(e>=500)return"retryable";if(e===408||e===425||e===429)return"retryable";return"non_retryable"},V=(e)=>{let t=e.toLowerCase();if(t.includes("timeout")||t.includes("temporar")||t.includes("network")||t.includes("retry"))return"retryable";return};class u extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(e,t,r,i={}){super(t);if(this.name="KMsgError",this.code=e,this.details=r,this.providerErrorCode=i.providerErrorCode,this.providerErrorText=i.providerErrorText,this.httpStatus=C(i.httpStatus),this.requestId=typeof i.requestId==="string"?i.requestId:void 0,this.retryAfterMs=C(i.retryAfterMs),this.attempt=C(i.attempt),Array.isArray(i.causeChain))this.causeChain=i.causeChain;else if(i.causeChain!==void 0)this.causeChain=[i.causeChain];if(Error.captureStackTrace)Error.captureStackTrace(this,u)}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 v={isRetryable(e,t={}){return v.classifyForRetry(e,t)==="retryable"},classifyForRetry(e,t={}){if(e instanceof u){if(new Set(t.retryableCodes??Array.from($)).has(e.code))return"retryable";if(new Set(t.nonRetryableCodes??Array.from(j)).has(e.code))return"non_retryable";if(e.httpStatus!==void 0)return J(e.httpStatus);let a=V(e.message);if(a)return a;if(t.classifyByMessage&&e.message){let c=t.classifyByMessage(e.message);if(c)return c}if(t.fallback)return t.fallback;return"non_retryable"}let r=e&&typeof e==="object"?e:void 0,i=D(r?.status)??D(r?.statusCode)??D(r?.code),n=C(r?.status)??C(r?.statusCode)??C(r?.httpStatus);if(typeof i==="string"&&i.startsWith("5"))return"retryable";if(n!==void 0){if(t.classifyByStatusCode)return t.classifyByStatusCode(n);return J(n)}let s=typeof r?.message==="string"?V(r.message):void 0;if(s)return s;if(t.classifyByMessage&&typeof r?.message==="string"){let o=t.classifyByMessage(r.message);if(o)return o}return t.fallback??"non_retryable"},resolveRetryAfterMs(e,t){if(t?.retryAfterMs){let r=t.retryAfterMs(e),i=G(r);if(i!==void 0)return i}if(e.retryAfterMs!==void 0)return G(e.retryAfterMs);if(e.code==="RATE_LIMIT_EXCEEDED"&&e.retryAfterMs===void 0)return;return},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 u(e.code,e.message,e.details,{...v.toRetryMetadata(e),attempt:C(t)})},DEFAULT_RETRYABLE_ERROR_CODES:$,DEFAULT_NON_RETRYABLE_ERROR_CODES:j};function pe(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 P extends u{kind;fieldPath;failMode;openFallback;constructor(e,t,r,i={}){super(pe(e),t,r,i);this.name="FieldCryptoError",this.kind=e,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 ce=["tenantId","providerId","messageId"];function S(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function de(e){if(typeof e!=="number"||!Number.isFinite(e))return;if(e<=0||e>100)return;return e}function Y(e){let t=[];for(let r of e){let i=S(r.kid),n=de(r.percentage);if(!i||n===void 0)continue;t.push({kid:i,percentage:n})}return t}function le(e,t,r){let i=t.map((n)=>{let s=e[n];return typeof s==="string"?s:""}).join("|");return`${r}::${i}`}function ye(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 fe(e,t){let r=0;for(let i of e)if(r+=i.percentage,t<r)return i.kid;return}function I(e,t,r){let i=Y(t.buckets),n=S(t.defaultKid)??S(r);if(i.length===0)return n;let s=S(t.seed)??"kmsg-rollout-v1",o=t.stickyFields??ce,p=le(e,o,s),a=ye(p)%100;return fe(i,a)??n}function W(e){return Y(e.buckets).map((t)=>t.kid)}function b(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function _(e){if(!Array.isArray(e))return[];return e.map((t)=>b(t)).filter((t)=>Boolean(t))}function B(e){let t=[],r=new Set;for(let i of e){let n=b(i);if(!n||r.has(n))continue;r.add(n),t.push(n)}return t}function ue(e){return b(e.providerId)??"default"}function Q(e){let t=b(e.activeKid)??"default",r=B([t,..._(e.decryptKids)]);return{async resolveEncryptKey(){return{kid:t}},async resolveDecryptKeys(){return r}}}function k(e){let t=typeof e.cacheTtlMs==="number"&&e.cacheTtlMs>=0?Math.trunc(e.cacheTtlMs):30000,r=b(e.fallback?.activeKid),i=_(e.fallback?.decryptKids),n;async function s(o){let p=Date.now();if(n&&p<n.expiresAt)return n.value;let a=await e.provider.loadKeySet(o),c=b(a.activeKid)??r??ue(o),l=B([c,..._(a.decryptKids),...i]),y={activeKid:c,decryptKids:l,refreshedAt:Date.now()};return n={value:y,expiresAt:Date.now()+t},y}return{async resolveEncryptKey(o){return{kid:(await s(o)).activeKid}},async resolveDecryptKeys(o){let p=await s(o);return p.decryptKids??[p.activeKid]}}}function Me(e,t){return{async resolveEncryptKey(r){let i=await e.resolveEncryptKey(r);return{kid:I(r,t,i.kid)??i.kid}},async resolveDecryptKeys(r){let i=await e.resolveEncryptKey(r),n=e.resolveDecryptKeys?await e.resolveDecryptKeys(r):[i.kid],s=I(r,t,i.kid),o=W(t);return B([...s?[s]:[],i.kid,...n??[],...o])}}}function De(e){return k({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 R(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function Z(e,t){return R(e[t])}function he(e,t){if(!e)return[];return e.split(t).map((r)=>R(r)).filter((r)=>Boolean(r))}function Be(e={}){let t=e.env??(typeof process<"u"?process.env:{}),r=R(e.delimiter)??",",i=e.activeKidEnv??"KMSG_ACTIVE_KID",n=e.decryptKidsEnv??"KMSG_DECRYPT_KIDS",s=Z(t,i)??R(e.fallbackActiveKid)??"default",o=[s,...he(Z(t,n),r),...e.fallbackDecryptKids??[]];return Q({activeKid:s,decryptKids:o})}function qe(e){return k({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 N(e){return typeof e==="function"}function X(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function L(e,t,r){let i=e.fields[t];if(i)return i;if(t.startsWith("metadata.")){let n=e.fields["metadata.*"];if(n)return n}return r}function me(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(!N(e.provider.encrypt))r.push({message:"provider.encrypt must be a function",rule:"fieldCrypto.provider.encrypt.required",path:"provider.encrypt"});if(!N(e.provider.decrypt))r.push({message:"provider.decrypt must be a function",rule:"fieldCrypto.provider.decrypt.required",path:"provider.decrypt"});if(!N(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 s=Object.entries(e.fields);if(s.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[o,p]of s){if(!X(o))r.push({message:"field path must be a non-empty string",rule:"fieldCrypto.fields.path.non_empty",path:"fields"});if(p!=="plain"&&p!=="encrypt"&&p!=="encrypt+hash"&&p!=="mask")r.push({message:`unsupported field mode: ${String(p)}`,rule:"fieldCrypto.fields.mode.supported",path:`fields.${o}`})}}let i=e.failMode??"closed",n=e.openFallback??"masked";if(i==="open"&&n==="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 s=0;s<e.aadFields.length;s+=1){let o=e.aadFields[s];if(!X(o))r.push({message:"aadFields cannot include empty key",rule:"fieldCrypto.aad_fields.no_empty_key",path:`aadFields[${s}]`})}}if(t.secureMode&&!t.compatPlainColumns){let s=L(e,"to","encrypt+hash"),o=L(e,"from","encrypt+hash");if(s==="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(o==="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 je(e,t={}){let r=me(e,t);if(r.valid)return;let i=r.issues[0];if(!i)throw new P("config","fieldCrypto config validation failed",{rule:"fieldCrypto.config.invalid",issues:r.issues});throw new P("config",i.message,{rule:i.rule,path:i.path,hint:i.hint,issues:r.issues},{fieldPath:i.path})}function x(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 O(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),r=t.length%4===0?t:`${t}${"=".repeat(4-t.length%4)}`,i=typeof globalThis<"u"?globalThis.Buffer:void 0;if(i)return new Uint8Array(i.from(r,"base64"));let n=atob(r),s=new Uint8Array(n.length);for(let o=0;o<n.length;o+=1)s[o]=n.charCodeAt(o);return s}function z(e,t){if(e instanceof Uint8Array)return e;if(e instanceof ArrayBuffer)return new Uint8Array(e);if(t==="base64url")return O(e);return new TextEncoder().encode(e)}function ge(e){let t=e instanceof Uint8Array?e:new Uint8Array(e);return Array.from(t).map((r)=>r.toString(16).padStart(2,"0")).join("")}function g(e){let t=new Uint8Array(e.byteLength);return t.set(e),t.buffer}function ee(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 Ce(e){if(typeof e==="string")return e;return JSON.stringify(e)}function Je(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 Ke(e){let t=String(e??"").trim();if(t.length===0)return"";let r=t.startsWith("+"),i=t.replace(/\D/g,"");return r?`+${i}`:i}function te(e=3,t=2){return(r)=>{let i=String(r??"");if(i.length<=e+t)return"*".repeat(Math.max(0,i.length));let n=i.slice(0,e),s=i.slice(-t);return`${n}${"*".repeat(i.length-e-t)}${s}`}}function Ve(e){let t=e.algorithm??"A256GCM",r=e.keyEncoding??"base64url",i=e.hashKeyEncoding??r,n=new Map,s=new Map,o=(a)=>{let c=n.get(a);if(c)return c;let l=e.keys[a];if(!l)throw Error(`Unknown encryption key id: ${a}`);let y=z(l,r),f=crypto.subtle.importKey("raw",g(y),"AES-GCM",!1,["encrypt","decrypt"]);return n.set(a,f),f},p=(a)=>{let c=s.get(a);if(c)return c;let l=e.hashKeys?.[a]??e.keys[a];if(!l)throw Error(`Unknown hash key id: ${a}`);let y=z(l,i),f=crypto.subtle.importKey("raw",g(y),{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return s.set(a,f),f};return{async encrypt(a){let c=a.kid??e.activeKid,l=await o(c),y=crypto.getRandomValues(new Uint8Array(12)),f=new TextEncoder().encode(JSON.stringify(a.aad??{})),h=new TextEncoder().encode(a.value),m=await crypto.subtle.encrypt({name:"AES-GCM",iv:g(y),additionalData:g(f),tagLength:128},l,g(h)),F=new Uint8Array(m),d=F.slice(F.length-16),E=F.slice(0,F.length-16);return{ciphertext:{v:1,alg:t,kid:c,iv:x(y),tag:x(d),ct:x(E)},kid:c}},async decrypt(a){let c=ee(a.ciphertext),l=a.candidateKids&&a.candidateKids.length>0?a.candidateKids:[c.kid],y=O(c.iv),f=O(c.tag),h=O(c.ct),m=new Uint8Array(h.length+f.length);m.set(h,0),m.set(f,h.length);let F=new TextEncoder().encode(JSON.stringify(a.aad??{})),d;for(let E of l)try{let T=await o(E),ae=await crypto.subtle.decrypt({name:"AES-GCM",iv:g(y),additionalData:g(F),tagLength:128},T,g(m));return new TextDecoder().decode(new Uint8Array(ae))}catch(T){d=T}throw Error(`Failed to decrypt ciphertext: ${d instanceof Error?d.message:String(d??"unknown")}`)},async hash(a){let c=a.kid??e.activeKid,l=await p(c),y=await crypto.subtle.sign("HMAC",l,g(new TextEncoder().encode(a.value)));return ge(y)},mask(a){return te()(a.value)}}}function Ye(){return{encrypt(e){return{ciphertext:JSON.stringify({v:1,alg:"NOOP",kid:"noop",iv:"",tag:"",ct:e.value})}},decrypt(e){try{return ee(e.ciphertext).ct}catch{return e.ciphertext}},hash(e){let t=Ke(e.value);return x(new TextEncoder().encode(t))},mask(e){return te()(e.value)}}}function We(e){return Ce(e)}var Fe;((n)=>{n.DEBUG="DEBUG";n.INFO="INFO";n.WARN="WARN";n.ERROR="ERROR"})(Fe||={});var be=["to","from","phone","phoneNumber","recipient","sender","secret","apiKey","apiSecret","authorization","auth","token","password","payload","message","content","text"];function we(e){let t=e.toLowerCase();return be.some((r)=>t.includes(r.toLowerCase()))}function ve(e){let t=e.trim();if(t.length<=4)return"***";if(t.includes("@")){let[n,s]=t.split("@");return`${n.slice(0,2)}${"*".repeat(Math.max(1,n.length-2))}@${s}`}let r=t.slice(0,3),i=t.slice(-2);return`${r}${"*".repeat(Math.max(1,t.length-5))}${i}`}function U(e,t){if(t===void 0||t===null)return t;if(we(e)){if(typeof t==="string")return ve(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)=>U(e,r));if(typeof t==="object"){let r={};for(let[i,n]of Object.entries(t))r[i]=U(i,n);return r}return t}function Ae(e){let t={};for(let[r,i]of Object.entries(e))t[r]=U(r,i);return t}class q{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=Ae(e.context);if(this.config.enableJson)return JSON.stringify({level:e.level,message:e.message,timestamp:e.timestamp.toISOString(),context:t,...e.error&&{error:{name:e.error.name,message:e.error.message,stack:e.error.stack}},...e.duration&&{duration:e.duration}});let r=e.timestamp.toISOString(),i=this.config.enableColors?this.colorizeLevel(e.level):e.level,n=Object.keys(t).length>0?` [${Object.entries(t).map(([o,p])=>`${o}=${p}`).join(", ")}]`:"",s=`${r} ${i}${n}: ${e.message}`;if(e.duration!==void 0)s+=` (${e.duration}ms)`;if(e.error)s+=`
|
|
2
|
+
${e.error.stack}`;return s}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 q({...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 i=Date.now(),n={...r,operation:e};this.debug(`Starting ${e}`,n);try{let s=await t(),o=Date.now()-i;return this.info(`Completed ${e}`,{...n,duration:o}),s}catch(s){let o=Date.now()-i;throw this.error(`Failed ${e}`,{...n,duration:o},s instanceof Error?s:Error(String(s))),s}}}var M;function re(e,t){return new q(e,t)}function K(){if(!M)M=re();return M}function Ze(e){M=e}var Xe={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 Le(e){let t=re({},e);return async(r,i)=>{let n=Date.now(),o={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",o);try{await i();let p=Date.now()-n;t.info("Request completed",{...o,status:r.res.status,duration:p})}catch(p){let a=Date.now()-n;throw t.error("Request failed",{...o,duration:a},p instanceof Error?p:Error(String(p))),p}}}class w{static defaultOptions={maxAttempts:3,initialDelay:1000,maxDelay:30000,backoffMultiplier:2,jitter:!0,retryCondition:(e)=>v.isRetryable(e)};static async execute(e,t={}){let r={...w.defaultOptions,...t},i,n=r.initialDelay;for(let s=1;s<=r.maxAttempts;s++)try{return await e()}catch(o){if(i=o,s===r.maxAttempts||!r.retryCondition(i,s))throw i;let p=r.jitter?n+Math.random()*n*0.1:n;r.onRetry?.(i,s),await new Promise((a)=>setTimeout(a,p)),n=Math.min(n*r.backoffMultiplier,r.maxDelay)}throw i}static createRetryableFunction(e,t={}){return async(...r)=>{return w.execute(()=>e(...r),t)}}}class H{static async execute(e,t,r={}){let i={concurrency:5,retryOptions:{maxAttempts:3,initialDelay:1000,maxDelay:1e4,backoffMultiplier:2,jitter:!0},failFast:!1,...r},n=Date.now(),s=[],o=[],p=0,a=w.createRetryableFunction(t,i.retryOptions),c=H.createBatches(e,i.concurrency);for(let y of c){let f=y.map(async(h)=>{try{let m=await a(h);s.push({item:h,result:m})}catch(m){if(o.push({item:h,error:m}),i.failFast)throw new u("MESSAGE_SEND_FAILED",`Bulk operation failed fast after ${o.length} failures`,{totalItems:e.length,failedCount:o.length})}finally{p++,i.onProgress?.(p,e.length,o.length)}});if(await Promise.allSettled(f),i.failFast&&o.length>0)break}let l=Date.now()-n;return{successful:s,failed:o,summary:{total:e.length,successful:s.length,failed:o.length,duration:l}}}static createBatches(e,t){let r=[];for(let i=0;i<e.length;i+=t)r.push(e.slice(i,i+t));return r}}class ie{options;state="CLOSED";failureCount=0;lastFailureTime=0;nextAttemptTime=0;constructor(e){this.options=e}async execute(e){let t=Date.now();switch(this.state){case"OPEN":if(t<this.nextAttemptTime)throw new u("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 r=await Promise.race([e(),new Promise((i,n)=>setTimeout(()=>n(new u("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 r}catch(r){throw this.recordFailure(),r}}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 ne{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((i)=>setTimeout(i,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 se=(e)=>({isSuccess:!0,isFailure:!1,value:e}),oe=(e)=>({isSuccess:!1,isFailure:!0,error:e}),ft={map(e,t){if(e.isSuccess)return se(t(e.value));return e},flatMap(e,t){if(e.isSuccess)return t(e.value);return e},mapError(e,t){if(e.isFailure)return oe(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 se(t)}catch(t){return oe(t)}},isOk(e){return e.isSuccess},isFail(e){return e.isFailure}};function Pe(){let e=globalThis;return e.__K_MSG_ENV__??e.__ENV__??e.process?.env??{}}function ht(e){let t=Pe()[e];if(typeof t==="string")return t;if(t===void 0)return;return String(t)}var gt=["PENDING","SENT","FAILED"],Ct="PENDING",Kt=(e)=>{let t=typeof e==="string"?e.trim().toUpperCase():"";if(t==="PENDING"||t==="SENT"||t==="FAILED")return t;return"PENDING"};export{me as validateFieldCryptoConfig,We as toCiphertextEnvelopeString,Ze as setGlobalLogger,I as selectActiveKidByRollout,L as resolveFieldMode,ht as readRuntimeEnv,se as ok,G as normalizeRetryAfterMs,Ke as normalizePhoneForHash,Kt as normalizeMessageStatus,Le as loggerMiddleware,Xe as logger,Je as isCryptoEnvelope,Pe as getRuntimeEnvSource,W as getRolloutKnownKids,K as getLogger,oe as fail,qe as createVaultTransitKeyResolver,Q as createStaticKeyResolver,Me as createRollingKeyResolver,k as createRefreshableKeyResolver,Ye as createNoopFieldCryptoProvider,re as createLogger,Be as createEnvKeyResolver,te as createDefaultMasker,De as createAwsKmsKeyResolver,Ve as createAesGcmFieldCryptoProvider,je as assertFieldCryptoConfig,w as RetryHandler,ft as Result,ne as RateLimiter,Ct as QUEUED_MESSAGE_STATUS,q as Logger,Fe as LogLevel,gt as KNOWN_MESSAGE_STATUSES,A as KMsgErrorCode,u as KMsgError,P as FieldCryptoError,v as ErrorUtils,ie as CircuitBreaker,H as BulkOperationHandler};
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
4
|
+
//# debugId=7D63913E6C8742B764756E2164756E21
|
|
5
5
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/errors.ts", "../src/crypto/errors.ts", "../src/crypto/policy.ts", "../src/crypto/types.ts", "../src/logger.ts", "../src/resilience/retry-handler.ts", "../src/resilience/bulk-operation.ts", "../src/resilience/circuit-breaker.ts", "../src/resilience/rate-limiter.ts", "../src/result.ts", "../src/runtime/env.ts", "../src/types/message.ts"],
|
|
3
|
+
"sources": ["../src/errors.ts", "../src/crypto/errors.ts", "../src/crypto/rollout-policy.ts", "../src/crypto/key-resolver.ts", "../src/crypto/key-adapters/aws-kms.ts", "../src/crypto/key-adapters/env.ts", "../src/crypto/key-adapters/vault-transit.ts", "../src/crypto/policy.ts", "../src/crypto/types.ts", "../src/logger.ts", "../src/resilience/retry-handler.ts", "../src/resilience/bulk-operation.ts", "../src/resilience/circuit-breaker.ts", "../src/resilience/rate-limiter.ts", "../src/result.ts", "../src/runtime/env.ts", "../src/types/message.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"export enum KMsgErrorCode {\n INVALID_REQUEST = \"INVALID_REQUEST\",\n AUTHENTICATION_FAILED = \"AUTHENTICATION_FAILED\",\n INSUFFICIENT_BALANCE = \"INSUFFICIENT_BALANCE\",\n TEMPLATE_NOT_FOUND = \"TEMPLATE_NOT_FOUND\",\n RATE_LIMIT_EXCEEDED = \"RATE_LIMIT_EXCEEDED\",\n NETWORK_ERROR = \"NETWORK_ERROR\",\n NETWORK_TIMEOUT = \"NETWORK_TIMEOUT\",\n NETWORK_SERVICE_UNAVAILABLE = \"NETWORK_SERVICE_UNAVAILABLE\",\n PROVIDER_ERROR = \"PROVIDER_ERROR\",\n MESSAGE_SEND_FAILED = \"MESSAGE_SEND_FAILED\",\n CRYPTO_CONFIG_ERROR = \"CRYPTO_CONFIG_ERROR\",\n CRYPTO_ENCRYPT_FAILED = \"CRYPTO_ENCRYPT_FAILED\",\n CRYPTO_DECRYPT_FAILED = \"CRYPTO_DECRYPT_FAILED\",\n CRYPTO_HASH_FAILED = \"CRYPTO_HASH_FAILED\",\n CRYPTO_POLICY_VIOLATION = \"CRYPTO_POLICY_VIOLATION\",\n UNKNOWN_ERROR = \"UNKNOWN_ERROR\",\n}\n\nexport type RetryPolicyErrorCode = KMsgErrorCode;\n\nexport type ProviderRetryHint = \"retryable\" | \"non_retryable\";\n\nexport interface KMsgErrorMetadata {\n providerErrorCode?: string;\n providerErrorText?: string;\n httpStatus?: number;\n requestId?: string;\n retryAfterMs?: number;\n attempt?: number;\n causeChain?: unknown[];\n}\n\nexport interface ErrorRetryPolicy {\n retryableCodes?: readonly KMsgErrorCode[];\n nonRetryableCodes?: readonly KMsgErrorCode[];\n classifyByStatusCode?: (status: number) => ProviderRetryHint;\n classifyByMessage?: (message: string) => ProviderRetryHint | undefined;\n /**\n * Optional override for retry hint inference.\n */\n fallback?: ProviderRetryHint;\n /**\n * Optional custom retry delay in milliseconds.\n */\n retryAfterMs?: (error: KMsgError) => number | undefined;\n}\n\nconst DEFAULT_RETRYABLE_ERROR_CODES: ReadonlySet<RetryPolicyErrorCode> =\n new Set([\n KMsgErrorCode.NETWORK_ERROR,\n KMsgErrorCode.RATE_LIMIT_EXCEEDED,\n KMsgErrorCode.NETWORK_TIMEOUT,\n KMsgErrorCode.NETWORK_SERVICE_UNAVAILABLE,\n KMsgErrorCode.PROVIDER_ERROR,\n KMsgErrorCode.UNKNOWN_ERROR,\n ]);\n\nconst DEFAULT_NON_RETRYABLE_ERROR_CODES: ReadonlySet<RetryPolicyErrorCode> =\n new Set([\n KMsgErrorCode.INVALID_REQUEST,\n KMsgErrorCode.AUTHENTICATION_FAILED,\n KMsgErrorCode.INSUFFICIENT_BALANCE,\n KMsgErrorCode.TEMPLATE_NOT_FOUND,\n KMsgErrorCode.MESSAGE_SEND_FAILED,\n KMsgErrorCode.CRYPTO_CONFIG_ERROR,\n KMsgErrorCode.CRYPTO_ENCRYPT_FAILED,\n KMsgErrorCode.CRYPTO_DECRYPT_FAILED,\n KMsgErrorCode.CRYPTO_HASH_FAILED,\n KMsgErrorCode.CRYPTO_POLICY_VIOLATION,\n ]);\n\nconst normalizeNumber = (value: unknown): number | undefined => {\n if (\n typeof value !== \"number\" ||\n Number.isNaN(value) ||\n !Number.isFinite(value)\n ) {\n return undefined;\n }\n\n return Math.trunc(value);\n};\n\nexport const normalizeRetryAfterMs = (value: unknown): number | undefined => {\n const normalized = normalizeNumber(value);\n if (normalized === undefined || normalized < 0) {\n return undefined;\n }\n\n return normalized;\n};\n\nconst toLowerString = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n return value.toLowerCase().trim();\n};\n\nconst classifyByHttpStatus = (status: number): ProviderRetryHint => {\n if (status >= 500) {\n return \"retryable\";\n }\n\n if (status === 408 || status === 425 || status === 429) {\n return \"retryable\";\n }\n\n return \"non_retryable\";\n};\n\nconst classifyByMessage = (message: string): ProviderRetryHint | undefined => {\n const normalized = message.toLowerCase();\n\n if (\n normalized.includes(\"timeout\") ||\n normalized.includes(\"temporar\") ||\n normalized.includes(\"network\") ||\n normalized.includes(\"retry\")\n ) {\n return \"retryable\";\n }\n\n return undefined;\n};\n\nexport class KMsgError extends Error {\n public readonly code: KMsgErrorCode;\n public readonly details?: Record<string, unknown>;\n public readonly providerErrorCode?: string;\n public readonly providerErrorText?: string;\n public readonly httpStatus?: number;\n public readonly requestId?: string;\n public readonly retryAfterMs?: number;\n public readonly attempt?: number;\n public readonly causeChain?: unknown[];\n\n constructor(\n code: KMsgErrorCode,\n message: string,\n details?: Record<string, unknown>,\n metadata: KMsgErrorMetadata = {},\n ) {\n super(message);\n this.name = \"KMsgError\";\n this.code = code;\n this.details = details;\n\n this.providerErrorCode = metadata.providerErrorCode;\n this.providerErrorText = metadata.providerErrorText;\n this.httpStatus = normalizeNumber(metadata.httpStatus);\n this.requestId =\n typeof metadata.requestId === \"string\" ? metadata.requestId : undefined;\n this.retryAfterMs = normalizeNumber(metadata.retryAfterMs);\n this.attempt = normalizeNumber(metadata.attempt);\n\n if (Array.isArray(metadata.causeChain)) {\n this.causeChain = metadata.causeChain;\n } else if (metadata.causeChain !== undefined) {\n this.causeChain = [metadata.causeChain];\n }\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, KMsgError);\n }\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n details: this.details,\n providerErrorCode: this.providerErrorCode,\n providerErrorText: this.providerErrorText,\n httpStatus: this.httpStatus,\n requestId: this.requestId,\n retryAfterMs: this.retryAfterMs,\n attempt: this.attempt,\n causeChain: this.causeChain,\n };\n }\n}\n\nexport const ErrorUtils = {\n isRetryable(error: unknown, policy: ErrorRetryPolicy = {}): boolean {\n return ErrorUtils.classifyForRetry(error, policy) === \"retryable\";\n },\n\n classifyForRetry(\n error: unknown,\n policy: ErrorRetryPolicy = {},\n ): ProviderRetryHint {\n if (error instanceof KMsgError) {\n const retryableCodes = new Set(\n policy.retryableCodes ?? Array.from(DEFAULT_RETRYABLE_ERROR_CODES),\n );\n if (retryableCodes.has(error.code)) {\n return \"retryable\";\n }\n\n const nonRetryableCodes = new Set(\n policy.nonRetryableCodes ??\n Array.from(DEFAULT_NON_RETRYABLE_ERROR_CODES),\n );\n if (nonRetryableCodes.has(error.code)) {\n return \"non_retryable\";\n }\n\n if (error.httpStatus !== undefined) {\n return classifyByHttpStatus(error.httpStatus);\n }\n\n const classifiedByMessage = classifyByMessage(error.message);\n if (classifiedByMessage) {\n return classifiedByMessage;\n }\n\n if (policy.classifyByMessage && error.message) {\n const classified = policy.classifyByMessage(error.message);\n if (classified) {\n return classified;\n }\n }\n\n if (policy.fallback) {\n return policy.fallback;\n }\n\n return \"non_retryable\";\n }\n\n const candidate =\n error && typeof error === \"object\"\n ? (error as {\n status?: unknown;\n statusCode?: unknown;\n httpStatus?: unknown;\n code?: unknown;\n message?: unknown;\n })\n : undefined;\n\n const status =\n toLowerString(candidate?.status) ??\n toLowerString(candidate?.statusCode) ??\n toLowerString(candidate?.code);\n const statusCode =\n normalizeNumber(candidate?.status) ??\n normalizeNumber(candidate?.statusCode) ??\n normalizeNumber(candidate?.httpStatus);\n\n if (typeof status === \"string\" && status.startsWith(\"5\")) {\n return \"retryable\";\n }\n\n if (statusCode !== undefined) {\n if (policy.classifyByStatusCode) {\n return policy.classifyByStatusCode(statusCode);\n }\n\n return classifyByHttpStatus(statusCode);\n }\n\n const classifiedByMessage =\n typeof candidate?.message === \"string\"\n ? classifyByMessage(candidate.message)\n : undefined;\n\n if (classifiedByMessage) {\n return classifiedByMessage;\n }\n\n if (policy.classifyByMessage && typeof candidate?.message === \"string\") {\n const classified = policy.classifyByMessage(candidate.message);\n if (classified) {\n return classified;\n }\n }\n\n return policy.fallback ?? \"non_retryable\";\n },\n\n resolveRetryAfterMs(\n error: KMsgError,\n policy?: ErrorRetryPolicy,\n ): number | undefined {\n if (policy?.retryAfterMs) {\n const override = policy.retryAfterMs(error);\n const normalized = normalizeRetryAfterMs(override);\n if (normalized !== undefined) {\n return normalized;\n }\n }\n\n if (error.retryAfterMs !== undefined) {\n return normalizeRetryAfterMs(error.retryAfterMs);\n }\n\n if (\n error.code === KMsgErrorCode.RATE_LIMIT_EXCEEDED &&\n error.retryAfterMs === undefined\n ) {\n return undefined;\n }\n\n return undefined;\n },\n\n isUnknownStatus: (statusCode: number | undefined): boolean => {\n if (\n statusCode === undefined ||\n Number.isNaN(statusCode) ||\n !Number.isFinite(statusCode)\n ) {\n return false;\n }\n\n return statusCode < 500;\n },\n\n toRetryMetadata(error: KMsgError): KMsgErrorMetadata {\n return {\n providerErrorCode: error.providerErrorCode,\n providerErrorText: error.providerErrorText,\n httpStatus: error.httpStatus,\n requestId: error.requestId,\n retryAfterMs: error.retryAfterMs,\n attempt: error.attempt,\n causeChain: error.causeChain,\n };\n },\n\n withAttempt(error: KMsgError, attempt: number): KMsgError {\n return new KMsgError(error.code, error.message, error.details, {\n ...ErrorUtils.toRetryMetadata(error),\n attempt: normalizeNumber(attempt),\n });\n },\n\n DEFAULT_RETRYABLE_ERROR_CODES,\n DEFAULT_NON_RETRYABLE_ERROR_CODES,\n};\n",
|
|
6
6
|
"import { KMsgError, KMsgErrorCode, type KMsgErrorMetadata } from \"../errors\";\nimport type { FieldCryptoFailMode, FieldCryptoOpenFallback } from \"./types\";\n\nexport type FieldCryptoErrorKind =\n | \"config\"\n | \"encrypt\"\n | \"decrypt\"\n | \"hash\"\n | \"policy\";\n\nfunction resolveCode(kind: FieldCryptoErrorKind): KMsgErrorCode {\n switch (kind) {\n case \"config\":\n return KMsgErrorCode.CRYPTO_CONFIG_ERROR;\n case \"encrypt\":\n return KMsgErrorCode.CRYPTO_ENCRYPT_FAILED;\n case \"decrypt\":\n return KMsgErrorCode.CRYPTO_DECRYPT_FAILED;\n case \"hash\":\n return KMsgErrorCode.CRYPTO_HASH_FAILED;\n case \"policy\":\n return KMsgErrorCode.CRYPTO_POLICY_VIOLATION;\n }\n}\n\nexport interface FieldCryptoErrorMetadata extends KMsgErrorMetadata {\n fieldPath?: string;\n failMode?: FieldCryptoFailMode;\n openFallback?: FieldCryptoOpenFallback;\n}\n\nexport class FieldCryptoError extends KMsgError {\n readonly kind: FieldCryptoErrorKind;\n readonly fieldPath?: string;\n readonly failMode?: FieldCryptoFailMode;\n readonly openFallback?: FieldCryptoOpenFallback;\n\n constructor(\n kind: FieldCryptoErrorKind,\n message: string,\n details?: Record<string, unknown>,\n metadata: FieldCryptoErrorMetadata = {},\n ) {\n super(resolveCode(kind), message, details, metadata);\n this.name = \"FieldCryptoError\";\n this.kind = kind;\n this.fieldPath =\n typeof metadata.fieldPath === \"string\" ? metadata.fieldPath : undefined;\n this.failMode = metadata.failMode;\n this.openFallback = metadata.openFallback;\n }\n\n override toJSON() {\n return {\n ...super.toJSON(),\n kind: this.kind,\n fieldPath: this.fieldPath,\n failMode: this.failMode,\n openFallback: this.openFallback,\n };\n }\n}\n",
|
|
7
|
+
"import type { FieldCryptoKeyContext } from \"./types\";\n\nexport interface ActiveKidRolloutBucket {\n kid: string;\n percentage: number;\n}\n\nexport interface ActiveKidRolloutPolicy {\n /**\n * Rollout targets in priority order.\n * Example: [{ kid: \"k-2026-02\", percentage: 25 }]\n */\n buckets: readonly ActiveKidRolloutBucket[];\n /**\n * Deterministic hash seed.\n */\n seed?: string;\n /**\n * Context keys used to build sticky rollout identity.\n */\n stickyFields?: readonly (keyof FieldCryptoKeyContext)[];\n /**\n * Fallback kid when no bucket matches.\n */\n defaultKid?: string;\n}\n\nconst DEFAULT_STICKY_FIELDS: readonly (keyof FieldCryptoKeyContext)[] = [\n \"tenantId\",\n \"providerId\",\n \"messageId\",\n];\n\nfunction normalizeKid(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction toUnitPercentage(value: unknown): number | undefined {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return undefined;\n if (value <= 0 || value > 100) return undefined;\n return value;\n}\n\nfunction sanitizeBuckets(\n buckets: readonly ActiveKidRolloutBucket[],\n): ActiveKidRolloutBucket[] {\n const next: ActiveKidRolloutBucket[] = [];\n for (const bucket of buckets) {\n const kid = normalizeKid(bucket.kid);\n const percentage = toUnitPercentage(bucket.percentage);\n if (!kid || percentage === undefined) continue;\n next.push({ kid, percentage });\n }\n return next;\n}\n\nfunction toStickyKey(\n context: FieldCryptoKeyContext,\n fields: readonly (keyof FieldCryptoKeyContext)[],\n seed: string,\n): string {\n const payload = fields\n .map((field) => {\n const value = context[field];\n return typeof value === \"string\" ? value : \"\";\n })\n .join(\"|\");\n return `${seed}::${payload}`;\n}\n\n/**\n * Deterministic FNV-1a 32-bit hash.\n */\nfunction hash32(input: string): number {\n let hash = 0x811c9dc5;\n for (let index = 0; index < input.length; index += 1) {\n hash ^= input.charCodeAt(index);\n hash = (hash * 0x01000193) >>> 0;\n }\n return hash >>> 0;\n}\n\nfunction resolveBucketKid(\n buckets: readonly ActiveKidRolloutBucket[],\n percentile: number,\n): string | undefined {\n let cursor = 0;\n for (const bucket of buckets) {\n cursor += bucket.percentage;\n if (percentile < cursor) {\n return bucket.kid;\n }\n }\n return undefined;\n}\n\nexport function selectActiveKidByRollout(\n context: FieldCryptoKeyContext,\n policy: ActiveKidRolloutPolicy,\n fallbackKid?: string,\n): string | undefined {\n const buckets = sanitizeBuckets(policy.buckets);\n const defaultKid =\n normalizeKid(policy.defaultKid) ?? normalizeKid(fallbackKid);\n\n if (buckets.length === 0) {\n return defaultKid;\n }\n\n const seed = normalizeKid(policy.seed) ?? \"kmsg-rollout-v1\";\n const stickyFields = policy.stickyFields ?? DEFAULT_STICKY_FIELDS;\n const stickyKey = toStickyKey(context, stickyFields, seed);\n const percentile = hash32(stickyKey) % 100;\n return resolveBucketKid(buckets, percentile) ?? defaultKid;\n}\n\nexport function getRolloutKnownKids(\n policy: ActiveKidRolloutPolicy,\n): readonly string[] {\n return sanitizeBuckets(policy.buckets).map((bucket) => bucket.kid);\n}\n",
|
|
8
|
+
"import {\n type ActiveKidRolloutPolicy,\n getRolloutKnownKids,\n selectActiveKidByRollout,\n} from \"./rollout-policy\";\nimport type { FieldCryptoKeyContext, KeyResolver, KeySetState } from \"./types\";\n\nexport interface StaticKeyResolverOptions {\n activeKid: string;\n decryptKids?: readonly string[];\n}\n\nexport interface KeySetStateProvider {\n loadKeySet(context: FieldCryptoKeyContext): Promise<KeySetState>;\n}\n\nexport interface RefreshableKeyResolverOptions {\n provider: KeySetStateProvider;\n cacheTtlMs?: number;\n fallback?: {\n activeKid?: string;\n decryptKids?: readonly string[];\n };\n}\n\ninterface CachedKeySetState {\n value: KeySetState;\n expiresAt: number;\n}\n\nfunction normalizeKid(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction normalizeKidList(value: readonly string[] | undefined): string[] {\n if (!Array.isArray(value)) return [];\n return value\n .map((kid) => normalizeKid(kid))\n .filter((kid): kid is string => Boolean(kid));\n}\n\nfunction dedupeKids(values: readonly string[]): string[] {\n const next: string[] = [];\n const seen = new Set<string>();\n for (const value of values) {\n const normalized = normalizeKid(value);\n if (!normalized || seen.has(normalized)) continue;\n seen.add(normalized);\n next.push(normalized);\n }\n return next;\n}\n\nfunction fallbackKidFromContext(context: FieldCryptoKeyContext): string {\n return normalizeKid(context.providerId) ?? \"default\";\n}\n\nexport function createStaticKeyResolver(\n options: StaticKeyResolverOptions,\n): KeyResolver {\n const activeKid = normalizeKid(options.activeKid) ?? \"default\";\n const decryptKids = dedupeKids([\n activeKid,\n ...normalizeKidList(options.decryptKids),\n ]);\n\n return {\n async resolveEncryptKey() {\n return { kid: activeKid };\n },\n async resolveDecryptKeys() {\n return decryptKids;\n },\n };\n}\n\nexport function createRefreshableKeyResolver(\n options: RefreshableKeyResolverOptions,\n): KeyResolver {\n const cacheTtlMs =\n typeof options.cacheTtlMs === \"number\" && options.cacheTtlMs >= 0\n ? Math.trunc(options.cacheTtlMs)\n : 30_000;\n\n const fallbackActiveKid = normalizeKid(options.fallback?.activeKid);\n const fallbackDecryptKids = normalizeKidList(options.fallback?.decryptKids);\n let cache: CachedKeySetState | undefined;\n\n async function load(context: FieldCryptoKeyContext): Promise<KeySetState> {\n const now = Date.now();\n if (cache && now < cache.expiresAt) {\n return cache.value;\n }\n\n const loaded = await options.provider.loadKeySet(context);\n const activeKid =\n normalizeKid(loaded.activeKid) ??\n fallbackActiveKid ??\n fallbackKidFromContext(context);\n\n const decryptKids = dedupeKids([\n activeKid,\n ...normalizeKidList(loaded.decryptKids),\n ...fallbackDecryptKids,\n ]);\n\n const next: KeySetState = {\n activeKid,\n decryptKids,\n refreshedAt: Date.now(),\n };\n cache = {\n value: next,\n expiresAt: Date.now() + cacheTtlMs,\n };\n return next;\n }\n\n return {\n async resolveEncryptKey(context) {\n const state = await load(context);\n return { kid: state.activeKid };\n },\n async resolveDecryptKeys(context) {\n const state = await load(context);\n return state.decryptKids ?? [state.activeKid];\n },\n };\n}\n\nexport function createRollingKeyResolver(\n baseResolver: KeyResolver,\n policy: ActiveKidRolloutPolicy,\n): KeyResolver {\n return {\n async resolveEncryptKey(context) {\n const base = await baseResolver.resolveEncryptKey(context);\n const selected = selectActiveKidByRollout(context, policy, base.kid);\n return {\n kid: selected ?? base.kid,\n };\n },\n async resolveDecryptKeys(context) {\n const baseEncrypt = await baseResolver.resolveEncryptKey(context);\n const baseDecrypt = baseResolver.resolveDecryptKeys\n ? await baseResolver.resolveDecryptKeys(context)\n : [baseEncrypt.kid];\n const selected = selectActiveKidByRollout(\n context,\n policy,\n baseEncrypt.kid,\n );\n const rolloutKids = getRolloutKnownKids(policy);\n\n return dedupeKids([\n ...(selected ? [selected] : []),\n baseEncrypt.kid,\n ...(baseDecrypt ?? []),\n ...rolloutKids,\n ]);\n },\n };\n}\n",
|
|
9
|
+
"import {\n createRefreshableKeyResolver,\n type KeySetStateProvider,\n} from \"../key-resolver\";\nimport type { FieldCryptoKeyContext, KeyResolver, KeySetState } from \"../types\";\n\nexport interface AwsKmsKeyResolverClient {\n getKeyState(\n context: FieldCryptoKeyContext & {\n keyAlias?: string;\n region?: string;\n },\n ): Promise<KeySetState>;\n}\n\nexport interface AwsKmsKeyResolverOptions {\n client: AwsKmsKeyResolverClient;\n keyAlias?: string;\n region?: string;\n cacheTtlMs?: number;\n fallbackActiveKid?: string;\n fallbackDecryptKids?: readonly string[];\n}\n\nexport function createAwsKmsKeyResolver(\n options: AwsKmsKeyResolverOptions,\n): KeyResolver {\n const provider: KeySetStateProvider = {\n async loadKeySet(context) {\n return options.client.getKeyState({\n ...context,\n ...(options.keyAlias ? { keyAlias: options.keyAlias } : {}),\n ...(options.region ? { region: options.region } : {}),\n });\n },\n };\n\n return createRefreshableKeyResolver({\n provider,\n cacheTtlMs: options.cacheTtlMs,\n fallback: {\n activeKid: options.fallbackActiveKid,\n decryptKids: options.fallbackDecryptKids,\n },\n });\n}\n",
|
|
10
|
+
"import { createStaticKeyResolver } from \"../key-resolver\";\nimport type { KeyResolver } from \"../types\";\n\nexport interface EnvKeyResolverOptions {\n env?: Record<string, string | undefined>;\n activeKidEnv?: string;\n decryptKidsEnv?: string;\n fallbackActiveKid?: string;\n fallbackDecryptKids?: readonly string[];\n delimiter?: string;\n}\n\nfunction normalize(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction resolveEnv(\n env: Record<string, string | undefined>,\n key: string,\n): string | undefined {\n return normalize(env[key]);\n}\n\nfunction parseKids(raw: string | undefined, delimiter: string): string[] {\n if (!raw) return [];\n return raw\n .split(delimiter)\n .map((item) => normalize(item))\n .filter((item): item is string => Boolean(item));\n}\n\nexport function createEnvKeyResolver(\n options: EnvKeyResolverOptions = {},\n): KeyResolver {\n const envSource =\n options.env ??\n ((typeof process !== \"undefined\" ? process.env : {}) as Record<\n string,\n string | undefined\n >);\n const delimiter = normalize(options.delimiter) ?? \",\";\n const activeKidEnv = options.activeKidEnv ?? \"KMSG_ACTIVE_KID\";\n const decryptKidsEnv = options.decryptKidsEnv ?? \"KMSG_DECRYPT_KIDS\";\n\n const activeKid =\n resolveEnv(envSource, activeKidEnv) ??\n normalize(options.fallbackActiveKid) ??\n \"default\";\n const decryptKids = [\n activeKid,\n ...parseKids(resolveEnv(envSource, decryptKidsEnv), delimiter),\n ...(options.fallbackDecryptKids ?? []),\n ];\n\n return createStaticKeyResolver({\n activeKid,\n decryptKids,\n });\n}\n",
|
|
11
|
+
"import {\n createRefreshableKeyResolver,\n type KeySetStateProvider,\n} from \"../key-resolver\";\nimport type { FieldCryptoKeyContext, KeyResolver, KeySetState } from \"../types\";\n\nexport interface VaultTransitKeyResolverClient {\n getKeyState(\n context: FieldCryptoKeyContext & {\n mountPath?: string;\n keyName?: string;\n namespace?: string;\n },\n ): Promise<KeySetState>;\n}\n\nexport interface VaultTransitKeyResolverOptions {\n client: VaultTransitKeyResolverClient;\n mountPath?: string;\n keyName?: string;\n namespace?: string;\n cacheTtlMs?: number;\n fallbackActiveKid?: string;\n fallbackDecryptKids?: readonly string[];\n}\n\nexport function createVaultTransitKeyResolver(\n options: VaultTransitKeyResolverOptions,\n): KeyResolver {\n const provider: KeySetStateProvider = {\n async loadKeySet(context) {\n return options.client.getKeyState({\n ...context,\n ...(options.mountPath ? { mountPath: options.mountPath } : {}),\n ...(options.keyName ? { keyName: options.keyName } : {}),\n ...(options.namespace ? { namespace: options.namespace } : {}),\n });\n },\n };\n\n return createRefreshableKeyResolver({\n provider,\n cacheTtlMs: options.cacheTtlMs,\n fallback: {\n activeKid: options.fallbackActiveKid,\n decryptKids: options.fallbackDecryptKids,\n },\n });\n}\n",
|
|
7
12
|
"import { FieldCryptoError } from \"./errors\";\nimport type { FieldCryptoConfig, FieldMode } from \"./types\";\n\nexport interface FieldCryptoPolicyValidationIssue {\n message: string;\n rule: string;\n path?: string;\n hint?: string;\n}\n\nexport interface FieldCryptoPolicyOptions {\n secureMode?: boolean;\n compatPlainColumns?: boolean;\n}\n\nexport interface FieldCryptoPolicyValidationResult {\n valid: boolean;\n issues: FieldCryptoPolicyValidationIssue[];\n}\n\nfunction isFunction(value: unknown): value is (...args: unknown[]) => unknown {\n return typeof value === \"function\";\n}\n\nfunction normalizeString(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nexport function resolveFieldMode(\n config: FieldCryptoConfig,\n path: string,\n fallback: FieldMode,\n): FieldMode {\n const exact = config.fields[path];\n if (exact) return exact;\n\n if (path.startsWith(\"metadata.\")) {\n const wildcard = config.fields[\"metadata.*\"];\n if (wildcard) return wildcard;\n }\n\n return fallback;\n}\n\nexport function validateFieldCryptoConfig(\n config: FieldCryptoConfig,\n options: FieldCryptoPolicyOptions = {},\n): FieldCryptoPolicyValidationResult {\n const issues: FieldCryptoPolicyValidationIssue[] = [];\n\n if (!config || typeof config !== \"object\") {\n return {\n valid: false,\n issues: [\n {\n message: \"fieldCrypto config must be an object\",\n rule: \"fieldCrypto.config.object\",\n hint: \"Provide a valid FieldCryptoConfig object\",\n },\n ],\n };\n }\n\n if (!config.provider || typeof config.provider !== \"object\") {\n issues.push({\n message: \"fieldCrypto provider is required\",\n rule: \"fieldCrypto.provider.required\",\n path: \"provider\",\n hint: \"Set provider with encrypt/decrypt/hash methods\",\n });\n } else {\n if (!isFunction(config.provider.encrypt)) {\n issues.push({\n message: \"provider.encrypt must be a function\",\n rule: \"fieldCrypto.provider.encrypt.required\",\n path: \"provider.encrypt\",\n });\n }\n if (!isFunction(config.provider.decrypt)) {\n issues.push({\n message: \"provider.decrypt must be a function\",\n rule: \"fieldCrypto.provider.decrypt.required\",\n path: \"provider.decrypt\",\n });\n }\n if (!isFunction(config.provider.hash)) {\n issues.push({\n message: \"provider.hash must be a function\",\n rule: \"fieldCrypto.provider.hash.required\",\n path: \"provider.hash\",\n });\n }\n }\n\n if (!config.fields || typeof config.fields !== \"object\") {\n issues.push({\n message: \"fieldCrypto.fields must be an object\",\n rule: \"fieldCrypto.fields.object\",\n path: \"fields\",\n hint: \"Define policies such as to, from, metadata.phoneNumber\",\n });\n } else {\n const entries = Object.entries(config.fields);\n if (entries.length === 0) {\n issues.push({\n message: \"fieldCrypto.fields must not be empty\",\n rule: \"fieldCrypto.fields.non_empty\",\n path: \"fields\",\n hint: \"Add at least one field mode mapping\",\n });\n }\n\n for (const [path, mode] of entries) {\n const normalizedPath = normalizeString(path);\n if (!normalizedPath) {\n issues.push({\n message: \"field path must be a non-empty string\",\n rule: \"fieldCrypto.fields.path.non_empty\",\n path: \"fields\",\n });\n }\n\n if (\n mode !== \"plain\" &&\n mode !== \"encrypt\" &&\n mode !== \"encrypt+hash\" &&\n mode !== \"mask\"\n ) {\n issues.push({\n message: `unsupported field mode: ${String(mode)}`,\n rule: \"fieldCrypto.fields.mode.supported\",\n path: `fields.${path}`,\n });\n }\n }\n }\n\n const failMode = config.failMode ?? \"closed\";\n const openFallback = config.openFallback ?? \"masked\";\n if (\n failMode === \"open\" &&\n openFallback === \"plaintext\" &&\n config.unsafeAllowPlaintextStorage !== true\n ) {\n issues.push({\n message:\n \"openFallback=plaintext requires unsafeAllowPlaintextStorage=true\",\n rule: \"fieldCrypto.fail_open.plaintext_guard\",\n path: \"openFallback\",\n hint: \"Use masked/null fallback, or explicitly enable unsafe plaintext\",\n });\n }\n\n if (Array.isArray(config.aadFields)) {\n if (config.aadFields.length === 0) {\n issues.push({\n message: \"aadFields must not be empty when provided\",\n rule: \"fieldCrypto.aad_fields.non_empty\",\n path: \"aadFields\",\n });\n }\n\n for (let index = 0; index < config.aadFields.length; index += 1) {\n const key = config.aadFields[index];\n if (!normalizeString(key)) {\n issues.push({\n message: \"aadFields cannot include empty key\",\n rule: \"fieldCrypto.aad_fields.no_empty_key\",\n path: `aadFields[${index}]`,\n });\n }\n }\n }\n\n if (options.secureMode && !options.compatPlainColumns) {\n const toMode = resolveFieldMode(config, \"to\", \"encrypt+hash\");\n const fromMode = resolveFieldMode(config, \"from\", \"encrypt+hash\");\n\n if (toMode === \"plain\") {\n issues.push({\n message:\n \"secure mode requires non-plain policy for `to` when compatPlainColumns=false\",\n rule: \"fieldCrypto.secure_mode.to_non_plain\",\n path: \"fields.to\",\n hint: \"Use encrypt+hash for lookup fields\",\n });\n }\n\n if (fromMode === \"plain\") {\n issues.push({\n message:\n \"secure mode requires non-plain policy for `from` when compatPlainColumns=false\",\n rule: \"fieldCrypto.secure_mode.from_non_plain\",\n path: \"fields.from\",\n hint: \"Use encrypt+hash for lookup fields\",\n });\n }\n }\n\n return {\n valid: issues.length === 0,\n issues,\n };\n}\n\nexport function assertFieldCryptoConfig(\n config: FieldCryptoConfig,\n options: FieldCryptoPolicyOptions = {},\n): void {\n const result = validateFieldCryptoConfig(config, options);\n if (result.valid) return;\n\n const first = result.issues[0];\n if (!first) {\n throw new FieldCryptoError(\n \"config\",\n \"fieldCrypto config validation failed\",\n {\n rule: \"fieldCrypto.config.invalid\",\n issues: result.issues,\n },\n );\n }\n\n throw new FieldCryptoError(\n \"config\",\n first.message,\n {\n rule: first.rule,\n path: first.path,\n hint: first.hint,\n issues: result.issues,\n },\n {\n fieldPath: first.path,\n },\n );\n}\n",
|
|
8
|
-
"export type FieldMode = \"plain\" | \"encrypt\" | \"encrypt+hash\" | \"mask\";\nexport type FieldCryptoFailMode = \"closed\" | \"open\";\nexport type FieldCryptoOpenFallback = \"masked\" | \"plaintext\" | \"null\";\nexport type MaybePromise<T> = T | Promise<T>;\n\nexport interface CryptoEnvelope {\n v: number;\n alg: string;\n kid: string;\n iv: string;\n tag: string;\n ct: string;\n}\n\nexport interface FieldCryptoAad {\n [key: string]: string;\n}\n\nexport interface FieldCryptoKeyContext {\n tenantId?: string;\n providerId?: string;\n messageId?: string;\n tableName?: string;\n fieldPath?: string;\n requestId?: string;\n}\n\nexport interface KeyResolver {\n resolveEncryptKey(\n context: FieldCryptoKeyContext,\n ): MaybePromise<{ kid: string }>;\n resolveDecryptKeys?(\n context: FieldCryptoKeyContext & {\n ciphertext?: string;\n },\n ): MaybePromise<readonly string[]>;\n}\n\nexport interface FieldCryptoEncryptInput {\n value: string;\n aad: FieldCryptoAad;\n path: string;\n kid?: string;\n}\n\nexport interface FieldCryptoDecryptInput {\n ciphertext: string;\n aad: FieldCryptoAad;\n path: string;\n candidateKids?: readonly string[];\n}\n\nexport interface FieldCryptoHashInput {\n value: string;\n path: string;\n kid?: string;\n}\n\nexport interface FieldCryptoMaskInput {\n value: string;\n path: string;\n}\n\nexport interface FieldCryptoProvider {\n encrypt(\n input: FieldCryptoEncryptInput,\n ): MaybePromise<{ ciphertext: string | CryptoEnvelope; kid?: string }>;\n decrypt(input: FieldCryptoDecryptInput): MaybePromise<string>;\n hash(input: FieldCryptoHashInput): MaybePromise<string>;\n mask?(input: FieldCryptoMaskInput): MaybePromise<string>;\n}\n\nexport interface FieldCryptoConfig {\n enabled?: boolean;\n fields: Record<string, FieldMode>;\n failMode?: FieldCryptoFailMode;\n openFallback?: FieldCryptoOpenFallback;\n unsafeAllowPlaintextStorage?: boolean;\n aadFields?: readonly string[];\n keyResolver?: KeyResolver;\n provider: FieldCryptoProvider;\n}\n\nexport type FieldCryptoMetricName =\n | \"crypto_encrypt_ms\"\n | \"crypto_decrypt_ms\"\n | \"crypto_fail_count\"\n | \"key_kid_usage\";\n\nexport interface FieldCryptoMetricEvent {\n name: FieldCryptoMetricName;\n value?: number;\n kid?: string;\n tags?: Record<string, string | number | boolean | undefined>;\n}\n\nfunction encodeBase64Url(buffer: ArrayBuffer | Uint8Array): string {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n const maybeBuffer =\n typeof globalThis !== \"undefined\"\n ? (\n globalThis as {\n Buffer?: {\n from: (input: Uint8Array) => {\n toString: (encoding: string) => string;\n };\n };\n }\n ).Buffer\n : undefined;\n const base64 = maybeBuffer\n ? maybeBuffer.from(bytes).toString(\"base64\")\n : btoa(String.fromCharCode(...bytes));\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/g, \"\");\n}\n\nfunction decodeBase64Url(value: string): Uint8Array {\n const normalized = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded =\n normalized.length % 4 === 0\n ? normalized\n : `${normalized}${\"=\".repeat(4 - (normalized.length % 4))}`;\n\n const maybeBuffer =\n typeof globalThis !== \"undefined\"\n ? (\n globalThis as {\n Buffer?: { from: (input: string, encoding: string) => Uint8Array };\n }\n ).Buffer\n : undefined;\n\n if (maybeBuffer) {\n return new Uint8Array(maybeBuffer.from(padded, \"base64\"));\n }\n\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n}\n\nfunction toUint8Array(\n value: string | ArrayBuffer | Uint8Array,\n encoding: \"utf8\" | \"base64url\",\n): Uint8Array {\n if (value instanceof Uint8Array) return value;\n if (value instanceof ArrayBuffer) return new Uint8Array(value);\n if (encoding === \"base64url\") return decodeBase64Url(value);\n return new TextEncoder().encode(value);\n}\n\nfunction toHex(buffer: ArrayBuffer | Uint8Array): string {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction toCryptoBufferSource(bytes: Uint8Array): ArrayBuffer {\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n return copy.buffer;\n}\n\nfunction parseEnvelope(ciphertext: string): CryptoEnvelope {\n const parsed = JSON.parse(ciphertext) as Partial<CryptoEnvelope>;\n if (\n !parsed ||\n typeof parsed !== \"object\" ||\n typeof parsed.v !== \"number\" ||\n typeof parsed.alg !== \"string\" ||\n typeof parsed.kid !== \"string\" ||\n typeof parsed.iv !== \"string\" ||\n typeof parsed.tag !== \"string\" ||\n typeof parsed.ct !== \"string\"\n ) {\n throw new Error(\"Invalid ciphertext envelope\");\n }\n\n return parsed as CryptoEnvelope;\n}\n\nfunction toCiphertextString(value: string | CryptoEnvelope): string {\n if (typeof value === \"string\") return value;\n return JSON.stringify(value);\n}\n\nexport function isCryptoEnvelope(value: unknown): value is CryptoEnvelope {\n if (!value || typeof value !== \"object\") return false;\n const candidate = value as Partial<CryptoEnvelope>;\n return (\n typeof candidate.v === \"number\" &&\n typeof candidate.alg === \"string\" &&\n typeof candidate.kid === \"string\" &&\n typeof candidate.iv === \"string\" &&\n typeof candidate.tag === \"string\" &&\n typeof candidate.ct === \"string\"\n );\n}\n\nexport function normalizePhoneForHash(value: string): string {\n const trimmed = String(value ?? \"\").trim();\n if (trimmed.length === 0) return \"\";\n\n const hasLeadingPlus = trimmed.startsWith(\"+\");\n const digitsOnly = trimmed.replace(/\\D/g, \"\");\n return hasLeadingPlus ? `+${digitsOnly}` : digitsOnly;\n}\n\nexport function createDefaultMasker(\n visibleStart = 3,\n visibleEnd = 2,\n): (value: string) => string {\n return (value: string): string => {\n const normalized = String(value ?? \"\");\n if (normalized.length <= visibleStart + visibleEnd) {\n return \"*\".repeat(Math.max(0, normalized.length));\n }\n const start = normalized.slice(0, visibleStart);\n const end = normalized.slice(-visibleEnd);\n return `${start}${\"*\".repeat(normalized.length - visibleStart - visibleEnd)}${end}`;\n };\n}\n\nexport interface AesGcmFieldCryptoProviderOptions {\n keys: Record<string, string | ArrayBuffer | Uint8Array>;\n activeKid: string;\n hashKeys?: Record<string, string | ArrayBuffer | Uint8Array>;\n keyEncoding?: \"utf8\" | \"base64url\";\n hashKeyEncoding?: \"utf8\" | \"base64url\";\n algorithm?: \"A256GCM\";\n}\n\nexport function createAesGcmFieldCryptoProvider(\n options: AesGcmFieldCryptoProviderOptions,\n): FieldCryptoProvider {\n const algorithm = options.algorithm ?? \"A256GCM\";\n const keyEncoding = options.keyEncoding ?? \"base64url\";\n const hashKeyEncoding = options.hashKeyEncoding ?? keyEncoding;\n const aesKeyCache = new Map<string, Promise<CryptoKey>>();\n const hashKeyCache = new Map<string, Promise<CryptoKey>>();\n\n const importAesKey = (kid: string): Promise<CryptoKey> => {\n const cached = aesKeyCache.get(kid);\n if (cached) return cached;\n\n const raw = options.keys[kid];\n if (!raw) {\n throw new Error(`Unknown encryption key id: ${kid}`);\n }\n const bytes = toUint8Array(raw, keyEncoding);\n const promise = crypto.subtle.importKey(\n \"raw\",\n toCryptoBufferSource(bytes),\n \"AES-GCM\",\n false,\n [\"encrypt\", \"decrypt\"],\n );\n aesKeyCache.set(kid, promise);\n return promise;\n };\n\n const importHashKey = (kid: string): Promise<CryptoKey> => {\n const cached = hashKeyCache.get(kid);\n if (cached) return cached;\n\n const raw = options.hashKeys?.[kid] ?? options.keys[kid];\n if (!raw) {\n throw new Error(`Unknown hash key id: ${kid}`);\n }\n const bytes = toUint8Array(raw, hashKeyEncoding);\n const promise = crypto.subtle.importKey(\n \"raw\",\n toCryptoBufferSource(bytes),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n hashKeyCache.set(kid, promise);\n return promise;\n };\n\n return {\n async encrypt(input) {\n const kid = input.kid ?? options.activeKid;\n const key = await importAesKey(kid);\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const additionalData = new TextEncoder().encode(\n JSON.stringify(input.aad ?? {}),\n );\n const plaintext = new TextEncoder().encode(input.value);\n\n const encrypted = await crypto.subtle.encrypt(\n {\n name: \"AES-GCM\",\n iv: toCryptoBufferSource(iv),\n additionalData: toCryptoBufferSource(additionalData),\n tagLength: 128,\n },\n key,\n toCryptoBufferSource(plaintext),\n );\n\n const encryptedBytes = new Uint8Array(encrypted);\n const tag = encryptedBytes.slice(encryptedBytes.length - 16);\n const ciphertext = encryptedBytes.slice(0, encryptedBytes.length - 16);\n\n return {\n ciphertext: {\n v: 1,\n alg: algorithm,\n kid,\n iv: encodeBase64Url(iv),\n tag: encodeBase64Url(tag),\n ct: encodeBase64Url(ciphertext),\n },\n kid,\n };\n },\n\n async decrypt(input) {\n const envelope = parseEnvelope(input.ciphertext);\n const candidateKids =\n input.candidateKids && input.candidateKids.length > 0\n ? input.candidateKids\n : [envelope.kid];\n const iv = decodeBase64Url(envelope.iv);\n const tag = decodeBase64Url(envelope.tag);\n const ciphertext = decodeBase64Url(envelope.ct);\n\n const encrypted = new Uint8Array(ciphertext.length + tag.length);\n encrypted.set(ciphertext, 0);\n encrypted.set(tag, ciphertext.length);\n\n const additionalData = new TextEncoder().encode(\n JSON.stringify(input.aad ?? {}),\n );\n\n let lastError: unknown;\n for (const kid of candidateKids) {\n try {\n const key = await importAesKey(kid);\n const decrypted = await crypto.subtle.decrypt(\n {\n name: \"AES-GCM\",\n iv: toCryptoBufferSource(iv),\n additionalData: toCryptoBufferSource(additionalData),\n tagLength: 128,\n },\n key,\n toCryptoBufferSource(encrypted),\n );\n return new TextDecoder().decode(new Uint8Array(decrypted));\n } catch (error) {\n lastError = error;\n }\n }\n\n throw new Error(\n `Failed to decrypt ciphertext: ${lastError instanceof Error ? lastError.message : String(lastError ?? \"unknown\")}`,\n );\n },\n\n async hash(input) {\n const kid = input.kid ?? options.activeKid;\n const key = await importHashKey(kid);\n const signature = await crypto.subtle.sign(\n \"HMAC\",\n key,\n toCryptoBufferSource(new TextEncoder().encode(input.value)),\n );\n return toHex(signature);\n },\n\n mask(input) {\n return createDefaultMasker()(input.value);\n },\n };\n}\n\nexport function createNoopFieldCryptoProvider(): FieldCryptoProvider {\n return {\n encrypt(input) {\n return {\n ciphertext: JSON.stringify({\n v: 1,\n alg: \"NOOP\",\n kid: \"noop\",\n iv: \"\",\n tag: \"\",\n ct: input.value,\n } satisfies CryptoEnvelope),\n };\n },\n decrypt(input) {\n try {\n const parsed = parseEnvelope(input.ciphertext);\n return parsed.ct;\n } catch {\n return input.ciphertext;\n }\n },\n hash(input) {\n const normalized = normalizePhoneForHash(input.value);\n return encodeBase64Url(new TextEncoder().encode(normalized));\n },\n mask(input) {\n return createDefaultMasker()(input.value);\n },\n };\n}\n\nexport function toCiphertextEnvelopeString(\n ciphertext: string | CryptoEnvelope,\n): string {\n return toCiphertextString(ciphertext);\n}\n",
|
|
13
|
+
"export type FieldMode = \"plain\" | \"encrypt\" | \"encrypt+hash\" | \"mask\";\nexport type FieldCryptoFailMode = \"closed\" | \"open\";\nexport type FieldCryptoOpenFallback = \"masked\" | \"plaintext\" | \"null\";\nexport type MaybePromise<T> = T | Promise<T>;\n\nexport interface CryptoEnvelope {\n v: number;\n alg: string;\n kid: string;\n iv: string;\n tag: string;\n ct: string;\n}\n\nexport interface FieldCryptoAad {\n [key: string]: string;\n}\n\nexport interface FieldCryptoKeyContext {\n tenantId?: string;\n providerId?: string;\n messageId?: string;\n tableName?: string;\n fieldPath?: string;\n requestId?: string;\n}\n\nexport interface KeySetState {\n activeKid: string;\n decryptKids?: readonly string[];\n refreshedAt?: number;\n}\n\nexport interface KeyResolver {\n resolveEncryptKey(\n context: FieldCryptoKeyContext,\n ): MaybePromise<{ kid: string }>;\n resolveDecryptKeys?(\n context: FieldCryptoKeyContext & {\n ciphertext?: string;\n },\n ): MaybePromise<readonly string[]>;\n}\n\nexport interface FieldCryptoEncryptInput {\n value: string;\n aad: FieldCryptoAad;\n path: string;\n kid?: string;\n}\n\nexport interface FieldCryptoDecryptInput {\n ciphertext: string;\n aad: FieldCryptoAad;\n path: string;\n candidateKids?: readonly string[];\n}\n\nexport interface FieldCryptoHashInput {\n value: string;\n path: string;\n kid?: string;\n}\n\nexport interface FieldCryptoMaskInput {\n value: string;\n path: string;\n}\n\nexport interface FieldCryptoProvider {\n encrypt(\n input: FieldCryptoEncryptInput,\n ): MaybePromise<{ ciphertext: string | CryptoEnvelope; kid?: string }>;\n decrypt(input: FieldCryptoDecryptInput): MaybePromise<string>;\n hash(input: FieldCryptoHashInput): MaybePromise<string>;\n mask?(input: FieldCryptoMaskInput): MaybePromise<string>;\n}\n\nexport interface FieldCryptoConfig {\n enabled?: boolean;\n fields: Record<string, FieldMode>;\n failMode?: FieldCryptoFailMode;\n openFallback?: FieldCryptoOpenFallback;\n unsafeAllowPlaintextStorage?: boolean;\n aadFields?: readonly string[];\n keyResolver?: KeyResolver;\n provider: FieldCryptoProvider;\n}\n\nexport type FieldCryptoMetricName =\n | \"crypto_encrypt_ms\"\n | \"crypto_decrypt_ms\"\n | \"crypto_fail_count\"\n | \"key_kid_usage\"\n | \"crypto_circuit_open_count\"\n | \"crypto_circuit_state\";\n\nexport type FieldCryptoCircuitState = \"closed\" | \"open\" | \"half-open\";\n\nexport interface FieldCryptoControlScope {\n tenantId?: string;\n providerId?: string;\n kid?: string;\n}\n\nexport interface FieldCryptoControlSignalEvent {\n state: FieldCryptoCircuitState;\n reason: \"threshold\" | \"cooldown\" | \"manual\" | \"recovered\";\n scope: string;\n scopeParts: FieldCryptoControlScope;\n operation: \"encrypt\" | \"decrypt\" | \"hash\";\n at: number;\n errorClass?: string;\n}\n\nexport interface FieldCryptoMetricEvent {\n name: FieldCryptoMetricName;\n value?: number;\n kid?: string;\n tags?: Record<string, string | number | boolean | undefined>;\n}\n\nfunction encodeBase64Url(buffer: ArrayBuffer | Uint8Array): string {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n const maybeBuffer =\n typeof globalThis !== \"undefined\"\n ? (\n globalThis as {\n Buffer?: {\n from: (input: Uint8Array) => {\n toString: (encoding: string) => string;\n };\n };\n }\n ).Buffer\n : undefined;\n const base64 = maybeBuffer\n ? maybeBuffer.from(bytes).toString(\"base64\")\n : btoa(String.fromCharCode(...bytes));\n return base64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/g, \"\");\n}\n\nfunction decodeBase64Url(value: string): Uint8Array {\n const normalized = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded =\n normalized.length % 4 === 0\n ? normalized\n : `${normalized}${\"=\".repeat(4 - (normalized.length % 4))}`;\n\n const maybeBuffer =\n typeof globalThis !== \"undefined\"\n ? (\n globalThis as {\n Buffer?: { from: (input: string, encoding: string) => Uint8Array };\n }\n ).Buffer\n : undefined;\n\n if (maybeBuffer) {\n return new Uint8Array(maybeBuffer.from(padded, \"base64\"));\n }\n\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n}\n\nfunction toUint8Array(\n value: string | ArrayBuffer | Uint8Array,\n encoding: \"utf8\" | \"base64url\",\n): Uint8Array {\n if (value instanceof Uint8Array) return value;\n if (value instanceof ArrayBuffer) return new Uint8Array(value);\n if (encoding === \"base64url\") return decodeBase64Url(value);\n return new TextEncoder().encode(value);\n}\n\nfunction toHex(buffer: ArrayBuffer | Uint8Array): string {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction toCryptoBufferSource(bytes: Uint8Array): ArrayBuffer {\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n return copy.buffer;\n}\n\nfunction parseEnvelope(ciphertext: string): CryptoEnvelope {\n const parsed = JSON.parse(ciphertext) as Partial<CryptoEnvelope>;\n if (\n !parsed ||\n typeof parsed !== \"object\" ||\n typeof parsed.v !== \"number\" ||\n typeof parsed.alg !== \"string\" ||\n typeof parsed.kid !== \"string\" ||\n typeof parsed.iv !== \"string\" ||\n typeof parsed.tag !== \"string\" ||\n typeof parsed.ct !== \"string\"\n ) {\n throw new Error(\"Invalid ciphertext envelope\");\n }\n\n return parsed as CryptoEnvelope;\n}\n\nfunction toCiphertextString(value: string | CryptoEnvelope): string {\n if (typeof value === \"string\") return value;\n return JSON.stringify(value);\n}\n\nexport function isCryptoEnvelope(value: unknown): value is CryptoEnvelope {\n if (!value || typeof value !== \"object\") return false;\n const candidate = value as Partial<CryptoEnvelope>;\n return (\n typeof candidate.v === \"number\" &&\n typeof candidate.alg === \"string\" &&\n typeof candidate.kid === \"string\" &&\n typeof candidate.iv === \"string\" &&\n typeof candidate.tag === \"string\" &&\n typeof candidate.ct === \"string\"\n );\n}\n\nexport function normalizePhoneForHash(value: string): string {\n const trimmed = String(value ?? \"\").trim();\n if (trimmed.length === 0) return \"\";\n\n const hasLeadingPlus = trimmed.startsWith(\"+\");\n const digitsOnly = trimmed.replace(/\\D/g, \"\");\n return hasLeadingPlus ? `+${digitsOnly}` : digitsOnly;\n}\n\nexport function createDefaultMasker(\n visibleStart = 3,\n visibleEnd = 2,\n): (value: string) => string {\n return (value: string): string => {\n const normalized = String(value ?? \"\");\n if (normalized.length <= visibleStart + visibleEnd) {\n return \"*\".repeat(Math.max(0, normalized.length));\n }\n const start = normalized.slice(0, visibleStart);\n const end = normalized.slice(-visibleEnd);\n return `${start}${\"*\".repeat(normalized.length - visibleStart - visibleEnd)}${end}`;\n };\n}\n\nexport interface AesGcmFieldCryptoProviderOptions {\n keys: Record<string, string | ArrayBuffer | Uint8Array>;\n activeKid: string;\n hashKeys?: Record<string, string | ArrayBuffer | Uint8Array>;\n keyEncoding?: \"utf8\" | \"base64url\";\n hashKeyEncoding?: \"utf8\" | \"base64url\";\n algorithm?: \"A256GCM\";\n}\n\nexport function createAesGcmFieldCryptoProvider(\n options: AesGcmFieldCryptoProviderOptions,\n): FieldCryptoProvider {\n const algorithm = options.algorithm ?? \"A256GCM\";\n const keyEncoding = options.keyEncoding ?? \"base64url\";\n const hashKeyEncoding = options.hashKeyEncoding ?? keyEncoding;\n const aesKeyCache = new Map<string, Promise<CryptoKey>>();\n const hashKeyCache = new Map<string, Promise<CryptoKey>>();\n\n const importAesKey = (kid: string): Promise<CryptoKey> => {\n const cached = aesKeyCache.get(kid);\n if (cached) return cached;\n\n const raw = options.keys[kid];\n if (!raw) {\n throw new Error(`Unknown encryption key id: ${kid}`);\n }\n const bytes = toUint8Array(raw, keyEncoding);\n const promise = crypto.subtle.importKey(\n \"raw\",\n toCryptoBufferSource(bytes),\n \"AES-GCM\",\n false,\n [\"encrypt\", \"decrypt\"],\n );\n aesKeyCache.set(kid, promise);\n return promise;\n };\n\n const importHashKey = (kid: string): Promise<CryptoKey> => {\n const cached = hashKeyCache.get(kid);\n if (cached) return cached;\n\n const raw = options.hashKeys?.[kid] ?? options.keys[kid];\n if (!raw) {\n throw new Error(`Unknown hash key id: ${kid}`);\n }\n const bytes = toUint8Array(raw, hashKeyEncoding);\n const promise = crypto.subtle.importKey(\n \"raw\",\n toCryptoBufferSource(bytes),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n hashKeyCache.set(kid, promise);\n return promise;\n };\n\n return {\n async encrypt(input) {\n const kid = input.kid ?? options.activeKid;\n const key = await importAesKey(kid);\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const additionalData = new TextEncoder().encode(\n JSON.stringify(input.aad ?? {}),\n );\n const plaintext = new TextEncoder().encode(input.value);\n\n const encrypted = await crypto.subtle.encrypt(\n {\n name: \"AES-GCM\",\n iv: toCryptoBufferSource(iv),\n additionalData: toCryptoBufferSource(additionalData),\n tagLength: 128,\n },\n key,\n toCryptoBufferSource(plaintext),\n );\n\n const encryptedBytes = new Uint8Array(encrypted);\n const tag = encryptedBytes.slice(encryptedBytes.length - 16);\n const ciphertext = encryptedBytes.slice(0, encryptedBytes.length - 16);\n\n return {\n ciphertext: {\n v: 1,\n alg: algorithm,\n kid,\n iv: encodeBase64Url(iv),\n tag: encodeBase64Url(tag),\n ct: encodeBase64Url(ciphertext),\n },\n kid,\n };\n },\n\n async decrypt(input) {\n const envelope = parseEnvelope(input.ciphertext);\n const candidateKids =\n input.candidateKids && input.candidateKids.length > 0\n ? input.candidateKids\n : [envelope.kid];\n const iv = decodeBase64Url(envelope.iv);\n const tag = decodeBase64Url(envelope.tag);\n const ciphertext = decodeBase64Url(envelope.ct);\n\n const encrypted = new Uint8Array(ciphertext.length + tag.length);\n encrypted.set(ciphertext, 0);\n encrypted.set(tag, ciphertext.length);\n\n const additionalData = new TextEncoder().encode(\n JSON.stringify(input.aad ?? {}),\n );\n\n let lastError: unknown;\n for (const kid of candidateKids) {\n try {\n const key = await importAesKey(kid);\n const decrypted = await crypto.subtle.decrypt(\n {\n name: \"AES-GCM\",\n iv: toCryptoBufferSource(iv),\n additionalData: toCryptoBufferSource(additionalData),\n tagLength: 128,\n },\n key,\n toCryptoBufferSource(encrypted),\n );\n return new TextDecoder().decode(new Uint8Array(decrypted));\n } catch (error) {\n lastError = error;\n }\n }\n\n throw new Error(\n `Failed to decrypt ciphertext: ${lastError instanceof Error ? lastError.message : String(lastError ?? \"unknown\")}`,\n );\n },\n\n async hash(input) {\n const kid = input.kid ?? options.activeKid;\n const key = await importHashKey(kid);\n const signature = await crypto.subtle.sign(\n \"HMAC\",\n key,\n toCryptoBufferSource(new TextEncoder().encode(input.value)),\n );\n return toHex(signature);\n },\n\n mask(input) {\n return createDefaultMasker()(input.value);\n },\n };\n}\n\nexport function createNoopFieldCryptoProvider(): FieldCryptoProvider {\n return {\n encrypt(input) {\n return {\n ciphertext: JSON.stringify({\n v: 1,\n alg: \"NOOP\",\n kid: \"noop\",\n iv: \"\",\n tag: \"\",\n ct: input.value,\n } satisfies CryptoEnvelope),\n };\n },\n decrypt(input) {\n try {\n const parsed = parseEnvelope(input.ciphertext);\n return parsed.ct;\n } catch {\n return input.ciphertext;\n }\n },\n hash(input) {\n const normalized = normalizePhoneForHash(input.value);\n return encodeBase64Url(new TextEncoder().encode(normalized));\n },\n mask(input) {\n return createDefaultMasker()(input.value);\n },\n };\n}\n\nexport function toCiphertextEnvelopeString(\n ciphertext: string | CryptoEnvelope,\n): string {\n return toCiphertextString(ciphertext);\n}\n",
|
|
9
14
|
"export enum LogLevel {\n DEBUG = \"DEBUG\",\n INFO = \"INFO\",\n WARN = \"WARN\",\n ERROR = \"ERROR\",\n}\n\nexport interface LogContext {\n component?: string;\n operation?: string;\n userId?: string;\n sessionId?: string;\n requestId?: string;\n traceId?: string;\n [key: string]: any;\n}\n\nexport interface LogEntry {\n level: LogLevel;\n message: string;\n timestamp: Date;\n context: LogContext;\n error?: Error;\n duration?: number;\n}\n\nexport interface LoggerConfig {\n level: LogLevel;\n enableConsole: boolean;\n enableFile?: boolean;\n filePath?: string;\n maxFileSize?: number;\n maxFiles?: number;\n enableJson?: boolean;\n enableColors?: boolean;\n}\n\nconst REDACTED_TOKEN = \"[REDACTED]\";\nconst MASKED_TOKEN = \"***\";\nconst SENSITIVE_CONTEXT_KEYS = [\n \"to\",\n \"from\",\n \"phone\",\n \"phoneNumber\",\n \"recipient\",\n \"sender\",\n \"secret\",\n \"apiKey\",\n \"apiSecret\",\n \"authorization\",\n \"auth\",\n \"token\",\n \"password\",\n \"payload\",\n \"message\",\n \"content\",\n \"text\",\n] as const;\n\nfunction isSensitiveContextKey(rawKey: string): boolean {\n const key = rawKey.toLowerCase();\n return SENSITIVE_CONTEXT_KEYS.some((candidate) =>\n key.includes(candidate.toLowerCase()),\n );\n}\n\nfunction maskStringValue(value: string): string {\n const trimmed = value.trim();\n if (trimmed.length <= 4) return MASKED_TOKEN;\n if (trimmed.includes(\"@\")) {\n const [local, domain] = trimmed.split(\"@\");\n const head = local.slice(0, 2);\n return `${head}${\"*\".repeat(Math.max(1, local.length - 2))}@${domain}`;\n }\n const head = trimmed.slice(0, 3);\n const tail = trimmed.slice(-2);\n return `${head}${\"*\".repeat(Math.max(1, trimmed.length - 5))}${tail}`;\n}\n\nfunction sanitizeContextValue(key: string, value: unknown): unknown {\n if (value === undefined || value === null) return value;\n\n if (isSensitiveContextKey(key)) {\n if (typeof value === \"string\") return maskStringValue(value);\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return MASKED_TOKEN;\n }\n if (Array.isArray(value)) return REDACTED_TOKEN;\n if (typeof value === \"object\") return REDACTED_TOKEN;\n }\n\n if (Array.isArray(value)) {\n return value.map((entry) => sanitizeContextValue(key, entry));\n }\n\n if (typeof value === \"object\") {\n const next: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n next[childKey] = sanitizeContextValue(childKey, childValue);\n }\n return next;\n }\n\n return value;\n}\n\nfunction sanitizeLogContext(context: LogContext): LogContext {\n const sanitized: LogContext = {};\n for (const [key, value] of Object.entries(context)) {\n sanitized[key] = sanitizeContextValue(key, value);\n }\n return sanitized;\n}\n\nexport class Logger {\n private config: LoggerConfig;\n private context: LogContext;\n\n constructor(context: LogContext = {}, config: Partial<LoggerConfig> = {}) {\n this.context = context;\n this.config = {\n level: LogLevel.INFO,\n enableConsole: true,\n enableJson: false,\n enableColors: true,\n ...config,\n };\n }\n\n private shouldLog(level: LogLevel): boolean {\n const levels = [\n LogLevel.DEBUG,\n LogLevel.INFO,\n LogLevel.WARN,\n LogLevel.ERROR,\n ];\n return levels.indexOf(level) >= levels.indexOf(this.config.level);\n }\n\n private formatMessage(entry: LogEntry): string {\n const context = sanitizeLogContext(entry.context);\n\n if (this.config.enableJson) {\n return JSON.stringify({\n level: entry.level,\n message: entry.message,\n timestamp: entry.timestamp.toISOString(),\n context,\n ...(entry.error && {\n error: {\n name: entry.error.name,\n message: entry.error.message,\n stack: entry.error.stack,\n },\n }),\n ...(entry.duration && { duration: entry.duration }),\n });\n }\n\n const timestamp = entry.timestamp.toISOString();\n const level = this.config.enableColors\n ? this.colorizeLevel(entry.level)\n : entry.level;\n const contextStr =\n Object.keys(context).length > 0\n ? ` [${Object.entries(context)\n .map(([k, v]) => `${k}=${v}`)\n .join(\", \")}]`\n : \"\";\n\n let message = `${timestamp} ${level}${contextStr}: ${entry.message}`;\n\n if (entry.duration !== undefined) {\n message += ` (${entry.duration}ms)`;\n }\n\n if (entry.error) {\n message += `\\n${entry.error.stack}`;\n }\n\n return message;\n }\n\n private colorizeLevel(level: LogLevel): string {\n if (!this.config.enableColors) return level;\n\n const colors = {\n [LogLevel.DEBUG]: \"\\x1b[36m\", // cyan\n [LogLevel.INFO]: \"\\x1b[32m\", // green\n [LogLevel.WARN]: \"\\x1b[33m\", // yellow\n [LogLevel.ERROR]: \"\\x1b[31m\", // red\n };\n\n return `${colors[level]}${level}\\x1b[0m`;\n }\n\n private writeLog(entry: LogEntry): void {\n if (!this.shouldLog(entry.level)) return;\n\n const message = this.formatMessage(entry);\n\n if (this.config.enableConsole) {\n const logFn =\n entry.level === LogLevel.ERROR\n ? console.error\n : entry.level === LogLevel.WARN\n ? console.warn\n : console.log;\n logFn(message);\n }\n\n // File logging would be implemented here if needed\n if (this.config.enableFile && this.config.filePath) {\n // Bun.write(this.config.filePath, message + '\\n', { createPath: true });\n }\n }\n\n debug(message: string, context: LogContext = {}): void {\n this.writeLog({\n level: LogLevel.DEBUG,\n message,\n timestamp: new Date(),\n context: { ...this.context, ...context },\n });\n }\n\n info(message: string, context: LogContext = {}): void {\n this.writeLog({\n level: LogLevel.INFO,\n message,\n timestamp: new Date(),\n context: { ...this.context, ...context },\n });\n }\n\n warn(message: string, context: LogContext = {}, error?: Error): void {\n this.writeLog({\n level: LogLevel.WARN,\n message,\n timestamp: new Date(),\n context: { ...this.context, ...context },\n error,\n });\n }\n\n error(message: string, context: LogContext = {}, error?: Error): void {\n this.writeLog({\n level: LogLevel.ERROR,\n message,\n timestamp: new Date(),\n context: { ...this.context, ...context },\n error,\n });\n }\n\n child(context: LogContext): Logger {\n return new Logger({ ...this.context, ...context }, this.config);\n }\n\n time(label: string): () => void {\n const start = Date.now();\n return () => {\n const duration = Date.now() - start;\n this.info(`${label} completed`, { duration });\n };\n }\n\n async measure<T>(\n operation: string,\n fn: () => Promise<T>,\n context: LogContext = {},\n ): Promise<T> {\n const start = Date.now();\n const operationContext = { ...context, operation };\n\n this.debug(`Starting ${operation}`, operationContext);\n\n try {\n const result = await fn();\n const duration = Date.now() - start;\n\n this.info(`Completed ${operation}`, { ...operationContext, duration });\n return result;\n } catch (error) {\n const duration = Date.now() - start;\n\n this.error(\n `Failed ${operation}`,\n { ...operationContext, duration },\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n }\n}\n\n// Global logger instance\nlet globalLogger: Logger;\n\nexport function createLogger(\n context?: LogContext,\n config?: Partial<LoggerConfig>,\n): Logger {\n return new Logger(context, config);\n}\n\nexport function getLogger(): Logger {\n if (!globalLogger) {\n globalLogger = createLogger();\n }\n return globalLogger;\n}\n\nexport function setGlobalLogger(logger: Logger): void {\n globalLogger = logger;\n}\n\n// Convenience functions\nexport const logger = {\n debug: (message: string, context?: LogContext) =>\n getLogger().debug(message, context),\n info: (message: string, context?: LogContext) =>\n getLogger().info(message, context),\n warn: (message: string, context?: LogContext, error?: Error) =>\n getLogger().warn(message, context, error),\n error: (message: string, context?: LogContext, error?: Error) =>\n getLogger().error(message, context, error),\n child: (context: LogContext) => getLogger().child(context),\n time: (label: string) => getLogger().time(label),\n measure: <T>(operation: string, fn: () => Promise<T>, context?: LogContext) =>\n getLogger().measure(operation, fn, context),\n};\n\n// Express-style middleware for Hono\nexport function loggerMiddleware(config?: Partial<LoggerConfig>) {\n const requestLogger = createLogger({}, config);\n\n return async (c: any, next: any) => {\n const start = Date.now();\n const requestId = Math.random().toString(36).substring(7);\n\n const context = {\n requestId,\n method: c.req.method,\n path: c.req.path,\n userAgent: c.req.header(\"user-agent\") || \"unknown\",\n };\n\n requestLogger.info(\"Request started\", context);\n\n try {\n await next();\n\n const duration = Date.now() - start;\n requestLogger.info(\"Request completed\", {\n ...context,\n status: c.res.status,\n duration,\n });\n } catch (error) {\n const duration = Date.now() - start;\n requestLogger.error(\n \"Request failed\",\n {\n ...context,\n duration,\n },\n error instanceof Error ? error : new Error(String(error)),\n );\n\n throw error;\n }\n };\n}\n",
|
|
10
15
|
"/**\n * Retry options and handler for K-Message Platform\n */\n\nimport { ErrorUtils } from \"../errors\";\n\nexport interface RetryOptions {\n maxAttempts?: number;\n initialDelay?: number;\n maxDelay?: number;\n backoffMultiplier?: number;\n jitter?: boolean;\n retryCondition?: (error: Error, attempt: number) => boolean;\n onRetry?: (error: Error, attempt: number) => void;\n}\n\n/**\n * Exponential backoff retry mechanism\n */\nexport class RetryHandler {\n private static defaultOptions: RetryOptions = {\n maxAttempts: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n backoffMultiplier: 2,\n jitter: true,\n retryCondition: (error) => ErrorUtils.isRetryable(error),\n };\n\n static async execute<T>(\n operation: () => Promise<T>,\n options: Partial<RetryOptions> = {},\n ): Promise<T> {\n const opts = {\n ...RetryHandler.defaultOptions,\n ...options,\n } as Required<RetryOptions>;\n let lastError: Error;\n let delay = opts.initialDelay;\n\n for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error as Error;\n\n if (\n attempt === opts.maxAttempts ||\n !opts.retryCondition!(lastError, attempt)\n ) {\n throw lastError;\n }\n\n const actualDelay = opts.jitter\n ? delay + Math.random() * delay * 0.1\n : delay;\n\n opts.onRetry?.(lastError, attempt);\n\n await new Promise((resolve) => setTimeout(resolve, actualDelay));\n\n delay = Math.min(delay * opts.backoffMultiplier, opts.maxDelay);\n }\n }\n\n throw lastError!;\n }\n\n static createRetryableFunction<T extends any[], R>(\n func: (...args: T) => Promise<R>,\n options: Partial<RetryOptions> = {},\n ): (...args: T) => Promise<R> {\n return async (...args: T) => {\n return RetryHandler.execute(() => func(...args), options);\n };\n }\n}\n",
|
|
11
16
|
"/**\n * Bulk operation handler with error recovery\n */\n\nimport { KMsgError, KMsgErrorCode } from \"../errors\";\nimport { RetryHandler, type RetryOptions } from \"./retry-handler\";\n\nexport interface BulkOperationOptions {\n concurrency: number;\n retryOptions: RetryOptions;\n failFast: boolean;\n onProgress?: (completed: number, total: number, failed: number) => void;\n}\n\nexport class BulkOperationHandler {\n static async execute<T, R>(\n items: T[],\n operation: (item: T) => Promise<R>,\n options: Partial<BulkOperationOptions> = {},\n ): Promise<{\n successful: { item: T; result: R }[];\n failed: { item: T; error: Error }[];\n summary: {\n total: number;\n successful: number;\n failed: number;\n duration: number;\n };\n }> {\n const opts: BulkOperationOptions = {\n concurrency: 5,\n retryOptions: {\n maxAttempts: 3,\n initialDelay: 1000,\n maxDelay: 10000,\n backoffMultiplier: 2,\n jitter: true,\n },\n failFast: false,\n ...options,\n };\n\n const startTime = Date.now();\n const successful: { item: T; result: R }[] = [];\n const failed: { item: T; error: Error }[] = [];\n let completed = 0;\n\n const retryableOperation = RetryHandler.createRetryableFunction(\n operation,\n opts.retryOptions,\n );\n\n const batches = BulkOperationHandler.createBatches(items, opts.concurrency);\n\n for (const batch of batches) {\n const batchPromises = batch.map(async (item) => {\n try {\n const result = await retryableOperation(item);\n successful.push({ item, result });\n } catch (error) {\n failed.push({ item, error: error as Error });\n\n if (opts.failFast) {\n throw new KMsgError(\n KMsgErrorCode.MESSAGE_SEND_FAILED,\n `Bulk operation failed fast after ${failed.length} failures`,\n { totalItems: items.length, failedCount: failed.length },\n );\n }\n } finally {\n completed++;\n opts.onProgress?.(completed, items.length, failed.length);\n }\n });\n\n await Promise.allSettled(batchPromises);\n\n if (opts.failFast && failed.length > 0) {\n break;\n }\n }\n\n const duration = Date.now() - startTime;\n\n return {\n successful,\n failed,\n summary: {\n total: items.length,\n successful: successful.length,\n failed: failed.length,\n duration,\n },\n };\n }\n\n private static createBatches<T>(items: T[], batchSize: number): T[][] {\n const batches: T[][] = [];\n for (let i = 0; i < items.length; i += batchSize) {\n batches.push(items.slice(i, i + batchSize));\n }\n return batches;\n }\n}\n",
|
|
@@ -15,7 +20,7 @@
|
|
|
15
20
|
"export type RuntimeEnvRecord = Record<string, string | undefined>;\n\ntype RuntimeGlobal = typeof globalThis & {\n __ENV__?: RuntimeEnvRecord;\n __K_MSG_ENV__?: RuntimeEnvRecord;\n process?: {\n env?: RuntimeEnvRecord;\n };\n};\n\n/**\n * Resolve environment variables in a runtime-neutral order.\n *\n * Priority:\n * 1. globalThis.__K_MSG_ENV__\n * 2. globalThis.__ENV__\n * 3. globalThis.process?.env\n */\nexport function getRuntimeEnvSource(): RuntimeEnvRecord {\n const runtimeGlobal = globalThis as RuntimeGlobal;\n return (\n runtimeGlobal.__K_MSG_ENV__ ??\n runtimeGlobal.__ENV__ ??\n runtimeGlobal.process?.env ??\n {}\n );\n}\n\nexport function readRuntimeEnv(key: string): string | undefined {\n const value = getRuntimeEnvSource()[key];\n if (typeof value === \"string\") {\n return value;\n }\n if (value === undefined) {\n return undefined;\n }\n return String(value);\n}\n",
|
|
16
21
|
"export type MessageType =\n | \"ALIMTALK\"\n | \"FRIENDTALK\"\n | \"SMS\"\n | \"LMS\"\n | \"MMS\"\n | \"NSA\"\n | \"VOICE\"\n | \"FAX\"\n | \"RCS_SMS\"\n | \"RCS_LMS\"\n | \"RCS_MMS\"\n | \"RCS_TPL\"\n | \"RCS_ITPL\"\n | \"RCS_LTPL\";\n\nexport type MessageStatus = \"PENDING\" | \"SENT\" | \"FAILED\";\n\nexport const KNOWN_MESSAGE_STATUSES: MessageStatus[] = [\n \"PENDING\",\n \"SENT\",\n \"FAILED\",\n];\n\nexport const QUEUED_MESSAGE_STATUS: MessageStatus = \"PENDING\";\n\nexport const normalizeMessageStatus = (status: unknown): MessageStatus => {\n const raw = typeof status === \"string\" ? status.trim().toUpperCase() : \"\";\n\n if (raw === \"PENDING\" || raw === \"SENT\" || raw === \"FAILED\") {\n return raw;\n }\n\n return QUEUED_MESSAGE_STATUS;\n};\n\nexport type MessageVariables = Record<\n string,\n string | number | boolean | Date | null | undefined\n>;\n\nexport interface MessageButton {\n name: string;\n /**\n * Provider-dependent. Common values: \"WL\" (web link), \"AL\" (app link), ...\n */\n type: string;\n urlPc?: string;\n urlMobile?: string;\n}\n\nexport type MessageBinaryInput =\n | {\n /**\n * URL or file path (provider-dependent).\n */\n ref: string;\n filename?: string;\n contentType?: string;\n }\n | {\n bytes: Uint8Array;\n filename?: string;\n contentType?: string;\n }\n | {\n blob: Blob;\n filename?: string;\n contentType?: string;\n };\n\nexport interface MessageMedia {\n /**\n * Image attachment (used by MMS, FriendTalk image, RCS_MMS, ...).\n */\n image?: MessageBinaryInput;\n}\n\nexport interface CommonSendOptions {\n /**\n * Correlation id generated by KMsg (or provided by the caller).\n * Providers must echo this value back in SendResult.messageId.\n */\n messageId?: string;\n /**\n * Optional routing hint to force a specific provider by id.\n */\n providerId?: string;\n to: string;\n /**\n * Sender number / sender id. Optional at KMsg layer; providers may require it.\n */\n from?: string;\n /**\n * Common delivery options understood by multiple providers.\n */\n options?: {\n scheduledAt?: Date;\n /**\n * Country code for providers that support it (e.g. SOLAPI).\n * Examples: \"82\", \"+82\".\n */\n country?: string;\n customFields?: Record<string, string>;\n };\n /**\n * Provider-specific escape hatch (use sparingly).\n */\n providerOptions?: Record<string, unknown>;\n}\n\nexport interface KakaoSendOptions {\n profileId?: string;\n plusId?: string;\n disableSms?: boolean;\n adFlag?: boolean;\n buttons?: unknown[];\n imageId?: string;\n /**\n * FriendTalk image upload link hint (SOLAPI).\n */\n imageLink?: string;\n // biome-ignore lint/suspicious/noExplicitAny: provider-specific extras\n [key: string]: any;\n}\n\nexport interface AlimTalkFailoverOptions {\n enabled?: boolean;\n fallbackChannel?: \"sms\" | \"lms\";\n fallbackContent?: string;\n fallbackTitle?: string;\n}\n\nexport type SendWarningCode =\n | \"FAILOVER_UNSUPPORTED_PROVIDER\"\n | \"FAILOVER_PARTIAL_PROVIDER\"\n | \"FALLBACK_CONTENT_MISSING\"\n | (string & {});\n\nexport interface SendWarning {\n code: SendWarningCode;\n message: string;\n details?: Record<string, unknown>;\n}\n\nexport interface NaverSendOptions {\n talkId?: string;\n /**\n * Override the template identifier for NSA (provider-specific).\n */\n templateId?: string;\n disableSms?: boolean;\n variables?: MessageVariables;\n buttons?: unknown[];\n // biome-ignore lint/suspicious/noExplicitAny: provider-specific extras\n [key: string]: any;\n}\n\nexport interface VoiceSendOptions {\n voiceType?: \"FEMALE\" | \"MALE\";\n headerMessage?: string;\n tailMessage?: string;\n replyRange?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;\n counselorNumber?: string;\n // biome-ignore lint/suspicious/noExplicitAny: provider-specific extras\n [key: string]: any;\n}\n\nexport interface FaxSendOptions {\n fileIds?: string[];\n fileUrls?: string[];\n // biome-ignore lint/suspicious/noExplicitAny: provider-specific extras\n [key: string]: any;\n}\n\nexport interface RcsSendOptions {\n brandId?: string;\n /**\n * Override template identifier for RCS_*TPL types.\n */\n templateId?: string;\n copyAllowed?: boolean;\n variables?: MessageVariables;\n mmsType?: \"M3\" | \"S3\" | \"M4\" | \"S4\" | \"M5\" | \"S5\" | \"M6\" | \"S6\";\n commercialType?: boolean;\n disableSms?: boolean;\n buttons?: unknown[];\n additionalBody?: {\n title?: string;\n description?: string;\n imageId?: string;\n buttons?: unknown[];\n // biome-ignore lint/suspicious/noExplicitAny: provider-specific extras\n [key: string]: any;\n };\n // biome-ignore lint/suspicious/noExplicitAny: provider-specific extras\n [key: string]: any;\n}\n\nexport interface SmsSendOptions extends CommonSendOptions {\n type: \"SMS\" | \"LMS\" | \"MMS\";\n text: string;\n /**\n * LMS/MMS subject.\n */\n subject?: string;\n /**\n * Media attachments. For backwards compatibility, `imageUrl` is treated as a legacy alias\n * for `media.image.ref` by some providers.\n */\n media?: MessageMedia;\n /**\n * Optional image URL for MMS (provider-specific).\n */\n imageUrl?: string;\n variables?: MessageVariables;\n}\n\nexport interface AlimTalkSendOptions extends CommonSendOptions {\n type: \"ALIMTALK\";\n templateId: string;\n variables: MessageVariables;\n kakao?: KakaoSendOptions;\n failover?: AlimTalkFailoverOptions;\n}\n\nexport interface FriendTalkSendOptions extends CommonSendOptions {\n type: \"FRIENDTALK\";\n text: string;\n media?: MessageMedia;\n imageUrl?: string;\n buttons?: MessageButton[];\n variables?: MessageVariables;\n kakao?: KakaoSendOptions;\n}\n\nexport interface NsaSendOptions extends CommonSendOptions {\n type: \"NSA\";\n templateId: string;\n variables: MessageVariables;\n naver?: NaverSendOptions;\n}\n\nexport interface VoiceMessageSendOptions extends CommonSendOptions {\n type: \"VOICE\";\n text: string;\n variables?: MessageVariables;\n voice?: VoiceSendOptions;\n}\n\nexport interface FaxMessageSendOptions extends CommonSendOptions {\n type: \"FAX\";\n fax: FaxSendOptions;\n}\n\nexport interface RcsTextSendOptions extends CommonSendOptions {\n type: \"RCS_SMS\" | \"RCS_LMS\" | \"RCS_MMS\";\n text: string;\n subject?: string;\n media?: MessageMedia;\n imageUrl?: string;\n variables?: MessageVariables;\n rcs?: RcsSendOptions;\n}\n\nexport interface RcsTemplateSendOptions extends CommonSendOptions {\n type: \"RCS_TPL\" | \"RCS_ITPL\" | \"RCS_LTPL\";\n templateId: string;\n variables: MessageVariables;\n rcs?: RcsSendOptions;\n}\n\nexport type SendOptions =\n | SmsSendOptions\n | AlimTalkSendOptions\n | FriendTalkSendOptions\n | NsaSendOptions\n | VoiceMessageSendOptions\n | FaxMessageSendOptions\n | RcsTextSendOptions\n | RcsTemplateSendOptions;\n\nexport type SmsDefaultSendInput = Omit<SmsSendOptions, \"type\" | \"text\"> & {\n type?: undefined;\n /**\n * SMS text. If omitted, `content` is used.\n */\n text?: string;\n /**\n * Alias for `text`.\n */\n content?: string;\n};\n\n/**\n * Developer-facing input type.\n * - SMS defaults allow omitting `type` and using `content`.\n * - Other channels are modeled as discriminated unions on `type`.\n */\nexport type SendInput = SendOptions | SmsDefaultSendInput;\n\nexport interface SendResult {\n /**\n * Correlation id (equals the request `messageId`).\n */\n messageId: string;\n providerId: string;\n providerMessageId?: string;\n status: MessageStatus;\n type: MessageType;\n to: string;\n warnings?: SendWarning[];\n raw?: unknown;\n}\n"
|
|
17
22
|
],
|
|
18
|
-
"mappings": "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",
|
|
19
|
-
"debugId": "
|
|
23
|
+
"mappings": "AAAO,IAAK,GAAL,CAAK,IAAL,CACL,kBAAkB,kBAClB,wBAAwB,wBACxB,uBAAuB,uBACvB,qBAAqB,qBACrB,sBAAsB,sBACtB,gBAAgB,gBAChB,kBAAkB,kBAClB,8BAA8B,8BAC9B,iBAAiB,iBACjB,sBAAsB,sBACtB,sBAAsB,sBACtB,wBAAwB,wBACxB,wBAAwB,wBACxB,qBAAqB,qBACrB,0BAA0B,0BAC1B,gBAAgB,kBAhBN,QAgDZ,IAAM,EACJ,IAAI,IAAI,CACN,gBACA,sBACA,kBACA,8BACA,iBACA,eACF,CAAC,EAEG,EACJ,IAAI,IAAI,CACN,kBACA,wBACA,uBACA,qBACA,sBACA,sBACA,wBACA,wBACA,qBACA,yBACF,CAAC,EAEG,EAAkB,CAAC,IAAuC,CAC9D,GACE,OAAO,IAAU,UACjB,OAAO,MAAM,CAAK,GAClB,CAAC,OAAO,SAAS,CAAK,EAEtB,OAGF,OAAO,KAAK,MAAM,CAAK,GAGZ,EAAwB,CAAC,IAAuC,CAC3E,IAAM,EAAa,EAAgB,CAAK,EACxC,GAAI,IAAe,QAAa,EAAa,EAC3C,OAGF,OAAO,GAGH,EAAgB,CAAC,IAAuC,CAC5D,GAAI,OAAO,IAAU,SACnB,OAGF,OAAO,EAAM,YAAY,EAAE,KAAK,GAG5B,EAAuB,CAAC,IAAsC,CAClE,GAAI,GAAU,IACZ,MAAO,YAGT,GAAI,IAAW,KAAO,IAAW,KAAO,IAAW,IACjD,MAAO,YAGT,MAAO,iBAGH,EAAoB,CAAC,IAAmD,CAC5E,IAAM,EAAa,EAAQ,YAAY,EAEvC,GACE,EAAW,SAAS,SAAS,GAC7B,EAAW,SAAS,UAAU,GAC9B,EAAW,SAAS,SAAS,GAC7B,EAAW,SAAS,OAAO,EAE3B,MAAO,YAGT,QAGK,MAAM,UAAkB,KAAM,CACnB,KACA,QACA,kBACA,kBACA,WACA,UACA,aACA,QACA,WAEhB,WAAW,CACT,EACA,EACA,EACA,EAA8B,CAAC,EAC/B,CACA,MAAM,CAAO,EAab,GAZA,KAAK,KAAO,YACZ,KAAK,KAAO,EACZ,KAAK,QAAU,EAEf,KAAK,kBAAoB,EAAS,kBAClC,KAAK,kBAAoB,EAAS,kBAClC,KAAK,WAAa,EAAgB,EAAS,UAAU,EACrD,KAAK,UACH,OAAO,EAAS,YAAc,SAAW,EAAS,UAAY,OAChE,KAAK,aAAe,EAAgB,EAAS,YAAY,EACzD,KAAK,QAAU,EAAgB,EAAS,OAAO,EAE3C,MAAM,QAAQ,EAAS,UAAU,EACnC,KAAK,WAAa,EAAS,WACtB,QAAI,EAAS,aAAe,OACjC,KAAK,WAAa,CAAC,EAAS,UAAU,EAGxC,GAAI,MAAM,kBACR,MAAM,kBAAkB,KAAM,CAAS,EAI3C,MAAM,EAAG,CACP,MAAO,CACL,KAAM,KAAK,KACX,KAAM,KAAK,KACX,QAAS,KAAK,QACd,QAAS,KAAK,QACd,kBAAmB,KAAK,kBACxB,kBAAmB,KAAK,kBACxB,WAAY,KAAK,WACjB,UAAW,KAAK,UAChB,aAAc,KAAK,aACnB,QAAS,KAAK,QACd,WAAY,KAAK,UACnB,EAEJ,CAEO,IAAM,EAAa,CACxB,WAAW,CAAC,EAAgB,EAA2B,CAAC,EAAY,CAClE,OAAO,EAAW,iBAAiB,EAAO,CAAM,IAAM,aAGxD,gBAAgB,CACd,EACA,EAA2B,CAAC,EACT,CACnB,GAAI,aAAiB,EAAW,CAI9B,GAHuB,IAAI,IACzB,EAAO,gBAAkB,MAAM,KAAK,CAA6B,CACnE,EACmB,IAAI,EAAM,IAAI,EAC/B,MAAO,YAOT,GAJ0B,IAAI,IAC5B,EAAO,mBACL,MAAM,KAAK,CAAiC,CAChD,EACsB,IAAI,EAAM,IAAI,EAClC,MAAO,gBAGT,GAAI,EAAM,aAAe,OACvB,OAAO,EAAqB,EAAM,UAAU,EAG9C,IAAM,EAAsB,EAAkB,EAAM,OAAO,EAC3D,GAAI,EACF,OAAO,EAGT,GAAI,EAAO,mBAAqB,EAAM,QAAS,CAC7C,IAAM,EAAa,EAAO,kBAAkB,EAAM,OAAO,EACzD,GAAI,EACF,OAAO,EAIX,GAAI,EAAO,SACT,OAAO,EAAO,SAGhB,MAAO,gBAGT,IAAM,EACJ,GAAS,OAAO,IAAU,SACrB,EAOD,OAEA,EACJ,EAAc,GAAW,MAAM,GAC/B,EAAc,GAAW,UAAU,GACnC,EAAc,GAAW,IAAI,EACzB,EACJ,EAAgB,GAAW,MAAM,GACjC,EAAgB,GAAW,UAAU,GACrC,EAAgB,GAAW,UAAU,EAEvC,GAAI,OAAO,IAAW,UAAY,EAAO,WAAW,GAAG,EACrD,MAAO,YAGT,GAAI,IAAe,OAAW,CAC5B,GAAI,EAAO,qBACT,OAAO,EAAO,qBAAqB,CAAU,EAG/C,OAAO,EAAqB,CAAU,EAGxC,IAAM,EACJ,OAAO,GAAW,UAAY,SAC1B,EAAkB,EAAU,OAAO,EACnC,OAEN,GAAI,EACF,OAAO,EAGT,GAAI,EAAO,mBAAqB,OAAO,GAAW,UAAY,SAAU,CACtE,IAAM,EAAa,EAAO,kBAAkB,EAAU,OAAO,EAC7D,GAAI,EACF,OAAO,EAIX,OAAO,EAAO,UAAY,iBAG5B,mBAAmB,CACjB,EACA,EACoB,CACpB,GAAI,GAAQ,aAAc,CACxB,IAAM,EAAW,EAAO,aAAa,CAAK,EACpC,EAAa,EAAsB,CAAQ,EACjD,GAAI,IAAe,OACjB,OAAO,EAIX,GAAI,EAAM,eAAiB,OACzB,OAAO,EAAsB,EAAM,YAAY,EAGjD,GACE,EAAM,OAAS,uBACf,EAAM,eAAiB,OAEvB,OAGF,QAGF,gBAAiB,CAAC,IAA4C,CAC5D,GACE,IAAe,QACf,OAAO,MAAM,CAAU,GACvB,CAAC,OAAO,SAAS,CAAU,EAE3B,MAAO,GAGT,OAAO,EAAa,KAGtB,eAAe,CAAC,EAAqC,CACnD,MAAO,CACL,kBAAmB,EAAM,kBACzB,kBAAmB,EAAM,kBACzB,WAAY,EAAM,WAClB,UAAW,EAAM,UACjB,aAAc,EAAM,aACpB,QAAS,EAAM,QACf,WAAY,EAAM,UACpB,GAGF,WAAW,CAAC,EAAkB,EAA4B,CACxD,OAAO,IAAI,EAAU,EAAM,KAAM,EAAM,QAAS,EAAM,QAAS,IAC1D,EAAW,gBAAgB,CAAK,EACnC,QAAS,EAAgB,CAAO,CAClC,CAAC,GAGH,gCACA,mCACF,EC9UA,SAAS,EAAW,CAAC,EAA2C,CAC9D,OAAQ,OACD,SACH,gCACG,UACH,kCACG,UACH,kCACG,OACH,+BACG,SACH,iCAUC,MAAM,UAAyB,CAAU,CACrC,KACA,UACA,SACA,aAET,WAAW,CACT,EACA,EACA,EACA,EAAqC,CAAC,EACtC,CACA,MAAM,GAAY,CAAI,EAAG,EAAS,EAAS,CAAQ,EACnD,KAAK,KAAO,mBACZ,KAAK,KAAO,EACZ,KAAK,UACH,OAAO,EAAS,YAAc,SAAW,EAAS,UAAY,OAChE,KAAK,SAAW,EAAS,SACzB,KAAK,aAAe,EAAS,aAGtB,MAAM,EAAG,CAChB,MAAO,IACF,MAAM,OAAO,EAChB,KAAM,KAAK,KACX,UAAW,KAAK,UAChB,SAAU,KAAK,SACf,aAAc,KAAK,YACrB,EAEJ,CClCA,IAAM,GAAkE,CACtE,WACA,aACA,WACF,EAEA,SAAS,CAAY,CAAC,EAAoC,CACxD,GAAI,OAAO,IAAU,SAAU,OAC/B,IAAM,EAAU,EAAM,KAAK,EAC3B,OAAO,EAAQ,OAAS,EAAI,EAAU,OAGxC,SAAS,EAAgB,CAAC,EAAoC,CAC5D,GAAI,OAAO,IAAU,UAAY,CAAC,OAAO,SAAS,CAAK,EAAG,OAC1D,GAAI,GAAS,GAAK,EAAQ,IAAK,OAC/B,OAAO,EAGT,SAAS,CAAe,CACtB,EAC0B,CAC1B,IAAM,EAAiC,CAAC,EACxC,QAAW,KAAU,EAAS,CAC5B,IAAM,EAAM,EAAa,EAAO,GAAG,EAC7B,EAAa,GAAiB,EAAO,UAAU,EACrD,GAAI,CAAC,GAAO,IAAe,OAAW,SACtC,EAAK,KAAK,CAAE,MAAK,YAAW,CAAC,EAE/B,OAAO,EAGT,SAAS,EAAW,CAClB,EACA,EACA,EACQ,CACR,IAAM,EAAU,EACb,IAAI,CAAC,IAAU,CACd,IAAM,EAAQ,EAAQ,GACtB,OAAO,OAAO,IAAU,SAAW,EAAQ,GAC5C,EACA,KAAK,GAAG,EACX,MAAO,GAAG,MAAS,IAMrB,SAAS,EAAM,CAAC,EAAuB,CACrC,IAAI,EAAO,WACX,QAAS,EAAQ,EAAG,EAAQ,EAAM,OAAQ,GAAS,EACjD,GAAQ,EAAM,WAAW,CAAK,EAC9B,EAAQ,EAAO,WAAgB,EAEjC,OAAO,IAAS,EAGlB,SAAS,EAAgB,CACvB,EACA,EACoB,CACpB,IAAI,EAAS,EACb,QAAW,KAAU,EAEnB,GADA,GAAU,EAAO,WACb,EAAa,EACf,OAAO,EAAO,IAGlB,OAGK,SAAS,CAAwB,CACtC,EACA,EACA,EACoB,CACpB,IAAM,EAAU,EAAgB,EAAO,OAAO,EACxC,EACJ,EAAa,EAAO,UAAU,GAAK,EAAa,CAAW,EAE7D,GAAI,EAAQ,SAAW,EACrB,OAAO,EAGT,IAAM,EAAO,EAAa,EAAO,IAAI,GAAK,kBACpC,EAAe,EAAO,cAAgB,GACtC,EAAY,GAAY,EAAS,EAAc,CAAI,EACnD,EAAa,GAAO,CAAS,EAAI,IACvC,OAAO,GAAiB,EAAS,CAAU,GAAK,EAG3C,SAAS,CAAmB,CACjC,EACmB,CACnB,OAAO,EAAgB,EAAO,OAAO,EAAE,IAAI,CAAC,IAAW,EAAO,GAAG,EC3FnE,SAAS,CAAY,CAAC,EAAoC,CACxD,GAAI,OAAO,IAAU,SAAU,OAC/B,IAAM,EAAU,EAAM,KAAK,EAC3B,OAAO,EAAQ,OAAS,EAAI,EAAU,OAGxC,SAAS,CAAgB,CAAC,EAAgD,CACxE,GAAI,CAAC,MAAM,QAAQ,CAAK,EAAG,MAAO,CAAC,EACnC,OAAO,EACJ,IAAI,CAAC,IAAQ,EAAa,CAAG,CAAC,EAC9B,OAAO,CAAC,IAAuB,QAAQ,CAAG,CAAC,EAGhD,SAAS,CAAU,CAAC,EAAqC,CACvD,IAAM,EAAiB,CAAC,EAClB,EAAO,IAAI,IACjB,QAAW,KAAS,EAAQ,CAC1B,IAAM,EAAa,EAAa,CAAK,EACrC,GAAI,CAAC,GAAc,EAAK,IAAI,CAAU,EAAG,SACzC,EAAK,IAAI,CAAU,EACnB,EAAK,KAAK,CAAU,EAEtB,OAAO,EAGT,SAAS,EAAsB,CAAC,EAAwC,CACtE,OAAO,EAAa,EAAQ,UAAU,GAAK,UAGtC,SAAS,CAAuB,CACrC,EACa,CACb,IAAM,EAAY,EAAa,EAAQ,SAAS,GAAK,UAC/C,EAAc,EAAW,CAC7B,EACA,GAAG,EAAiB,EAAQ,WAAW,CACzC,CAAC,EAED,MAAO,MACC,kBAAiB,EAAG,CACxB,MAAO,CAAE,IAAK,CAAU,QAEpB,mBAAkB,EAAG,CACzB,OAAO,EAEX,EAGK,SAAS,CAA4B,CAC1C,EACa,CACb,IAAM,EACJ,OAAO,EAAQ,aAAe,UAAY,EAAQ,YAAc,EAC5D,KAAK,MAAM,EAAQ,UAAU,EAC7B,MAEA,EAAoB,EAAa,EAAQ,UAAU,SAAS,EAC5D,EAAsB,EAAiB,EAAQ,UAAU,WAAW,EACtE,EAEJ,eAAe,CAAI,CAAC,EAAsD,CACxE,IAAM,EAAM,KAAK,IAAI,EACrB,GAAI,GAAS,EAAM,EAAM,UACvB,OAAO,EAAM,MAGf,IAAM,EAAS,MAAM,EAAQ,SAAS,WAAW,CAAO,EAClD,EACJ,EAAa,EAAO,SAAS,GAC7B,GACA,GAAuB,CAAO,EAE1B,EAAc,EAAW,CAC7B,EACA,GAAG,EAAiB,EAAO,WAAW,EACtC,GAAG,CACL,CAAC,EAEK,EAAoB,CACxB,YACA,cACA,YAAa,KAAK,IAAI,CACxB,EAKA,OAJA,EAAQ,CACN,MAAO,EACP,UAAW,KAAK,IAAI,EAAI,CAC1B,EACO,EAGT,MAAO,MACC,kBAAiB,CAAC,EAAS,CAE/B,MAAO,CAAE,KADK,MAAM,EAAK,CAAO,GACZ,SAAU,QAE1B,mBAAkB,CAAC,EAAS,CAChC,IAAM,EAAQ,MAAM,EAAK,CAAO,EAChC,OAAO,EAAM,aAAe,CAAC,EAAM,SAAS,EAEhD,EAGK,SAAS,EAAwB,CACtC,EACA,EACa,CACb,MAAO,MACC,kBAAiB,CAAC,EAAS,CAC/B,IAAM,EAAO,MAAM,EAAa,kBAAkB,CAAO,EAEzD,MAAO,CACL,IAFe,EAAyB,EAAS,EAAQ,EAAK,GAAG,GAEhD,EAAK,GACxB,QAEI,mBAAkB,CAAC,EAAS,CAChC,IAAM,EAAc,MAAM,EAAa,kBAAkB,CAAO,EAC1D,EAAc,EAAa,mBAC7B,MAAM,EAAa,mBAAmB,CAAO,EAC7C,CAAC,EAAY,GAAG,EACd,EAAW,EACf,EACA,EACA,EAAY,GACd,EACM,EAAc,EAAoB,CAAM,EAE9C,OAAO,EAAW,CAChB,GAAI,EAAW,CAAC,CAAQ,EAAI,CAAC,EAC7B,EAAY,IACZ,GAAI,GAAe,CAAC,EACpB,GAAG,CACL,CAAC,EAEL,EC3IK,SAAS,EAAuB,CACrC,EACa,CAWb,OAAO,EAA6B,CAClC,SAXoC,MAC9B,WAAU,CAAC,EAAS,CACxB,OAAO,EAAQ,OAAO,YAAY,IAC7B,KACC,EAAQ,SAAW,CAAE,SAAU,EAAQ,QAAS,EAAI,CAAC,KACrD,EAAQ,OAAS,CAAE,OAAQ,EAAQ,MAAO,EAAI,CAAC,CACrD,CAAC,EAEL,EAIE,WAAY,EAAQ,WACpB,SAAU,CACR,UAAW,EAAQ,kBACnB,YAAa,EAAQ,mBACvB,CACF,CAAC,EChCH,SAAS,CAAS,CAAC,EAAoC,CACrD,GAAI,OAAO,IAAU,SAAU,OAC/B,IAAM,EAAU,EAAM,KAAK,EAC3B,OAAO,EAAQ,OAAS,EAAI,EAAU,OAGxC,SAAS,CAAU,CACjB,EACA,EACoB,CACpB,OAAO,EAAU,EAAI,EAAI,EAG3B,SAAS,EAAS,CAAC,EAAyB,EAA6B,CACvE,GAAI,CAAC,EAAK,MAAO,CAAC,EAClB,OAAO,EACJ,MAAM,CAAS,EACf,IAAI,CAAC,IAAS,EAAU,CAAI,CAAC,EAC7B,OAAO,CAAC,IAAyB,QAAQ,CAAI,CAAC,EAG5C,SAAS,EAAoB,CAClC,EAAiC,CAAC,EACrB,CACb,IAAM,EACJ,EAAQ,MACN,OAAO,QAAY,IAAc,QAAQ,IAAM,CAAC,GAI9C,EAAY,EAAU,EAAQ,SAAS,GAAK,IAC5C,EAAe,EAAQ,cAAgB,kBACvC,EAAiB,EAAQ,gBAAkB,oBAE3C,EACJ,EAAW,EAAW,CAAY,GAClC,EAAU,EAAQ,iBAAiB,GACnC,UACI,EAAc,CAClB,EACA,GAAG,GAAU,EAAW,EAAW,CAAc,EAAG,CAAS,EAC7D,GAAI,EAAQ,qBAAuB,CAAC,CACtC,EAEA,OAAO,EAAwB,CAC7B,YACA,aACF,CAAC,ECjCI,SAAS,EAA6B,CAC3C,EACa,CAYb,OAAO,EAA6B,CAClC,SAZoC,MAC9B,WAAU,CAAC,EAAS,CACxB,OAAO,EAAQ,OAAO,YAAY,IAC7B,KACC,EAAQ,UAAY,CAAE,UAAW,EAAQ,SAAU,EAAI,CAAC,KACxD,EAAQ,QAAU,CAAE,QAAS,EAAQ,OAAQ,EAAI,CAAC,KAClD,EAAQ,UAAY,CAAE,UAAW,EAAQ,SAAU,EAAI,CAAC,CAC9D,CAAC,EAEL,EAIE,WAAY,EAAQ,WACpB,SAAU,CACR,UAAW,EAAQ,kBACnB,YAAa,EAAQ,mBACvB,CACF,CAAC,EC3BH,SAAS,CAAU,CAAC,EAA0D,CAC5E,OAAO,OAAO,IAAU,WAG1B,SAAS,CAAe,CAAC,EAAoC,CAC3D,GAAI,OAAO,IAAU,SAAU,OAC/B,IAAM,EAAU,EAAM,KAAK,EAC3B,OAAO,EAAQ,OAAS,EAAI,EAAU,OAGjC,SAAS,CAAgB,CAC9B,EACA,EACA,EACW,CACX,IAAM,EAAQ,EAAO,OAAO,GAC5B,GAAI,EAAO,OAAO,EAElB,GAAI,EAAK,WAAW,WAAW,EAAG,CAChC,IAAM,EAAW,EAAO,OAAO,cAC/B,GAAI,EAAU,OAAO,EAGvB,OAAO,EAGF,SAAS,EAAyB,CACvC,EACA,EAAoC,CAAC,EACF,CACnC,IAAM,EAA6C,CAAC,EAEpD,GAAI,CAAC,GAAU,OAAO,IAAW,SAC/B,MAAO,CACL,MAAO,GACP,OAAQ,CACN,CACE,QAAS,uCACT,KAAM,4BACN,KAAM,0CACR,CACF,CACF,EAGF,GAAI,CAAC,EAAO,UAAY,OAAO,EAAO,WAAa,SACjD,EAAO,KAAK,CACV,QAAS,mCACT,KAAM,gCACN,KAAM,WACN,KAAM,gDACR,CAAC,EACI,KACL,GAAI,CAAC,EAAW,EAAO,SAAS,OAAO,EACrC,EAAO,KAAK,CACV,QAAS,sCACT,KAAM,wCACN,KAAM,kBACR,CAAC,EAEH,GAAI,CAAC,EAAW,EAAO,SAAS,OAAO,EACrC,EAAO,KAAK,CACV,QAAS,sCACT,KAAM,wCACN,KAAM,kBACR,CAAC,EAEH,GAAI,CAAC,EAAW,EAAO,SAAS,IAAI,EAClC,EAAO,KAAK,CACV,QAAS,mCACT,KAAM,qCACN,KAAM,eACR,CAAC,EAIL,GAAI,CAAC,EAAO,QAAU,OAAO,EAAO,SAAW,SAC7C,EAAO,KAAK,CACV,QAAS,uCACT,KAAM,4BACN,KAAM,SACN,KAAM,wDACR,CAAC,EACI,KACL,IAAM,EAAU,OAAO,QAAQ,EAAO,MAAM,EAC5C,GAAI,EAAQ,SAAW,EACrB,EAAO,KAAK,CACV,QAAS,uCACT,KAAM,+BACN,KAAM,SACN,KAAM,qCACR,CAAC,EAGH,QAAY,EAAM,KAAS,EAAS,CAElC,GAAI,CADmB,EAAgB,CAAI,EAEzC,EAAO,KAAK,CACV,QAAS,wCACT,KAAM,oCACN,KAAM,QACR,CAAC,EAGH,GACE,IAAS,SACT,IAAS,WACT,IAAS,gBACT,IAAS,OAET,EAAO,KAAK,CACV,QAAS,2BAA2B,OAAO,CAAI,IAC/C,KAAM,oCACN,KAAM,UAAU,GAClB,CAAC,GAKP,IAAM,EAAW,EAAO,UAAY,SAC9B,EAAe,EAAO,cAAgB,SAC5C,GACE,IAAa,QACb,IAAiB,aACjB,EAAO,8BAAgC,GAEvC,EAAO,KAAK,CACV,QACE,mEACF,KAAM,wCACN,KAAM,eACN,KAAM,iEACR,CAAC,EAGH,GAAI,MAAM,QAAQ,EAAO,SAAS,EAAG,CACnC,GAAI,EAAO,UAAU,SAAW,EAC9B,EAAO,KAAK,CACV,QAAS,4CACT,KAAM,mCACN,KAAM,WACR,CAAC,EAGH,QAAS,EAAQ,EAAG,EAAQ,EAAO,UAAU,OAAQ,GAAS,EAAG,CAC/D,IAAM,EAAM,EAAO,UAAU,GAC7B,GAAI,CAAC,EAAgB,CAAG,EACtB,EAAO,KAAK,CACV,QAAS,qCACT,KAAM,sCACN,KAAM,aAAa,IACrB,CAAC,GAKP,GAAI,EAAQ,YAAc,CAAC,EAAQ,mBAAoB,CACrD,IAAM,EAAS,EAAiB,EAAQ,KAAM,cAAc,EACtD,EAAW,EAAiB,EAAQ,OAAQ,cAAc,EAEhE,GAAI,IAAW,QACb,EAAO,KAAK,CACV,QACE,+EACF,KAAM,uCACN,KAAM,YACN,KAAM,oCACR,CAAC,EAGH,GAAI,IAAa,QACf,EAAO,KAAK,CACV,QACE,iFACF,KAAM,yCACN,KAAM,cACN,KAAM,oCACR,CAAC,EAIL,MAAO,CACL,MAAO,EAAO,SAAW,EACzB,QACF,EAGK,SAAS,EAAuB,CACrC,EACA,EAAoC,CAAC,EAC/B,CACN,IAAM,EAAS,GAA0B,EAAQ,CAAO,EACxD,GAAI,EAAO,MAAO,OAElB,IAAM,EAAQ,EAAO,OAAO,GAC5B,GAAI,CAAC,EACH,MAAM,IAAI,EACR,SACA,uCACA,CACE,KAAM,6BACN,OAAQ,EAAO,MACjB,CACF,EAGF,MAAM,IAAI,EACR,SACA,EAAM,QACN,CACE,KAAM,EAAM,KACZ,KAAM,EAAM,KACZ,KAAM,EAAM,KACZ,OAAQ,EAAO,MACjB,EACA,CACE,UAAW,EAAM,IACnB,CACF,ECpHF,SAAS,CAAe,CAAC,EAA0C,CACjE,IAAM,EAAQ,aAAkB,WAAa,EAAS,IAAI,WAAW,CAAM,EACrE,EACJ,OAAO,WAAe,IAEhB,WAOA,OACF,OAIN,OAHe,EACX,EAAY,KAAK,CAAK,EAAE,SAAS,QAAQ,EACzC,KAAK,OAAO,aAAa,GAAG,CAAK,CAAC,GACxB,QAAQ,MAAO,GAAG,EAAE,QAAQ,MAAO,GAAG,EAAE,QAAQ,OAAQ,EAAE,EAG1E,SAAS,CAAe,CAAC,EAA2B,CAClD,IAAM,EAAa,EAAM,QAAQ,KAAM,GAAG,EAAE,QAAQ,KAAM,GAAG,EACvD,EACJ,EAAW,OAAS,IAAM,EACtB,EACA,GAAG,IAAa,IAAI,OAAO,EAAK,EAAW,OAAS,CAAE,IAEtD,EACJ,OAAO,WAAe,IAEhB,WAGA,OACF,OAEN,GAAI,EACF,OAAO,IAAI,WAAW,EAAY,KAAK,EAAQ,QAAQ,CAAC,EAG1D,IAAM,EAAS,KAAK,CAAM,EACpB,EAAQ,IAAI,WAAW,EAAO,MAAM,EAC1C,QAAS,EAAQ,EAAG,EAAQ,EAAO,OAAQ,GAAS,EAClD,EAAM,GAAS,EAAO,WAAW,CAAK,EAExC,OAAO,EAGT,SAAS,CAAY,CACnB,EACA,EACY,CACZ,GAAI,aAAiB,WAAY,OAAO,EACxC,GAAI,aAAiB,YAAa,OAAO,IAAI,WAAW,CAAK,EAC7D,GAAI,IAAa,YAAa,OAAO,EAAgB,CAAK,EAC1D,OAAO,IAAI,YAAY,EAAE,OAAO,CAAK,EAGvC,SAAS,EAAK,CAAC,EAA0C,CACvD,IAAM,EAAQ,aAAkB,WAAa,EAAS,IAAI,WAAW,CAAM,EAC3E,OAAO,MAAM,KAAK,CAAK,EACpB,IAAI,CAAC,IAAS,EAAK,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,EAChD,KAAK,EAAE,EAGZ,SAAS,CAAoB,CAAC,EAAgC,CAC5D,IAAM,EAAO,IAAI,WAAW,EAAM,UAAU,EAE5C,OADA,EAAK,IAAI,CAAK,EACP,EAAK,OAGd,SAAS,EAAa,CAAC,EAAoC,CACzD,IAAM,EAAS,KAAK,MAAM,CAAU,EACpC,GACE,CAAC,GACD,OAAO,IAAW,UAClB,OAAO,EAAO,IAAM,UACpB,OAAO,EAAO,MAAQ,UACtB,OAAO,EAAO,MAAQ,UACtB,OAAO,EAAO,KAAO,UACrB,OAAO,EAAO,MAAQ,UACtB,OAAO,EAAO,KAAO,SAErB,MAAU,MAAM,6BAA6B,EAG/C,OAAO,EAGT,SAAS,EAAkB,CAAC,EAAwC,CAClE,GAAI,OAAO,IAAU,SAAU,OAAO,EACtC,OAAO,KAAK,UAAU,CAAK,EAGtB,SAAS,EAAgB,CAAC,EAAyC,CACxE,GAAI,CAAC,GAAS,OAAO,IAAU,SAAU,MAAO,GAChD,IAAM,EAAY,EAClB,OACE,OAAO,EAAU,IAAM,UACvB,OAAO,EAAU,MAAQ,UACzB,OAAO,EAAU,MAAQ,UACzB,OAAO,EAAU,KAAO,UACxB,OAAO,EAAU,MAAQ,UACzB,OAAO,EAAU,KAAO,SAIrB,SAAS,EAAqB,CAAC,EAAuB,CAC3D,IAAM,EAAU,OAAO,GAAS,EAAE,EAAE,KAAK,EACzC,GAAI,EAAQ,SAAW,EAAG,MAAO,GAEjC,IAAM,EAAiB,EAAQ,WAAW,GAAG,EACvC,EAAa,EAAQ,QAAQ,MAAO,EAAE,EAC5C,OAAO,EAAiB,IAAI,IAAe,EAGtC,SAAS,EAAmB,CACjC,EAAe,EACf,EAAa,EACc,CAC3B,MAAO,CAAC,IAA0B,CAChC,IAAM,EAAa,OAAO,GAAS,EAAE,EACrC,GAAI,EAAW,QAAU,EAAe,EACtC,MAAO,IAAI,OAAO,KAAK,IAAI,EAAG,EAAW,MAAM,CAAC,EAElD,IAAM,EAAQ,EAAW,MAAM,EAAG,CAAY,EACxC,EAAM,EAAW,MAAM,CAAC,CAAU,EACxC,MAAO,GAAG,IAAQ,IAAI,OAAO,EAAW,OAAS,EAAe,CAAU,IAAI,KAa3E,SAAS,EAA+B,CAC7C,EACqB,CACrB,IAAM,EAAY,EAAQ,WAAa,UACjC,EAAc,EAAQ,aAAe,YACrC,EAAkB,EAAQ,iBAAmB,EAC7C,EAAc,IAAI,IAClB,EAAe,IAAI,IAEnB,EAAe,CAAC,IAAoC,CACxD,IAAM,EAAS,EAAY,IAAI,CAAG,EAClC,GAAI,EAAQ,OAAO,EAEnB,IAAM,EAAM,EAAQ,KAAK,GACzB,GAAI,CAAC,EACH,MAAU,MAAM,8BAA8B,GAAK,EAErD,IAAM,EAAQ,EAAa,EAAK,CAAW,EACrC,EAAU,OAAO,OAAO,UAC5B,MACA,EAAqB,CAAK,EAC1B,UACA,GACA,CAAC,UAAW,SAAS,CACvB,EAEA,OADA,EAAY,IAAI,EAAK,CAAO,EACrB,GAGH,EAAgB,CAAC,IAAoC,CACzD,IAAM,EAAS,EAAa,IAAI,CAAG,EACnC,GAAI,EAAQ,OAAO,EAEnB,IAAM,EAAM,EAAQ,WAAW,IAAQ,EAAQ,KAAK,GACpD,GAAI,CAAC,EACH,MAAU,MAAM,wBAAwB,GAAK,EAE/C,IAAM,EAAQ,EAAa,EAAK,CAAe,EACzC,EAAU,OAAO,OAAO,UAC5B,MACA,EAAqB,CAAK,EAC1B,CAAE,KAAM,OAAQ,KAAM,SAAU,EAChC,GACA,CAAC,MAAM,CACT,EAEA,OADA,EAAa,IAAI,EAAK,CAAO,EACtB,GAGT,MAAO,MACC,QAAO,CAAC,EAAO,CACnB,IAAM,EAAM,EAAM,KAAO,EAAQ,UAC3B,EAAM,MAAM,EAAa,CAAG,EAC5B,EAAK,OAAO,gBAAgB,IAAI,WAAW,EAAE,CAAC,EAC9C,EAAiB,IAAI,YAAY,EAAE,OACvC,KAAK,UAAU,EAAM,KAAO,CAAC,CAAC,CAChC,EACM,EAAY,IAAI,YAAY,EAAE,OAAO,EAAM,KAAK,EAEhD,EAAY,MAAM,OAAO,OAAO,QACpC,CACE,KAAM,UACN,GAAI,EAAqB,CAAE,EAC3B,eAAgB,EAAqB,CAAc,EACnD,UAAW,GACb,EACA,EACA,EAAqB,CAAS,CAChC,EAEM,EAAiB,IAAI,WAAW,CAAS,EACzC,EAAM,EAAe,MAAM,EAAe,OAAS,EAAE,EACrD,EAAa,EAAe,MAAM,EAAG,EAAe,OAAS,EAAE,EAErE,MAAO,CACL,WAAY,CACV,EAAG,EACH,IAAK,EACL,MACA,GAAI,EAAgB,CAAE,EACtB,IAAK,EAAgB,CAAG,EACxB,GAAI,EAAgB,CAAU,CAChC,EACA,KACF,QAGI,QAAO,CAAC,EAAO,CACnB,IAAM,EAAW,GAAc,EAAM,UAAU,EACzC,EACJ,EAAM,eAAiB,EAAM,cAAc,OAAS,EAChD,EAAM,cACN,CAAC,EAAS,GAAG,EACb,EAAK,EAAgB,EAAS,EAAE,EAChC,EAAM,EAAgB,EAAS,GAAG,EAClC,EAAa,EAAgB,EAAS,EAAE,EAExC,EAAY,IAAI,WAAW,EAAW,OAAS,EAAI,MAAM,EAC/D,EAAU,IAAI,EAAY,CAAC,EAC3B,EAAU,IAAI,EAAK,EAAW,MAAM,EAEpC,IAAM,EAAiB,IAAI,YAAY,EAAE,OACvC,KAAK,UAAU,EAAM,KAAO,CAAC,CAAC,CAChC,EAEI,EACJ,QAAW,KAAO,EAChB,GAAI,CACF,IAAM,EAAM,MAAM,EAAa,CAAG,EAC5B,GAAY,MAAM,OAAO,OAAO,QACpC,CACE,KAAM,UACN,GAAI,EAAqB,CAAE,EAC3B,eAAgB,EAAqB,CAAc,EACnD,UAAW,GACb,EACA,EACA,EAAqB,CAAS,CAChC,EACA,OAAO,IAAI,YAAY,EAAE,OAAO,IAAI,WAAW,EAAS,CAAC,EACzD,MAAO,EAAO,CACd,EAAY,EAIhB,MAAU,MACR,iCAAiC,aAAqB,MAAQ,EAAU,QAAU,OAAO,GAAa,SAAS,GACjH,QAGI,KAAI,CAAC,EAAO,CAChB,IAAM,EAAM,EAAM,KAAO,EAAQ,UAC3B,EAAM,MAAM,EAAc,CAAG,EAC7B,EAAY,MAAM,OAAO,OAAO,KACpC,OACA,EACA,EAAqB,IAAI,YAAY,EAAE,OAAO,EAAM,KAAK,CAAC,CAC5D,EACA,OAAO,GAAM,CAAS,GAGxB,IAAI,CAAC,EAAO,CACV,OAAO,GAAoB,EAAE,EAAM,KAAK,EAE5C,EAGK,SAAS,EAA6B,EAAwB,CACnE,MAAO,CACL,OAAO,CAAC,EAAO,CACb,MAAO,CACL,WAAY,KAAK,UAAU,CACzB,EAAG,EACH,IAAK,OACL,IAAK,OACL,GAAI,GACJ,IAAK,GACL,GAAI,EAAM,KACZ,CAA0B,CAC5B,GAEF,OAAO,CAAC,EAAO,CACb,GAAI,CAEF,OADe,GAAc,EAAM,UAAU,EAC/B,GACd,KAAM,CACN,OAAO,EAAM,aAGjB,IAAI,CAAC,EAAO,CACV,IAAM,EAAa,GAAsB,EAAM,KAAK,EACpD,OAAO,EAAgB,IAAI,YAAY,EAAE,OAAO,CAAU,CAAC,GAE7D,IAAI,CAAC,EAAO,CACV,OAAO,GAAoB,EAAE,EAAM,KAAK,EAE5C,EAGK,SAAS,EAA0B,CACxC,EACQ,CACR,OAAO,GAAmB,CAAU,EC5b/B,IAAK,IAAL,CAAK,IAAL,CACL,QAAQ,QACR,OAAO,OACP,OAAO,OACP,QAAQ,UAJE,SAuCZ,IAAM,GAAyB,CAC7B,KACA,OACA,QACA,cACA,YACA,SACA,SACA,SACA,YACA,gBACA,OACA,QACA,WACA,UACA,UACA,UACA,MACF,EAEA,SAAS,EAAqB,CAAC,EAAyB,CACtD,IAAM,EAAM,EAAO,YAAY,EAC/B,OAAO,GAAuB,KAAK,CAAC,IAClC,EAAI,SAAS,EAAU,YAAY,CAAC,CACtC,EAGF,SAAS,EAAe,CAAC,EAAuB,CAC9C,IAAM,EAAU,EAAM,KAAK,EAC3B,GAAI,EAAQ,QAAU,EAAG,MA9BN,MA+BnB,GAAI,EAAQ,SAAS,GAAG,EAAG,CACzB,IAAO,EAAO,GAAU,EAAQ,MAAM,GAAG,EAEzC,MAAO,GADM,EAAM,MAAM,EAAG,CAAC,IACZ,IAAI,OAAO,KAAK,IAAI,EAAG,EAAM,OAAS,CAAC,CAAC,KAAK,IAEhE,IAAM,EAAO,EAAQ,MAAM,EAAG,CAAC,EACzB,EAAO,EAAQ,MAAM,EAAE,EAC7B,MAAO,GAAG,IAAO,IAAI,OAAO,KAAK,IAAI,EAAG,EAAQ,OAAS,CAAC,CAAC,IAAI,IAGjE,SAAS,CAAoB,CAAC,EAAa,EAAyB,CAClE,GAAI,IAAU,QAAa,IAAU,KAAM,OAAO,EAElD,GAAI,GAAsB,CAAG,EAAG,CAC9B,GAAI,OAAO,IAAU,SAAU,OAAO,GAAgB,CAAK,EAC3D,GAAI,OAAO,IAAU,UAAY,OAAO,IAAU,UAChD,MA/Ce,MAiDjB,GAAI,MAAM,QAAQ,CAAK,EAAG,MAlDP,aAmDnB,GAAI,OAAO,IAAU,SAAU,MAnDZ,aAsDrB,GAAI,MAAM,QAAQ,CAAK,EACrB,OAAO,EAAM,IAAI,CAAC,IAAU,EAAqB,EAAK,CAAK,CAAC,EAG9D,GAAI,OAAO,IAAU,SAAU,CAC7B,IAAM,EAAgC,CAAC,EACvC,QAAY,EAAU,KAAe,OAAO,QAAQ,CAAK,EACvD,EAAK,GAAY,EAAqB,EAAU,CAAU,EAE5D,OAAO,EAGT,OAAO,EAGT,SAAS,EAAkB,CAAC,EAAiC,CAC3D,IAAM,EAAwB,CAAC,EAC/B,QAAY,EAAK,KAAU,OAAO,QAAQ,CAAO,EAC/C,EAAU,GAAO,EAAqB,EAAK,CAAK,EAElD,OAAO,EAGF,MAAM,CAAO,CACV,OACA,QAER,WAAW,CAAC,EAAsB,CAAC,EAAG,EAAgC,CAAC,EAAG,CACxE,KAAK,QAAU,EACf,KAAK,OAAS,CACZ,MAAO,OACP,cAAe,GACf,WAAY,GACZ,aAAc,MACX,CACL,EAGM,SAAS,CAAC,EAA0B,CAC1C,IAAM,EAAS,CACb,QACA,OACA,OACA,OACF,EACA,OAAO,EAAO,QAAQ,CAAK,GAAK,EAAO,QAAQ,KAAK,OAAO,KAAK,EAG1D,aAAa,CAAC,EAAyB,CAC7C,IAAM,EAAU,GAAmB,EAAM,OAAO,EAEhD,GAAI,KAAK,OAAO,WACd,OAAO,KAAK,UAAU,CACpB,MAAO,EAAM,MACb,QAAS,EAAM,QACf,UAAW,EAAM,UAAU,YAAY,EACvC,aACI,EAAM,OAAS,CACjB,MAAO,CACL,KAAM,EAAM,MAAM,KAClB,QAAS,EAAM,MAAM,QACrB,MAAO,EAAM,MAAM,KACrB,CACF,KACI,EAAM,UAAY,CAAE,SAAU,EAAM,QAAS,CACnD,CAAC,EAGH,IAAM,EAAY,EAAM,UAAU,YAAY,EACxC,EAAQ,KAAK,OAAO,aACtB,KAAK,cAAc,EAAM,KAAK,EAC9B,EAAM,MACJ,EACJ,OAAO,KAAK,CAAO,EAAE,OAAS,EAC1B,KAAK,OAAO,QAAQ,CAAO,EACxB,IAAI,EAAE,EAAG,KAAO,GAAG,KAAK,GAAG,EAC3B,KAAK,IAAI,KACZ,GAEF,EAAU,GAAG,KAAa,IAAQ,MAAe,EAAM,UAE3D,GAAI,EAAM,WAAa,OACrB,GAAW,KAAK,EAAM,cAGxB,GAAI,EAAM,MACR,GAAW;AAAA,EAAK,EAAM,MAAM,QAG9B,OAAO,EAGD,aAAa,CAAC,EAAyB,CAC7C,GAAI,CAAC,KAAK,OAAO,aAAc,OAAO,EAStC,MAAO,GAPQ,EACZ,SAAiB,YACjB,QAAgB,YAChB,QAAgB,YAChB,SAAiB,UACpB,EAEiB,KAAS,WAGpB,QAAQ,CAAC,EAAuB,CACtC,GAAI,CAAC,KAAK,UAAU,EAAM,KAAK,EAAG,OAElC,IAAM,EAAU,KAAK,cAAc,CAAK,EAExC,GAAI,KAAK,OAAO,eAEZ,EAAM,QAAU,QACZ,QAAQ,MACR,EAAM,QAAU,OACd,QAAQ,KACR,QAAQ,KACV,CAAO,EAIf,GAAI,KAAK,OAAO,YAAc,KAAK,OAAO,SAAU,EAKtD,KAAK,CAAC,EAAiB,EAAsB,CAAC,EAAS,CACrD,KAAK,SAAS,CACZ,MAAO,QACP,UACA,UAAW,IAAI,KACf,QAAS,IAAK,KAAK,WAAY,CAAQ,CACzC,CAAC,EAGH,IAAI,CAAC,EAAiB,EAAsB,CAAC,EAAS,CACpD,KAAK,SAAS,CACZ,MAAO,OACP,UACA,UAAW,IAAI,KACf,QAAS,IAAK,KAAK,WAAY,CAAQ,CACzC,CAAC,EAGH,IAAI,CAAC,EAAiB,EAAsB,CAAC,EAAG,EAAqB,CACnE,KAAK,SAAS,CACZ,MAAO,OACP,UACA,UAAW,IAAI,KACf,QAAS,IAAK,KAAK,WAAY,CAAQ,EACvC,OACF,CAAC,EAGH,KAAK,CAAC,EAAiB,EAAsB,CAAC,EAAG,EAAqB,CACpE,KAAK,SAAS,CACZ,MAAO,QACP,UACA,UAAW,IAAI,KACf,QAAS,IAAK,KAAK,WAAY,CAAQ,EACvC,OACF,CAAC,EAGH,KAAK,CAAC,EAA6B,CACjC,OAAO,IAAI,EAAO,IAAK,KAAK,WAAY,CAAQ,EAAG,KAAK,MAAM,EAGhE,IAAI,CAAC,EAA2B,CAC9B,IAAM,EAAQ,KAAK,IAAI,EACvB,MAAO,IAAM,CACX,IAAM,EAAW,KAAK,IAAI,EAAI,EAC9B,KAAK,KAAK,GAAG,cAAmB,CAAE,UAAS,CAAC,QAI1C,QAAU,CACd,EACA,EACA,EAAsB,CAAC,EACX,CACZ,IAAM,EAAQ,KAAK,IAAI,EACjB,EAAmB,IAAK,EAAS,WAAU,EAEjD,KAAK,MAAM,YAAY,IAAa,CAAgB,EAEpD,GAAI,CACF,IAAM,EAAS,MAAM,EAAG,EAClB,EAAW,KAAK,IAAI,EAAI,EAG9B,OADA,KAAK,KAAK,aAAa,IAAa,IAAK,EAAkB,UAAS,CAAC,EAC9D,EACP,MAAO,EAAO,CACd,IAAM,EAAW,KAAK,IAAI,EAAI,EAO9B,MALA,KAAK,MACH,UAAU,IACV,IAAK,EAAkB,UAAS,EAChC,aAAiB,MAAQ,EAAY,MAAM,OAAO,CAAK,CAAC,CAC1D,EACM,GAGZ,CAGA,IAAI,EAEG,SAAS,EAAY,CAC1B,EACA,EACQ,CACR,OAAO,IAAI,EAAO,EAAS,CAAM,EAG5B,SAAS,CAAS,EAAW,CAClC,GAAI,CAAC,EACH,EAAe,GAAa,EAE9B,OAAO,EAGF,SAAS,EAAe,CAAC,EAAsB,CACpD,EAAe,EAIV,IAAM,GAAS,CACpB,MAAO,CAAC,EAAiB,IACvB,EAAU,EAAE,MAAM,EAAS,CAAO,EACpC,KAAM,CAAC,EAAiB,IACtB,EAAU,EAAE,KAAK,EAAS,CAAO,EACnC,KAAM,CAAC,EAAiB,EAAsB,IAC5C,EAAU,EAAE,KAAK,EAAS,EAAS,CAAK,EAC1C,MAAO,CAAC,EAAiB,EAAsB,IAC7C,EAAU,EAAE,MAAM,EAAS,EAAS,CAAK,EAC3C,MAAO,CAAC,IAAwB,EAAU,EAAE,MAAM,CAAO,EACzD,KAAM,CAAC,IAAkB,EAAU,EAAE,KAAK,CAAK,EAC/C,QAAS,CAAI,EAAmB,EAAsB,IACpD,EAAU,EAAE,QAAQ,EAAW,EAAI,CAAO,CAC9C,EAGO,SAAS,EAAgB,CAAC,EAAgC,CAC/D,IAAM,EAAgB,GAAa,CAAC,EAAG,CAAM,EAE7C,MAAO,OAAO,EAAQ,IAAc,CAClC,IAAM,EAAQ,KAAK,IAAI,EAGjB,EAAU,CACd,UAHgB,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,CAAC,EAItD,OAAQ,EAAE,IAAI,OACd,KAAM,EAAE,IAAI,KACZ,UAAW,EAAE,IAAI,OAAO,YAAY,GAAK,SAC3C,EAEA,EAAc,KAAK,kBAAmB,CAAO,EAE7C,GAAI,CACF,MAAM,EAAK,EAEX,IAAM,EAAW,KAAK,IAAI,EAAI,EAC9B,EAAc,KAAK,oBAAqB,IACnC,EACH,OAAQ,EAAE,IAAI,OACd,UACF,CAAC,EACD,MAAO,EAAO,CACd,IAAM,EAAW,KAAK,IAAI,EAAI,EAU9B,MATA,EAAc,MACZ,iBACA,IACK,EACH,UACF,EACA,aAAiB,MAAQ,EAAY,MAAM,OAAO,CAAK,CAAC,CAC1D,EAEM,IC/VL,MAAM,CAAa,OACT,gBAA+B,CAC5C,YAAa,EACb,aAAc,KACd,SAAU,MACV,kBAAmB,EACnB,OAAQ,GACR,eAAgB,CAAC,IAAU,EAAW,YAAY,CAAK,CACzD,cAEa,QAAU,CACrB,EACA,EAAiC,CAAC,EACtB,CACZ,IAAM,EAAO,IACR,EAAa,kBACb,CACL,EACI,EACA,EAAQ,EAAK,aAEjB,QAAS,EAAU,EAAG,GAAW,EAAK,YAAa,IACjD,GAAI,CACF,OAAO,MAAM,EAAU,EACvB,MAAO,EAAO,CAGd,GAFA,EAAY,EAGV,IAAY,EAAK,aACjB,CAAC,EAAK,eAAgB,EAAW,CAAO,EAExC,MAAM,EAGR,IAAM,EAAc,EAAK,OACrB,EAAQ,KAAK,OAAO,EAAI,EAAQ,IAChC,EAEJ,EAAK,UAAU,EAAW,CAAO,EAEjC,MAAM,IAAI,QAAQ,CAAC,IAAY,WAAW,EAAS,CAAW,CAAC,EAE/D,EAAQ,KAAK,IAAI,EAAQ,EAAK,kBAAmB,EAAK,QAAQ,EAIlE,MAAM,QAGD,wBAA2C,CAChD,EACA,EAAiC,CAAC,EACN,CAC5B,MAAO,UAAU,IAAY,CAC3B,OAAO,EAAa,QAAQ,IAAM,EAAK,GAAG,CAAI,EAAG,CAAO,GAG9D,CC9DO,MAAM,CAAqB,aACnB,QAAa,CACxB,EACA,EACA,EAAyC,CAAC,EAUzC,CACD,IAAM,EAA6B,CACjC,YAAa,EACb,aAAc,CACZ,YAAa,EACb,aAAc,KACd,SAAU,IACV,kBAAmB,EACnB,OAAQ,EACV,EACA,SAAU,MACP,CACL,EAEM,EAAY,KAAK,IAAI,EACrB,EAAuC,CAAC,EACxC,EAAsC,CAAC,EACzC,EAAY,EAEV,EAAqB,EAAa,wBACtC,EACA,EAAK,YACP,EAEM,EAAU,EAAqB,cAAc,EAAO,EAAK,WAAW,EAE1E,QAAW,KAAS,EAAS,CAC3B,IAAM,EAAgB,EAAM,IAAI,MAAO,IAAS,CAC9C,GAAI,CACF,IAAM,EAAS,MAAM,EAAmB,CAAI,EAC5C,EAAW,KAAK,CAAE,OAAM,QAAO,CAAC,EAChC,MAAO,EAAO,CAGd,GAFA,EAAO,KAAK,CAAE,OAAM,MAAO,CAAe,CAAC,EAEvC,EAAK,SACP,MAAM,IAAI,wBAER,oCAAoC,EAAO,kBAC3C,CAAE,WAAY,EAAM,OAAQ,YAAa,EAAO,MAAO,CACzD,SAEF,CACA,IACA,EAAK,aAAa,EAAW,EAAM,OAAQ,EAAO,MAAM,GAE3D,EAID,GAFA,MAAM,QAAQ,WAAW,CAAa,EAElC,EAAK,UAAY,EAAO,OAAS,EACnC,MAIJ,IAAM,EAAW,KAAK,IAAI,EAAI,EAE9B,MAAO,CACL,aACA,SACA,QAAS,CACP,MAAO,EAAM,OACb,WAAY,EAAW,OACvB,OAAQ,EAAO,OACf,UACF,CACF,QAGa,cAAgB,CAAC,EAAY,EAA0B,CACpE,IAAM,EAAiB,CAAC,EACxB,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,GAAK,EACrC,EAAQ,KAAK,EAAM,MAAM,EAAG,EAAI,CAAS,CAAC,EAE5C,OAAO,EAEX,CCxFO,MAAM,EAAe,CAMN,QALZ,MAAyC,SACzC,aAAe,EACf,gBAAkB,EAClB,gBAAkB,EAE1B,WAAW,CAAS,EAAgC,CAAhC,oBAEd,QAAU,CAAC,EAAyC,CACxD,IAAM,EAAM,KAAK,IAAI,EAErB,OAAQ,KAAK,WACN,OACH,GAAI,EAAM,KAAK,gBACb,MAAM,IAAI,gCAER,0BACA,CAAE,MAAO,KAAK,MAAO,gBAAiB,KAAK,eAAgB,CAC7D,EAEF,KAAK,MAAQ,YACb,KAAK,QAAQ,aAAa,EAC1B,UAEG,YACH,UAEG,SACH,MAGJ,GAAI,CACF,IAAM,EAAS,MAAM,QAAQ,KAAK,CAChC,EAAU,EACV,IAAI,QAAe,CAAC,EAAG,IACrB,WACE,IACE,EACE,IAAI,oBAEF,0BACA,CAAE,QAAS,KAAK,QAAQ,OAAQ,CAClC,CACF,EACF,KAAK,QAAQ,OACf,CACF,CACF,CAAC,EAED,GAAI,KAAK,QAAU,YACjB,KAAK,MAAQ,SACb,KAAK,aAAe,EACpB,KAAK,QAAQ,UAAU,EAGzB,OAAO,EACP,MAAO,EAAO,CAEd,MADA,KAAK,cAAc,EACb,GAIF,aAAa,EAAS,CAI5B,GAHA,KAAK,eACL,KAAK,gBAAkB,KAAK,IAAI,EAE5B,KAAK,cAAgB,KAAK,QAAQ,iBACpC,KAAK,MAAQ,OACb,KAAK,gBAAkB,KAAK,gBAAkB,KAAK,QAAQ,aAC3D,KAAK,QAAQ,SAAS,EAI1B,QAAQ,EAAW,CACjB,OAAO,KAAK,MAGd,eAAe,EAAW,CACxB,OAAO,KAAK,aAGd,KAAK,EAAS,CACZ,KAAK,MAAQ,SACb,KAAK,aAAe,EACpB,KAAK,gBAAkB,EACvB,KAAK,gBAAkB,EAE3B,CClGO,MAAM,EAAY,CAIb,YACA,SAJF,SAAqB,CAAC,EAE9B,WAAW,CACD,EACA,EACR,CAFQ,mBACA,qBAGJ,QAAO,EAAkB,CAC7B,IAAM,EAAM,KAAK,IAAI,EAIrB,GAFA,KAAK,SAAW,KAAK,SAAS,OAAO,CAAC,IAAS,EAAM,EAAO,KAAK,QAAQ,EAErE,KAAK,SAAS,QAAU,KAAK,YAAa,CAC5C,IAAM,EAAgB,KAAK,IAAI,GAAG,KAAK,QAAQ,EACzC,EAAW,KAAK,UAAY,EAAM,GAExC,GAAI,EAAW,EAEb,OADA,MAAM,IAAI,QAAQ,CAAC,IAAY,WAAW,EAAS,CAAQ,CAAC,EACrD,KAAK,QAAQ,EAIxB,KAAK,SAAS,KAAK,CAAG,EAGxB,cAAc,EAAY,CACxB,IAAM,EAAM,KAAK,IAAI,EAErB,OADA,KAAK,SAAW,KAAK,SAAS,OAAO,CAAC,IAAS,EAAM,EAAO,KAAK,QAAQ,EAClE,KAAK,SAAS,OAAS,KAAK,YAGrC,oBAAoB,EAAW,CAC7B,IAAM,EAAM,KAAK,IAAI,EAErB,OADA,KAAK,SAAW,KAAK,SAAS,OAAO,CAAC,IAAS,EAAM,EAAO,KAAK,QAAQ,EAClE,KAAK,IAAI,EAAG,KAAK,YAAc,KAAK,SAAS,MAAM,EAE9D,CC3BO,IAAM,GAAK,CAAI,KAAqB,CACzC,UAAW,GACX,UAAW,GACX,OACF,GAEa,GAAO,CAAI,KAAuB,CAC7C,UAAW,GACX,UAAW,GACX,OACF,GAKa,GAAS,CAIpB,GAAY,CAAC,EAAsB,EAAmC,CACpE,GAAI,EAAO,UACT,OAAO,GAAG,EAAG,EAAO,KAAK,CAAC,EAE5B,OAAO,GAMT,OAAgB,CACd,EACA,EACc,CACd,GAAI,EAAO,UACT,OAAO,EAAG,EAAO,KAAK,EAExB,OAAO,GAMT,QAAiB,CAAC,EAAsB,EAAmC,CACzE,GAAI,EAAO,UACT,OAAO,GAAK,EAAG,EAAO,KAAK,CAAC,EAE9B,OAAO,GAMT,MAAY,CAAC,EAAyB,CACpC,GAAI,EAAO,UACT,OAAO,EAAO,MAEhB,MAAM,EAAO,OAMf,QAAc,CAAC,EAAsB,EAAoB,CACvD,GAAI,EAAO,UACT,OAAO,EAAO,MAEhB,OAAO,GAMT,YAAkB,CAAC,EAAsB,EAAwB,CAC/D,GAAI,EAAO,UACT,OAAO,EAAO,MAEhB,OAAO,EAAG,EAAO,KAAK,GAMxB,KAAc,CACZ,EACA,EACG,CACH,GAAI,EAAO,UACT,OAAO,EAAS,GAAG,EAAO,KAAK,EAEjC,OAAO,EAAS,KAAK,EAAO,KAAK,QAM7B,YAAyB,CAAC,EAA4C,CAC1E,GAAI,CACF,IAAM,EAAQ,MAAM,EACpB,OAAO,GAAG,CAAK,EACf,MAAO,EAAO,CACd,OAAO,GAAK,CAAU,IAO1B,IAAU,CAAC,EAAuC,CAChD,OAAO,EAAO,WAMhB,MAAY,CAAC,EAAyC,CACpD,OAAO,EAAO,UAElB,ECjHO,SAAS,EAAmB,EAAqB,CACtD,IAAM,EAAgB,WACtB,OACE,EAAc,eACd,EAAc,SACd,EAAc,SAAS,KACvB,CAAC,EAIE,SAAS,EAAc,CAAC,EAAiC,CAC9D,IAAM,EAAQ,GAAoB,EAAE,GACpC,GAAI,OAAO,IAAU,SACnB,OAAO,EAET,GAAI,IAAU,OACZ,OAEF,OAAO,OAAO,CAAK,EClBd,IAAM,GAA0C,CACrD,UACA,OACA,QACF,EAEa,GAAuC,UAEvC,GAAyB,CAAC,IAAmC,CACxE,IAAM,EAAM,OAAO,IAAW,SAAW,EAAO,KAAK,EAAE,YAAY,EAAI,GAEvE,GAAI,IAAQ,WAAa,IAAQ,QAAU,IAAQ,SACjD,OAAO,EAGT,MATkD",
|
|
24
|
+
"debugId": "7D63913E6C8742B764756E2164756E21",
|
|
20
25
|
"names": []
|
|
21
26
|
}
|