nucleus-core-ts 0.9.754 → 0.9.755
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ See the Apache Version 2.0 License for specific language governing permissions
|
|
|
14
14
|
and limitations under the License.
|
|
15
15
|
***************************************************************************** */var Reflect2;(function(Reflect3){(function(factory){var root=typeof globalThis==="object"?globalThis:typeof global==="object"?global:typeof self==="object"?self:typeof this==="object"?this:sloppyModeThis(),exporter=makeExporter(Reflect3);if(typeof root.Reflect<"u")exporter=makeExporter(root.Reflect,exporter);if(factory(exporter,root),typeof root.Reflect>"u")root.Reflect=Reflect3;function makeExporter(target,previous){return function(key,value){if(Object.defineProperty(target,key,{configurable:!0,writable:!0,value}),previous)previous(key,value)}}function functionThis(){try{return Function("return this;")()}catch(_){}}function indirectEvalThis(){try{return(0,eval)("(function() { return this; })()")}catch(_){}}function sloppyModeThis(){return functionThis()||indirectEvalThis()}})(function(exporter,root){var hasOwn=Object.prototype.hasOwnProperty,supportsSymbol=typeof Symbol==="function",toPrimitiveSymbol=supportsSymbol&&typeof Symbol.toPrimitive<"u"?Symbol.toPrimitive:"@@toPrimitive",iteratorSymbol=supportsSymbol&&typeof Symbol.iterator<"u"?Symbol.iterator:"@@iterator",supportsCreate=typeof Object.create==="function",supportsProto={__proto__:[]}instanceof Array,downLevel=!supportsCreate&&!supportsProto,HashMap={create:supportsCreate?function(){return MakeDictionary(Object.create(null))}:supportsProto?function(){return MakeDictionary({__proto__:null})}:function(){return MakeDictionary({})},has:downLevel?function(map,key){return hasOwn.call(map,key)}:function(map,key){return key in map},get:downLevel?function(map,key){return hasOwn.call(map,key)?map[key]:void 0}:function(map,key){return map[key]}},functionPrototype=Object.getPrototypeOf(Function),_Map=typeof Map==="function"&&typeof Map.prototype.entries==="function"?Map:CreateMapPolyfill(),_Set=typeof Set==="function"&&typeof Set.prototype.entries==="function"?Set:CreateSetPolyfill(),_WeakMap=typeof WeakMap==="function"?WeakMap:CreateWeakMapPolyfill(),registrySymbol=supportsSymbol?Symbol.for("@reflect-metadata:registry"):void 0,metadataRegistry=GetOrCreateMetadataRegistry(),metadataProvider=CreateMetadataProvider(metadataRegistry);function decorate(decorators,target,propertyKey,attributes){if(!IsUndefined(propertyKey)){if(!IsArray(decorators))throw TypeError();if(!IsObject(target))throw TypeError();if(!IsObject(attributes)&&!IsUndefined(attributes)&&!IsNull(attributes))throw TypeError();if(IsNull(attributes))attributes=void 0;return propertyKey=ToPropertyKey(propertyKey),DecorateProperty(decorators,target,propertyKey,attributes)}else{if(!IsArray(decorators))throw TypeError();if(!IsConstructor(target))throw TypeError();return DecorateConstructor(decorators,target)}}exporter("decorate",decorate);function metadata(metadataKey,metadataValue){function decorator(target,propertyKey){if(!IsObject(target))throw TypeError();if(!IsUndefined(propertyKey)&&!IsPropertyKey(propertyKey))throw TypeError();OrdinaryDefineOwnMetadata(metadataKey,metadataValue,target,propertyKey)}return decorator}exporter("metadata",metadata);function defineMetadata(metadataKey,metadataValue,target,propertyKey){if(!IsObject(target))throw TypeError();if(!IsUndefined(propertyKey))propertyKey=ToPropertyKey(propertyKey);return OrdinaryDefineOwnMetadata(metadataKey,metadataValue,target,propertyKey)}exporter("defineMetadata",defineMetadata);function hasMetadata(metadataKey,target,propertyKey){if(!IsObject(target))throw TypeError();if(!IsUndefined(propertyKey))propertyKey=ToPropertyKey(propertyKey);return OrdinaryHasMetadata(metadataKey,target,propertyKey)}exporter("hasMetadata",hasMetadata);function hasOwnMetadata(metadataKey,target,propertyKey){if(!IsObject(target))throw TypeError();if(!IsUndefined(propertyKey))propertyKey=ToPropertyKey(propertyKey);return OrdinaryHasOwnMetadata(metadataKey,target,propertyKey)}exporter("hasOwnMetadata",hasOwnMetadata);function getMetadata(metadataKey,target,propertyKey){if(!IsObject(target))throw TypeError();if(!IsUndefined(propertyKey))propertyKey=ToPropertyKey(propertyKey);return OrdinaryGetMetadata(metadataKey,target,propertyKey)}exporter("getMetadata",getMetadata);function getOwnMetadata(metadataKey,target,propertyKey){if(!IsObject(target))throw TypeError();if(!IsUndefined(propertyKey))propertyKey=ToPropertyKey(propertyKey);return OrdinaryGetOwnMetadata(metadataKey,target,propertyKey)}exporter("getOwnMetadata",getOwnMetadata);function getMetadataKeys(target,propertyKey){if(!IsObject(target))throw TypeError();if(!IsUndefined(propertyKey))propertyKey=ToPropertyKey(propertyKey);return OrdinaryMetadataKeys(target,propertyKey)}exporter("getMetadataKeys",getMetadataKeys);function getOwnMetadataKeys(target,propertyKey){if(!IsObject(target))throw TypeError();if(!IsUndefined(propertyKey))propertyKey=ToPropertyKey(propertyKey);return OrdinaryOwnMetadataKeys(target,propertyKey)}exporter("getOwnMetadataKeys",getOwnMetadataKeys);function deleteMetadata(metadataKey,target,propertyKey){if(!IsObject(target))throw TypeError();if(!IsUndefined(propertyKey))propertyKey=ToPropertyKey(propertyKey);if(!IsObject(target))throw TypeError();if(!IsUndefined(propertyKey))propertyKey=ToPropertyKey(propertyKey);var provider=GetMetadataProvider(target,propertyKey,!1);if(IsUndefined(provider))return!1;return provider.OrdinaryDeleteMetadata(metadataKey,target,propertyKey)}exporter("deleteMetadata",deleteMetadata);function DecorateConstructor(decorators,target){for(var i=decorators.length-1;i>=0;--i){var decorator=decorators[i],decorated=decorator(target);if(!IsUndefined(decorated)&&!IsNull(decorated)){if(!IsConstructor(decorated))throw TypeError();target=decorated}}return target}function DecorateProperty(decorators,target,propertyKey,descriptor){for(var i=decorators.length-1;i>=0;--i){var decorator=decorators[i],decorated=decorator(target,propertyKey,descriptor);if(!IsUndefined(decorated)&&!IsNull(decorated)){if(!IsObject(decorated))throw TypeError();descriptor=decorated}}return descriptor}function OrdinaryHasMetadata(MetadataKey,O,P){var hasOwn2=OrdinaryHasOwnMetadata(MetadataKey,O,P);if(hasOwn2)return!0;var parent=OrdinaryGetPrototypeOf(O);if(!IsNull(parent))return OrdinaryHasMetadata(MetadataKey,parent,P);return!1}function OrdinaryHasOwnMetadata(MetadataKey,O,P){var provider=GetMetadataProvider(O,P,!1);if(IsUndefined(provider))return!1;return ToBoolean(provider.OrdinaryHasOwnMetadata(MetadataKey,O,P))}function OrdinaryGetMetadata(MetadataKey,O,P){var hasOwn2=OrdinaryHasOwnMetadata(MetadataKey,O,P);if(hasOwn2)return OrdinaryGetOwnMetadata(MetadataKey,O,P);var parent=OrdinaryGetPrototypeOf(O);if(!IsNull(parent))return OrdinaryGetMetadata(MetadataKey,parent,P);return}function OrdinaryGetOwnMetadata(MetadataKey,O,P){var provider=GetMetadataProvider(O,P,!1);if(IsUndefined(provider))return;return provider.OrdinaryGetOwnMetadata(MetadataKey,O,P)}function OrdinaryDefineOwnMetadata(MetadataKey,MetadataValue,O,P){var provider=GetMetadataProvider(O,P,!0);provider.OrdinaryDefineOwnMetadata(MetadataKey,MetadataValue,O,P)}function OrdinaryMetadataKeys(O,P){var ownKeys=OrdinaryOwnMetadataKeys(O,P),parent=OrdinaryGetPrototypeOf(O);if(parent===null)return ownKeys;var parentKeys=OrdinaryMetadataKeys(parent,P);if(parentKeys.length<=0)return ownKeys;if(ownKeys.length<=0)return parentKeys;var set=new _Set,keys=[];for(var _i=0,ownKeys_1=ownKeys;_i<ownKeys_1.length;_i++){var key=ownKeys_1[_i],hasKey=set.has(key);if(!hasKey)set.add(key),keys.push(key)}for(var _a=0,parentKeys_1=parentKeys;_a<parentKeys_1.length;_a++){var key=parentKeys_1[_a],hasKey=set.has(key);if(!hasKey)set.add(key),keys.push(key)}return keys}function OrdinaryOwnMetadataKeys(O,P){var provider=GetMetadataProvider(O,P,!1);if(!provider)return[];return provider.OrdinaryOwnMetadataKeys(O,P)}function Type(x){if(x===null)return 1;switch(typeof x){case"undefined":return 0;case"boolean":return 2;case"string":return 3;case"symbol":return 4;case"number":return 5;case"object":return x===null?1:6;default:return 6}}function IsUndefined(x){return x===void 0}function IsNull(x){return x===null}function IsSymbol(x){return typeof x==="symbol"}function IsObject(x){return typeof x==="object"?x!==null:typeof x==="function"}function ToPrimitive(input,PreferredType){switch(Type(input)){case 0:return input;case 1:return input;case 2:return input;case 3:return input;case 4:return input;case 5:return input}var hint=PreferredType===3?"string":PreferredType===5?"number":"default",exoticToPrim=GetMethod(input,toPrimitiveSymbol);if(exoticToPrim!==void 0){var result=exoticToPrim.call(input,hint);if(IsObject(result))throw TypeError();return result}return OrdinaryToPrimitive(input,hint==="default"?"number":hint)}function OrdinaryToPrimitive(O,hint){if(hint==="string"){var toString_1=O.toString;if(IsCallable(toString_1)){var result=toString_1.call(O);if(!IsObject(result))return result}var valueOf=O.valueOf;if(IsCallable(valueOf)){var result=valueOf.call(O);if(!IsObject(result))return result}}else{var valueOf=O.valueOf;if(IsCallable(valueOf)){var result=valueOf.call(O);if(!IsObject(result))return result}var toString_2=O.toString;if(IsCallable(toString_2)){var result=toString_2.call(O);if(!IsObject(result))return result}}throw TypeError()}function ToBoolean(argument){return!!argument}function ToString(argument){return""+argument}function ToPropertyKey(argument){var key=ToPrimitive(argument,3);if(IsSymbol(key))return key;return ToString(key)}function IsArray(argument){return Array.isArray?Array.isArray(argument):argument instanceof Object?argument instanceof Array:Object.prototype.toString.call(argument)==="[object Array]"}function IsCallable(argument){return typeof argument==="function"}function IsConstructor(argument){return typeof argument==="function"}function IsPropertyKey(argument){switch(Type(argument)){case 3:return!0;case 4:return!0;default:return!1}}function SameValueZero(x,y){return x===y||x!==x&&y!==y}function GetMethod(V,P){var func=V[P];if(func===void 0||func===null)return;if(!IsCallable(func))throw TypeError();return func}function GetIterator(obj){var method=GetMethod(obj,iteratorSymbol);if(!IsCallable(method))throw TypeError();var iterator=method.call(obj);if(!IsObject(iterator))throw TypeError();return iterator}function IteratorValue(iterResult){return iterResult.value}function IteratorStep(iterator){var result=iterator.next();return result.done?!1:result}function IteratorClose(iterator){var f=iterator.return;if(f)f.call(iterator)}function OrdinaryGetPrototypeOf(O){var proto=Object.getPrototypeOf(O);if(typeof O!=="function"||O===functionPrototype)return proto;if(proto!==functionPrototype)return proto;var prototype=O.prototype,prototypeProto=prototype&&Object.getPrototypeOf(prototype);if(prototypeProto==null||prototypeProto===Object.prototype)return proto;var constructor=prototypeProto.constructor;if(typeof constructor!=="function")return proto;if(constructor===O)return proto;return constructor}function CreateMetadataRegistry(){var fallback;if(!IsUndefined(registrySymbol)&&typeof root.Reflect<"u"&&!(registrySymbol in root.Reflect)&&typeof root.Reflect.defineMetadata==="function")fallback=CreateFallbackProvider(root.Reflect);var first,second,rest,targetProviderMap=new _WeakMap,registry={registerProvider,getProvider,setProvider};return registry;function registerProvider(provider){if(!Object.isExtensible(registry))throw Error("Cannot add provider to a frozen registry.");switch(!0){case fallback===provider:break;case IsUndefined(first):first=provider;break;case first===provider:break;case IsUndefined(second):second=provider;break;case second===provider:break;default:if(rest===void 0)rest=new _Set;rest.add(provider);break}}function getProviderNoCache(O,P){if(!IsUndefined(first)){if(first.isProviderFor(O,P))return first;if(!IsUndefined(second)){if(second.isProviderFor(O,P))return first;if(!IsUndefined(rest)){var iterator=GetIterator(rest);while(!0){var next=IteratorStep(iterator);if(!next)return;var provider=IteratorValue(next);if(provider.isProviderFor(O,P))return IteratorClose(iterator),provider}}}}if(!IsUndefined(fallback)&&fallback.isProviderFor(O,P))return fallback;return}function getProvider(O,P){var providerMap=targetProviderMap.get(O),provider;if(!IsUndefined(providerMap))provider=providerMap.get(P);if(!IsUndefined(provider))return provider;if(provider=getProviderNoCache(O,P),!IsUndefined(provider)){if(IsUndefined(providerMap))providerMap=new _Map,targetProviderMap.set(O,providerMap);providerMap.set(P,provider)}return provider}function hasProvider(provider){if(IsUndefined(provider))throw TypeError();return first===provider||second===provider||!IsUndefined(rest)&&rest.has(provider)}function setProvider(O,P,provider){if(!hasProvider(provider))throw Error("Metadata provider not registered.");var existingProvider=getProvider(O,P);if(existingProvider!==provider){if(!IsUndefined(existingProvider))return!1;var providerMap=targetProviderMap.get(O);if(IsUndefined(providerMap))providerMap=new _Map,targetProviderMap.set(O,providerMap);providerMap.set(P,provider)}return!0}}function GetOrCreateMetadataRegistry(){var metadataRegistry2;if(!IsUndefined(registrySymbol)&&IsObject(root.Reflect)&&Object.isExtensible(root.Reflect))metadataRegistry2=root.Reflect[registrySymbol];if(IsUndefined(metadataRegistry2))metadataRegistry2=CreateMetadataRegistry();if(!IsUndefined(registrySymbol)&&IsObject(root.Reflect)&&Object.isExtensible(root.Reflect))Object.defineProperty(root.Reflect,registrySymbol,{enumerable:!1,configurable:!1,writable:!1,value:metadataRegistry2});return metadataRegistry2}function CreateMetadataProvider(registry){var metadata2=new _WeakMap,provider={isProviderFor:function(O,P){var targetMetadata=metadata2.get(O);if(IsUndefined(targetMetadata))return!1;return targetMetadata.has(P)},OrdinaryDefineOwnMetadata:OrdinaryDefineOwnMetadata2,OrdinaryHasOwnMetadata:OrdinaryHasOwnMetadata2,OrdinaryGetOwnMetadata:OrdinaryGetOwnMetadata2,OrdinaryOwnMetadataKeys:OrdinaryOwnMetadataKeys2,OrdinaryDeleteMetadata};return metadataRegistry.registerProvider(provider),provider;function GetOrCreateMetadataMap(O,P,Create){var targetMetadata=metadata2.get(O),createdTargetMetadata=!1;if(IsUndefined(targetMetadata)){if(!Create)return;targetMetadata=new _Map,metadata2.set(O,targetMetadata),createdTargetMetadata=!0}var metadataMap=targetMetadata.get(P);if(IsUndefined(metadataMap)){if(!Create)return;if(metadataMap=new _Map,targetMetadata.set(P,metadataMap),!registry.setProvider(O,P,provider)){if(targetMetadata.delete(P),createdTargetMetadata)metadata2.delete(O);throw Error("Wrong provider for target.")}}return metadataMap}function OrdinaryHasOwnMetadata2(MetadataKey,O,P){var metadataMap=GetOrCreateMetadataMap(O,P,!1);if(IsUndefined(metadataMap))return!1;return ToBoolean(metadataMap.has(MetadataKey))}function OrdinaryGetOwnMetadata2(MetadataKey,O,P){var metadataMap=GetOrCreateMetadataMap(O,P,!1);if(IsUndefined(metadataMap))return;return metadataMap.get(MetadataKey)}function OrdinaryDefineOwnMetadata2(MetadataKey,MetadataValue,O,P){var metadataMap=GetOrCreateMetadataMap(O,P,!0);metadataMap.set(MetadataKey,MetadataValue)}function OrdinaryOwnMetadataKeys2(O,P){var keys=[],metadataMap=GetOrCreateMetadataMap(O,P,!1);if(IsUndefined(metadataMap))return keys;var keysObj=metadataMap.keys(),iterator=GetIterator(keysObj),k=0;while(!0){var next=IteratorStep(iterator);if(!next)return keys.length=k,keys;var nextValue=IteratorValue(next);try{keys[k]=nextValue}catch(e){try{IteratorClose(iterator)}finally{throw e}}k++}}function OrdinaryDeleteMetadata(MetadataKey,O,P){var metadataMap=GetOrCreateMetadataMap(O,P,!1);if(IsUndefined(metadataMap))return!1;if(!metadataMap.delete(MetadataKey))return!1;if(metadataMap.size===0){var targetMetadata=metadata2.get(O);if(!IsUndefined(targetMetadata)){if(targetMetadata.delete(P),targetMetadata.size===0)metadata2.delete(targetMetadata)}}return!0}}function CreateFallbackProvider(reflect){var{defineMetadata:defineMetadata2,hasOwnMetadata:hasOwnMetadata2,getOwnMetadata:getOwnMetadata2,getOwnMetadataKeys:getOwnMetadataKeys2,deleteMetadata:deleteMetadata2}=reflect,metadataOwner=new _WeakMap,provider={isProviderFor:function(O,P){var metadataPropertySet=metadataOwner.get(O);if(!IsUndefined(metadataPropertySet)&&metadataPropertySet.has(P))return!0;if(getOwnMetadataKeys2(O,P).length){if(IsUndefined(metadataPropertySet))metadataPropertySet=new _Set,metadataOwner.set(O,metadataPropertySet);return metadataPropertySet.add(P),!0}return!1},OrdinaryDefineOwnMetadata:defineMetadata2,OrdinaryHasOwnMetadata:hasOwnMetadata2,OrdinaryGetOwnMetadata:getOwnMetadata2,OrdinaryOwnMetadataKeys:getOwnMetadataKeys2,OrdinaryDeleteMetadata:deleteMetadata2};return provider}function GetMetadataProvider(O,P,Create){var registeredProvider=metadataRegistry.getProvider(O,P);if(!IsUndefined(registeredProvider))return registeredProvider;if(Create){if(metadataRegistry.setProvider(O,P,metadataProvider))return metadataProvider;throw Error("Illegal state.")}return}function CreateMapPolyfill(){var cacheSentinel={},arraySentinel=[],MapIterator=function(){function MapIterator2(keys,values,selector){this._index=0,this._keys=keys,this._values=values,this._selector=selector}return MapIterator2.prototype["@@iterator"]=function(){return this},MapIterator2.prototype[iteratorSymbol]=function(){return this},MapIterator2.prototype.next=function(){var index=this._index;if(index>=0&&index<this._keys.length){var result=this._selector(this._keys[index],this._values[index]);if(index+1>=this._keys.length)this._index=-1,this._keys=arraySentinel,this._values=arraySentinel;else this._index++;return{value:result,done:!1}}return{value:void 0,done:!0}},MapIterator2.prototype.throw=function(error){if(this._index>=0)this._index=-1,this._keys=arraySentinel,this._values=arraySentinel;throw error},MapIterator2.prototype.return=function(value){if(this._index>=0)this._index=-1,this._keys=arraySentinel,this._values=arraySentinel;return{value,done:!0}},MapIterator2}(),Map2=function(){function Map3(){this._keys=[],this._values=[],this._cacheKey=cacheSentinel,this._cacheIndex=-2}return Object.defineProperty(Map3.prototype,"size",{get:function(){return this._keys.length},enumerable:!0,configurable:!0}),Map3.prototype.has=function(key){return this._find(key,!1)>=0},Map3.prototype.get=function(key){var index=this._find(key,!1);return index>=0?this._values[index]:void 0},Map3.prototype.set=function(key,value){var index=this._find(key,!0);return this._values[index]=value,this},Map3.prototype.delete=function(key){var index=this._find(key,!1);if(index>=0){var size=this._keys.length;for(var i=index+1;i<size;i++)this._keys[i-1]=this._keys[i],this._values[i-1]=this._values[i];if(this._keys.length--,this._values.length--,SameValueZero(key,this._cacheKey))this._cacheKey=cacheSentinel,this._cacheIndex=-2;return!0}return!1},Map3.prototype.clear=function(){this._keys.length=0,this._values.length=0,this._cacheKey=cacheSentinel,this._cacheIndex=-2},Map3.prototype.keys=function(){return new MapIterator(this._keys,this._values,getKey)},Map3.prototype.values=function(){return new MapIterator(this._keys,this._values,getValue)},Map3.prototype.entries=function(){return new MapIterator(this._keys,this._values,getEntry)},Map3.prototype["@@iterator"]=function(){return this.entries()},Map3.prototype[iteratorSymbol]=function(){return this.entries()},Map3.prototype._find=function(key,insert){if(!SameValueZero(this._cacheKey,key)){this._cacheIndex=-1;for(var i=0;i<this._keys.length;i++)if(SameValueZero(this._keys[i],key)){this._cacheIndex=i;break}}if(this._cacheIndex<0&&insert)this._cacheIndex=this._keys.length,this._keys.push(key),this._values.push(void 0);return this._cacheIndex},Map3}();return Map2;function getKey(key,_){return key}function getValue(_,value){return value}function getEntry(key,value){return[key,value]}}function CreateSetPolyfill(){var Set2=function(){function Set3(){this._map=new _Map}return Object.defineProperty(Set3.prototype,"size",{get:function(){return this._map.size},enumerable:!0,configurable:!0}),Set3.prototype.has=function(value){return this._map.has(value)},Set3.prototype.add=function(value){return this._map.set(value,value),this},Set3.prototype.delete=function(value){return this._map.delete(value)},Set3.prototype.clear=function(){this._map.clear()},Set3.prototype.keys=function(){return this._map.keys()},Set3.prototype.values=function(){return this._map.keys()},Set3.prototype.entries=function(){return this._map.entries()},Set3.prototype["@@iterator"]=function(){return this.keys()},Set3.prototype[iteratorSymbol]=function(){return this.keys()},Set3}();return Set2}function CreateWeakMapPolyfill(){var UUID_SIZE=16,keys=HashMap.create(),rootKey=CreateUniqueKey();return function(){function WeakMap2(){this._key=CreateUniqueKey()}return WeakMap2.prototype.has=function(target){var table=GetOrCreateWeakMapTable(target,!1);return table!==void 0?HashMap.has(table,this._key):!1},WeakMap2.prototype.get=function(target){var table=GetOrCreateWeakMapTable(target,!1);return table!==void 0?HashMap.get(table,this._key):void 0},WeakMap2.prototype.set=function(target,value){var table=GetOrCreateWeakMapTable(target,!0);return table[this._key]=value,this},WeakMap2.prototype.delete=function(target){var table=GetOrCreateWeakMapTable(target,!1);return table!==void 0?delete table[this._key]:!1},WeakMap2.prototype.clear=function(){this._key=CreateUniqueKey()},WeakMap2}();function CreateUniqueKey(){var key;do key="@@WeakMap@@"+CreateUUID();while(HashMap.has(keys,key));return keys[key]=!0,key}function GetOrCreateWeakMapTable(target,create){if(!hasOwn.call(target,rootKey)){if(!create)return;Object.defineProperty(target,rootKey,{value:HashMap.create()})}return target[rootKey]}function FillRandomBytes(buffer,size){for(var i=0;i<size;++i)buffer[i]=Math.random()*255|0;return buffer}function GenRandomBytes(size){if(typeof Uint8Array==="function"){var array=new Uint8Array(size);if(typeof crypto<"u")crypto.getRandomValues(array);else if(typeof msCrypto<"u")msCrypto.getRandomValues(array);else FillRandomBytes(array,size);return array}return FillRandomBytes(Array(size),size)}function CreateUUID(){var data=GenRandomBytes(UUID_SIZE);data[6]=data[6]&79|64,data[8]=data[8]&191|128;var result="";for(var offset=0;offset<UUID_SIZE;++offset){var byte=data[offset];if(offset===4||offset===6||offset===8)result+="-";if(byte<16)result+="0";result+=byte.toString(16).toLowerCase()}return result}}function MakeDictionary(obj){return obj.__=void 0,delete obj.__,obj}})})(Reflect2||(Reflect2={}))});function severityRank(severity){return AUDIT_SEVERITY_RANK[severity??"info"]??0}function classifyAudit(operation,summary){let op=(operation||"").toUpperCase();if(summary?.startsWith("API key rejected"))return{severity:"medium",category:"auth"};if(summary&&AUTH_FAILURE_CLASSIFICATION[summary])return AUTH_FAILURE_CLASSIFICATION[summary];if(op.startsWith("IMPERSONATE")||op==="HARD_DELETE"||op==="CHANGE_USER_ID"||op==="PROVISION"||op==="RESTORE"||op.startsWith("ADMIN_"))return{severity:"high",category:"admin"};if(op.endsWith("_FAILED"))return{severity:"medium",category:"auth"};if(op.startsWith("PASSWORD"))return{severity:"medium",category:"auth"};if(op==="LOGIN"||op==="LOGOUT"||op==="REGISTER"||op==="OAUTH_LOGIN"||op==="MAGIC_LINK"||op==="INVITE")return{severity:"info",category:"auth"};if(op==="CREATE"||op==="UPDATE"||op==="PATCH"||op==="DELETE"||op==="TOGGLE"||op==="VERIFICATION")return{severity:"info",category:"data_change"};if(op==="GET"||op==="POST"||op==="PUT"||op==="PATCH"||op==="HEAD")return{severity:"low",category:"auth"};return{severity:"info",category:"data_change"}}var AUDIT_SEVERITY_RANK,ROUTINE_AUTH_REASONS,DEFAULT_AUDIT_SUPPRESS_REASONS,AUTH_FAILURE_CLASSIFICATION;var init_auditTaxonomy=__esm(()=>{AUDIT_SEVERITY_RANK={info:0,low:1,medium:2,high:3,critical:4};ROUTINE_AUTH_REASONS=["No session token","Invalid session","Session expired","Session inactive timeout","Authentication secrets not defined"],DEFAULT_AUDIT_SUPPRESS_REASONS=[...ROUTINE_AUTH_REASONS],AUTH_FAILURE_CLASSIFICATION={"No session token":{severity:"low",category:"auth"},"Invalid session":{severity:"low",category:"auth"},"Session expired":{severity:"low",category:"auth"},"Session inactive timeout":{severity:"low",category:"auth"},"Authentication secrets not defined":{severity:"critical",category:"config"},"Session revoked":{severity:"high",category:"security_anomaly"},"Invalid or missing access token":{severity:"medium",category:"auth"},"Access token tenant binding failed":{severity:"high",category:"security_anomaly"},"Invalid API key":{severity:"medium",category:"auth"},"Cohort expired":{severity:"medium",category:"authz"}}});var AUTH_LOGIN="authentication.login",AUTH_REGISTER="authentication.register",AUTH_SESSION="authentication.session",AUTH_PASSWORD_CHANGE="authentication.passwordChange",AUTH_PASSWORD_RESET="authentication.passwordReset",AUTH_PASSWORD_SET="authentication.passwordSet",TENANT_PROVISION="tenant.provision",TENANT_SELF_SIGNUP="tenant.selfSignup",TENANT_SUSPEND="tenant.suspend",matchesScope=(scope,enabledScopes)=>{if(enabledScopes.length===0)return!1;if(enabledScopes.includes("*"))return!0;if(enabledScopes.includes(scope))return!0;let category=scope.split(".")[0];if(category&&enabledScopes.includes(`${category}.*`))return!0;return!1};var init_scopes=()=>{};var LOG_LEVEL_PRIORITY,LOG_LEVEL_COLORS,RESET_COLOR="\x1B[0m",DIM_COLOR="\x1B[2m",BOLD_COLOR="\x1B[1m";var init_types=__esm(()=>{LOG_LEVEL_PRIORITY={debug:0,info:1,warn:2,error:3,fatal:4},LOG_LEVEL_COLORS={debug:"\x1B[36m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",fatal:"\x1B[35m"}});function redactSensitiveData(obj,redactKeys=DEFAULT_REDACT_KEYS,seen=new WeakSet){if(obj===null||obj===void 0)return obj;if(obj instanceof Error){let code=obj.code;return redactSensitiveData({name:obj.name,message:obj.message,stack:obj.stack,...code!==void 0?{code}:{}},redactKeys,seen)}if(typeof obj!=="object")return obj;if(seen.has(obj))return"[Circular]";if(seen.add(obj),Array.isArray(obj))return obj.map((item)=>redactSensitiveData(item,redactKeys,seen));let result={};for(let[key,value]of Object.entries(obj))if(redactKeys.some((redactKey)=>key.toLowerCase().includes(redactKey.toLowerCase())))result[key]="[REDACTED]";else if(value instanceof Error||typeof value==="object"&&value!==null)result[key]=redactSensitiveData(value,redactKeys,seen);else result[key]=value;return result}function getCallerInfo(){let stack=Error().stack;if(!stack)return{file:"unknown",line:0,function:"unknown"};let lines=stack.split(`
|
|
16
16
|
`).slice(1);for(let line of lines){let match=line.match(/at\s+(?:(.+?)\s+)?\(?(.+?):(\d+):(\d+)\)?/);if(!match)continue;let[,fnName,filePath,lineNum]=match,fileName=filePath?filePath.split("/").pop()||filePath:"unknown";if(LOGGER_INTERNAL_FILES.includes(fileName))continue;return{file:fileName,line:parseInt(lineNum||"0",10),function:fnName?.replace(/^Object\./,"")||"anonymous"}}return{file:"unknown",line:0,function:"unknown"}}function formatError(error){if(error instanceof Error)return{name:error.name,message:error.message,stack:error.stack,code:error.code};if(typeof error==="string")return{name:"Error",message:error};return{name:"UnknownError",message:String(error)}}function mergeContext(base,additional){if(!base&&!additional)return;if(!base)return additional;if(!additional)return base;return{...base,...additional}}function formatDuration(ms){if(ms<1)return`${(ms*1000).toFixed(2)}\xB5s`;if(ms<1000)return`${ms.toFixed(2)}ms`;return`${(ms/1000).toFixed(2)}s`}function safeStringify(obj,indent){let seen=new WeakSet;return JSON.stringify(obj,(_,value)=>{if(typeof value==="object"&&value!==null){if(seen.has(value))return"[Circular]";seen.add(value)}if(typeof value==="bigint")return value.toString();if(value instanceof Error)return{name:value.name,message:value.message,stack:value.stack};return value},indent)}var DEFAULT_REDACT_KEYS,LOGGER_INTERNAL_FILES;var init_utils=__esm(()=>{DEFAULT_REDACT_KEYS=["password","secret","token","apiKey","api_key","authorization","cookie","credit_card","creditCard","ssn","privateKey","private_key"];LOGGER_INTERNAL_FILES=["Logger.ts","transports.ts","utils.ts"]});class ConsoleTransport{name="console";colorize;prettyPrint;constructor(options={}){this.colorize=options.colorize??!0,this.prettyPrint=options.prettyPrint??!0}log(entry){if(this.prettyPrint)this.logPretty(entry);else this.logJson(entry)}logJson(entry){let output=safeStringify(entry);this.getConsoleMethod(entry.level)(output)}logPretty(entry){let method=this.getConsoleMethod(entry.level),color=this.colorize?LOG_LEVEL_COLORS[entry.level]:"",reset=this.colorize?RESET_COLOR:"",dim=this.colorize?DIM_COLOR:"",bold=this.colorize?BOLD_COLOR:"",time=new Date(entry.timestamp).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"}),levelStr=entry.level.toUpperCase().padEnd(5),serviceStr=entry.service?`[${entry.service}]`:"",correlationStr=entry.correlationId?`${dim}(${entry.correlationId.slice(0,8)})${reset}`:"",durationStr=entry.duration!==void 0?`${dim}${formatDuration(entry.duration)}${reset}`:"",line=`${dim}${time}${reset} ${color}${bold}${levelStr}${reset} ${serviceStr}${correlationStr} ${entry.message} ${durationStr}`;if(method(line.trim()),entry.caller)method(` ${dim}at ${entry.caller.function} (${entry.caller.file}:${entry.caller.line})${reset}`);if(entry.context&&Object.keys(entry.context).length>0)method(` ${dim}context:${reset}`,entry.context);if(entry.error){if(method(` ${color}${entry.error.name}: ${entry.error.message}${reset}`),entry.error.stack){let stackLines=entry.error.stack.split(`
|
|
17
|
-
`).slice(1,4);for(let stackLine of stackLines)method(` ${dim}${stackLine.trim()}${reset}`)}}}getConsoleMethod(level){switch(level){case"debug":return console.debug.bind(console);case"info":return console.info.bind(console);case"warn":return console.warn.bind(console);case"error":case"fatal":return console.error.bind(console);default:return console.log.bind(console)}}}class DatabaseAuditTransport{name="database";db;table;enabled;dedupEnabled;dedupWindowMs;dedupSlots=new Map;lastSweep=0;constructor(options){this.db=options.db,this.table=options.table,this.enabled=options.enabled??!0,this.dedupEnabled=options.dedup?.enabled??!1,this.dedupWindowMs=Math.max(1,options.dedup?.windowSeconds??60)*1000}setDb(db){this.db=db}setTable(table){this.table=table}setEnabled(enabled){this.enabled=enabled}setDedup(dedup){if(this.dedupEnabled=dedup.enabled??this.dedupEnabled,dedup.windowSeconds!=null)this.dedupWindowMs=Math.max(1,dedup.windowSeconds)*1000}isDedupable(entry){return this.dedupEnabled&&(entry.category==="auth"||entry.category==="authz"||entry.category==="security_anomaly")}sweep(now){if(now-this.lastSweep<this.dedupWindowMs)return;this.lastSweep=now;for(let[key,slot]of this.dedupSlots)if(slot.expiresAt<=now)this.dedupSlots.delete(key)}async write(entry){if(!this.enabled||!this.db||!this.table)return;try{let now=Date.now();if(this.isDedupable(entry)){this.sweep(now);let key=`${entry.ipAddress}|${entry.operation}|${entry.summary}|${entry.userId??""}`,slot=this.dedupSlots.get(key);if(slot&&slot.expiresAt>now){slot.count+=1,await this.bumpOccurrence(slot.rowId,slot.count,now);return}this.dedupSlots.set(key,{rowId:entry.id,count:1,expiresAt:now+this.dedupWindowMs})}await this.db.insert(this.table).values({id:entry.id,entityId:entry.entityId,entityName:entry.entityName,operationType:entry.operation,userId:entry.userId,ipAddress:entry.ipAddress,userAgent:entry.userAgent,summary:entry.summary,severity:entry.severity,category:entry.category,occurrenceCount:1,oldValues:entry.oldValues,newValues:entry.newValues,path:entry.path,query:entry.query})}catch(error){console.error("Audit log write failed:",error)}}async bumpOccurrence(rowId,count,nowMs){try{let{eq}=await import("drizzle-orm"),idCol=this.table.id;await this.db.update(this.table).set({occurrenceCount:count,lastOccurrenceAt:new Date(nowMs)}).where(eq(idCol,rowId))}catch(error){console.error("Audit dedup update failed:",error)}}}class ConsoleAuditTransport{name="console-audit";enabled;constructor(options={}){this.enabled=options.enabled??!0}write(entry){if(!this.enabled)return;let reset=RESET_COLOR,dim=DIM_COLOR,color={info:"\x1B[35m",low:"\x1B[90m",medium:"\x1B[33m",high:"\x1B[31m",critical:"\x1B[1m\x1B[31m"}[entry.severity]??"\x1B[35m",sev=entry.severity.toUpperCase(),actor=entry.userId||"anonymous",cat=entry.category;console.log(`${dim}${entry.timestamp}${reset} ${color}AUDIT\xB7${sev}${reset} ${dim}(${cat})${reset} [${entry.operation}] ${entry.entityName}${entry.entityId?`:${entry.entityId}`:""} ${dim}by ${actor}${reset}${entry.summary?` ${dim}\u2014${reset} ${entry.summary}`:""}`)}}var init_transports=__esm(()=>{init_types();init_utils()});import{randomUUID}from"crypto";class Logger{config;transports;auditTransports;context;correlationId;static instance=null;constructor(config={},context={},correlationId){this.config={...DEFAULT_CONFIG,...config},this.config.redactKeys=[...new Set([...DEFAULT_REDACT_KEYS,...config.redactKeys||[]])],this.context=context,this.correlationId=correlationId,this.transports=[new ConsoleTransport({colorize:this.config.colorize,prettyPrint:this.config.prettyPrint})],this.auditTransports=[new ConsoleAuditTransport({enabled:this.config.prettyPrint})]}static getInstance(config){if(!Logger.instance)Logger.instance=new Logger(config);return Logger.instance}static resetInstance(){Logger.instance=null}configure(config){return this.config={...this.config,...config},this.config.redactKeys=[...new Set([...DEFAULT_REDACT_KEYS,...config.redactKeys||this.config.redactKeys||[]])],this.transports=[new ConsoleTransport({colorize:this.config.colorize,prettyPrint:this.config.prettyPrint}),...this.transports.filter((t)=>t.name!=="console")],this}child(context,correlationId){let childLogger=new Logger(this.config,mergeContext(this.context,context)||{},correlationId||this.correlationId);return childLogger.transports=this.transports,childLogger.auditTransports=this.auditTransports,childLogger}withCorrelationId(correlationId){return this.child({},correlationId)}addTransport(transport){this.transports.push(transport)}addAuditTransport(transport){this.auditTransports.push(transport)}setLevel(level){this.config.level=level}setAuditEnabled(enabled){this.config.auditEnabled=enabled}isAuditEnabled(){return this.config.auditEnabled}setAuditSuppressReasons(reasons){this.config.auditSuppressReasons=reasons}setAuditMinSeverity(severity){this.config.auditMinSeverity=severity}shouldLog(level){return LOG_LEVEL_PRIORITY[level]>=LOG_LEVEL_PRIORITY[this.config.level]}shouldLogScope(scope){if(!scope)return!0;return matchesScope(scope,this.config.enabledScopes)}setEnabledScopes(scopes){this.config.enabledScopes=scopes}getEnabledScopes(){return this.config.enabledScopes}scoped(scope){return new ScopedLogger(this,scope)}createEntry(level,message,context,error,startTime,scope){let entry={timestamp:new Date().toISOString(),level,message,scope,service:this.config.service,correlationId:this.correlationId},mergedContext=mergeContext(this.context,context);if(mergedContext&&Object.keys(mergedContext).length>0)entry.context=redactSensitiveData(mergedContext,this.config.redactKeys);if(this.config.includeCallerInfo)entry.caller=getCallerInfo();if(error)entry.error=formatError(error);if(startTime!==void 0)entry.duration=performance.now()-startTime;return entry}log(level,message,context,error,startTime,scope){if(!this.shouldLog(level))return;if(!this.shouldLogScope(scope))return;let entry=this.createEntry(level,message,context,error,startTime,scope);for(let transport of this.transports)try{transport.log(entry)}catch(err){console.error(`Logger transport "${transport.name}" failed:`,err)}}debug(message,context){this.log("debug",message,context)}info(message,context){this.log("info",message,context)}warn(message,context){this.log("warn",message,context)}error(message,error,context){this.log("error",message,context,error)}fatal(message,error,context){this.log("fatal",message,context,error)}time(label){let start=performance.now();return()=>{this.log("debug",`${label} completed`,void 0,void 0,start)}}async timeAsync(label,fn,context){let start=performance.now();try{let result=await fn();return this.log("debug",`${label} completed`,context,void 0,start),result}catch(error){throw this.log("error",`${label} failed`,context,error,start),error}}request(options){let level=options.statusCode>=500?"error":options.statusCode>=400?"warn":"info";this.log(level,`${options.method} ${options.path} ${options.statusCode}`,{method:options.method,path:options.path,statusCode:options.statusCode,durationMs:options.duration,correlationId:options.correlationId,userId:options.userId,ip:options.ip,userAgent:options.userAgent})}db(options){let level=options.error?"error":"debug";this.log(level,`DB ${options.operation} on ${options.table}`,{operation:options.operation,table:options.table,durationMs:options.duration,rowCount:options.rowCount},options.error)}async flush(){for(let transport of this.transports)if(transport.flush)await transport.flush()}async audit(options){let summary=options.summary||`${options.operation} on ${options.entityName}`;if(this.config.auditSuppressReasons?.includes(summary))return;let derived=classifyAudit(options.operation,summary),severity=options.severity??derived.severity,category=options.category??derived.category;if(severityRank(severity)<severityRank(this.config.auditMinSeverity))return;let entry={id:randomUUID(),timestamp:new Date().toISOString(),entityName:options.entityName,entityId:options.entityId??null,operation:options.operation,userId:options.userId??null,summary,severity,category,oldValues:redactSensitiveData(options.oldValues||{}),newValues:redactSensitiveData(options.newValues||{}),ipAddress:options.ipAddress||"unknown",userAgent:options.userAgent||"unknown",path:options.path||"",query:options.query||"",correlationId:this.correlationId};for(let transport of this.auditTransports)try{await transport.write(entry)}catch(err){console.error(`Audit transport "${transport.name}" failed:`,err)}}auditOnly(options){this.audit(options)}async trace(options){let shouldLog=options.log!==!1,shouldAudit=options.writeAudit===!0||options.writeAudit!==!1&&this.config.auditEnabled&&options.audit;if(shouldLog)this.log(options.level||"info",options.message,options.context,options.error);if(shouldAudit&&options.audit)await this.audit(options.audit)}traceSync(options){let shouldLog=options.log!==!1,shouldAudit=options.writeAudit===!0||options.writeAudit!==!1&&this.config.auditEnabled&&options.audit;if(shouldLog)this.log(options.level||"info",options.message,options.context,options.error);if(shouldAudit&&options.audit)this.audit(options.audit)}}class ScopedLogger{parent;scope;constructor(parent,scope){this.parent=parent,this.scope=scope}debug(message,context){this.parent.log("debug",message,context,void 0,void 0,this.scope)}info(message,context){this.parent.log("info",message,context,void 0,void 0,this.scope)}warn(message,context){this.parent.log("warn",message,context,void 0,void 0,this.scope)}error(message,error,context){this.parent.log("error",message,context,error,void 0,this.scope)}}var DEFAULT_CONFIG,logger;var init_Logger=__esm(()=>{init_auditTaxonomy();init_scopes();init_transports();init_types();init_utils();DEFAULT_CONFIG={level:"info",service:"nucleus",environment:"development",redactKeys:[],colorize:!0,prettyPrint:!0,includeCallerInfo:!0,asyncBufferSize:100,flushIntervalMs:1000,auditEnabled:!1,auditSuppressReasons:DEFAULT_AUDIT_SUPPRESS_REASONS,auditMinSeverity:"info",enabledScopes:["*"]};logger=Logger.getInstance()});var require_fast_decode_uri_component=__commonJS((exports,module)=>{var UTF8_ACCEPT=12,UTF8_REJECT=0,UTF8_DATA=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,7,7,7,7,7,7,7,7,7,7,7,7,8,7,7,10,9,9,9,11,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,24,36,48,60,72,84,96,0,12,12,12,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,24,24,24,0,0,0,0,0,0,0,0,0,24,24,0,0,0,0,0,0,0,0,0,0,48,48,48,0,0,0,0,0,0,0,0,0,0,48,48,0,0,0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0,127,63,63,63,0,31,15,15,15,7,7,7];function decodeURIComponent2(uri){var percentPosition=uri.indexOf("%");if(percentPosition===-1)return uri;var length=uri.length,decoded="",last=0,codepoint=0,startOfOctets=percentPosition,state=UTF8_ACCEPT;while(percentPosition>-1&&percentPosition<length){var high=hexCodeToInt(uri[percentPosition+1],4),low=hexCodeToInt(uri[percentPosition+2],0),byte=high|low,type=UTF8_DATA[byte];if(state=UTF8_DATA[256+state+type],codepoint=codepoint<<6|byte&UTF8_DATA[364+type],state===UTF8_ACCEPT)decoded+=uri.slice(last,startOfOctets),decoded+=codepoint<=65535?String.fromCharCode(codepoint):String.fromCharCode(55232+(codepoint>>10),56320+(codepoint&1023)),codepoint=0,last=percentPosition+3,percentPosition=startOfOctets=uri.indexOf("%",last);else if(state===UTF8_REJECT)return null;else{if(percentPosition+=3,percentPosition<length&&uri.charCodeAt(percentPosition)===37)continue;return null}}return decoded+uri.slice(last)}var HEX={"0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};function hexCodeToInt(c,shift){var i=HEX[c];return i===void 0?255:i<<shift}module.exports=decodeURIComponent2});import{createHash,randomBytes}from"crypto";var API_KEY_BYTE_LENGTH=32,HASH_ALGORITHM="sha256",generateApiKey=(prefix="nk_live")=>{let randomPart=randomBytes(API_KEY_BYTE_LENGTH).toString("hex"),rawKey=`${prefix}_${randomPart}`,keyHash=hashApiKey(rawKey),keyPreview=`${prefix}_...${randomPart.slice(-4)}`;return{rawKey,keyHash,keyPreview}},hashApiKey=(rawKey)=>{return createHash(HASH_ALGORITHM).update(rawKey).digest("hex")},validateApiKeyFormat=(rawKey)=>{return/^nk_(live|test)_[a-f0-9]{64}$/.test(rawKey)},extractApiKeyFromHeader=(headers)=>{let apiKeyHeader=headers.get("x-api-key");if(apiKeyHeader&&validateApiKeyFormat(apiKeyHeader))return apiKeyHeader;let authHeader=headers.get("authorization");if(authHeader){let bearerMatch=authHeader.match(/^Bearer\s+(nk_(?:live|test)_[a-f0-9]{64})$/);if(bearerMatch?.[1])return bearerMatch[1]}return null},validateApiKeyRecord=(record)=>{if(!record.isActive)return{valid:!1,reason:"API key is inactive"};if(record.revokedAt)return{valid:!1,reason:"API key has been revoked"};if(record.expiresAt&&new Date(record.expiresAt)<new Date)return{valid:!1,reason:"API key has expired"};return{valid:!0,record}},intersectPermissions=(userPermissions,keyPermissions)=>{let userSet=new Set(userPermissions);return keyPermissions.filter((p)=>userSet.has(p))};var init_ApiKey=()=>{};var normalize=(value)=>{return value?.trim().toLowerCase()||"unknown"},extractHeaderValue=(headers,key)=>{return headers[key.toLowerCase()]??headers[key]};import crypto2 from"crypto";var generateDeviceFingerprint=(input)=>{let payload=JSON.stringify({userAgent:normalize(input.userAgent),extra:input.extra??{}});return{hash:crypto2.createHash("sha256").update(payload).digest("base64url"),components:input}};var init_Generate=()=>{};var validateDeviceFingerprint=({savedFingerprint,requestIp,headers})=>{let userAgent=extractHeaderValue(headers,"user-agent"),forwardedFor=extractHeaderValue(headers,"x-forwarded-for")??requestIp??void 0,currentFingerprint=generateDeviceFingerprint({userAgent,ipAddress:forwardedFor}),componentMismatch=[{field:"userAgent",saved:savedFingerprint.components.userAgent,received:userAgent},{field:"ipAddress",saved:savedFingerprint.components.ipAddress,received:forwardedFor}].find(({saved,received})=>saved??(received??"")!=="");if(componentMismatch)return{isValid:!1,reason:`${componentMismatch.field} mismatch`,currentFingerprint};return{isValid:!0,currentFingerprint}};var init_Validate=__esm(()=>{init_Generate()});var init_Fingerprint=__esm(()=>{init_Generate();init_Validate()});import crypto3 from"crypto";var base64UrlEncode=(data)=>{return(Buffer.isBuffer(data)?data.toString("base64"):Buffer.from(data).toString("base64")).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},base64UrlDecode=(data)=>{let padding="=".repeat((4-data.length%4)%4),base64=data.replace(/-/g,"+").replace(/_/g,"/")+padding;return Buffer.from(base64,"base64").toString("utf-8")},createSignature=(data,secret,algorithm)=>{let hmacAlgorithm=algorithm.replace("HS","sha"),hmac=crypto3.createHmac(hmacAlgorithm,secret);return hmac.update(data),base64UrlEncode(hmac.digest())},verifySignature=(data,signature,secret,algorithm)=>{let expectedSignature=createSignature(data,secret,algorithm),sigBuf=Buffer.from(signature),expBuf=Buffer.from(expectedSignature);if(sigBuf.length!==expBuf.length)return!1;return crypto3.timingSafeEqual(sigBuf,expBuf)},encodeHeader=(header)=>{return base64UrlEncode(JSON.stringify(header))},encodePayload=(payload)=>{return base64UrlEncode(JSON.stringify(payload))},decodeHeader=(encoded)=>{try{return JSON.parse(base64UrlDecode(encoded))}catch{return null}},decodePayload=(encoded)=>{try{return JSON.parse(base64UrlDecode(encoded))}catch{return null}};var init_utils2=()=>{};var decodeJWT=(token)=>{let parts=token.split(".");if(parts.length!==3)return null;let[encodedHeader,encodedPayload,signature]=parts;if(!encodedHeader||!encodedPayload||!signature)return null;let header=decodeHeader(encodedHeader),payload=decodePayload(encodedPayload);if(!header||!payload)return null;return{header,payload,signature}};var init_Decode=__esm(()=>{init_utils2()});var signJWT=(options,secret,algorithm="HS256")=>{let header={alg:algorithm,typ:"JWT"},now=Math.floor(Date.now()/1000),payload={sub:options.subject,iat:now,exp:now+options.expiresInSeconds,iss:options.issuer,aud:options.audience,jti:options.jwtId,sessionId:options.sessionId,...options.customClaims},encodedHeader=encodeHeader(header),encodedPayload=encodePayload(payload),dataToSign=`${encodedHeader}.${encodedPayload}`,signature=createSignature(dataToSign,secret,algorithm);return`${dataToSign}.${signature}`};var init_Sign=__esm(()=>{init_utils2()});var audienceMatches=(aud,expected)=>{if(typeof aud==="string")return aud===expected;if(Array.isArray(aud))return aud.includes(expected);return!1},verifyJWT=(token,secret,expected)=>{let parts=token.split(".");if(parts.length!==3)return{valid:!1,error:"Invalid token format: expected 3 parts"};let[encodedHeader,encodedPayload,signature]=parts;if(!encodedHeader||!encodedPayload||!signature)return{valid:!1,error:"Invalid token format: missing parts"};let header=decodeHeader(encodedHeader);if(!header)return{valid:!1,error:"Invalid header: failed to decode"};if(header.typ!=="JWT")return{valid:!1,error:"Invalid header: typ must be JWT"};if(!["HS256","HS384","HS512"].includes(header.alg))return{valid:!1,error:`Unsupported algorithm: ${header.alg}`};let dataToVerify=`${encodedHeader}.${encodedPayload}`;if(!verifySignature(dataToVerify,signature,secret,header.alg))return{valid:!1,error:"Invalid signature"};let payload=decodePayload(encodedPayload);if(!payload)return{valid:!1,error:"Invalid payload: failed to decode"};let now=Math.floor(Date.now()/1000);if(payload.exp&&payload.exp<now)return{valid:!1,error:"Token expired"};if(payload.iat&&payload.iat>now+60)return{valid:!1,error:"Token issued in the future"};if(expected?.issuer&&payload.iss!==expected.issuer)return{valid:!1,error:"Invalid issuer"};if(expected?.audience&&!audienceMatches(payload.aud,expected.audience))return{valid:!1,error:"Invalid audience"};return{valid:!0,payload}};var init_Verify=__esm(()=>{init_utils2()});var exports_JWT={};__export(exports_JWT,{verifyJWT:()=>verifyJWT,signJWT:()=>signJWT,decodeJWT:()=>decodeJWT});var init_JWT=__esm(()=>{init_Decode();init_Sign();init_Verify()});var init_Generate2=()=>{};var init_Password=__esm(()=>{init_Generate2()});var init_Logger2=__esm(()=>{init_auditTaxonomy();init_Logger();init_transports();init_utils();init_scopes()});var DEFAULT_DAPR_HOST="127.0.0.1",DEFAULT_DAPR_PORT="3500",DEFAULT_MAX_BODY_SIZE_MB=4,DEFAULT_STATE_STORE="statestore-redis",DEFAULT_PUBSUB_NAME="pubsub-rabbitmq",DEFAULT_SECRET_STORE="secretstore",DEFAULT_CONFIG_STORE="configstore-redis",ENV_DAPR_HOST="DAPR_HOST",ENV_DAPR_HTTP_PORT="DAPR_HTTP_PORT",ENV_DAPR_HTTP_ENDPOINT="DAPR_HTTP_ENDPOINT",ENV_DAPR_GRPC_ENDPOINT="DAPR_GRPC_ENDPOINT",ENV_DAPR_API_TOKEN="DAPR_API_TOKEN",DEFAULT_OPERATION_TIMEOUT_MS=30000,DEFAULT_CONNECTION_TIMEOUT_MS=1e4,DEFAULT_HEALTH_CHECK_TIMEOUT_MS=5000,CONNECTION_STATUS,HEALTH_STATUS,ERROR_CODES;var init_constants=__esm(()=>{CONNECTION_STATUS={CONNECTED:"connected",DISCONNECTED:"disconnected",CONNECTING:"connecting",ERROR:"error"},HEALTH_STATUS={HEALTHY:"healthy",UNHEALTHY:"unhealthy"},ERROR_CODES={CONNECTION_ERROR:"DAPR_CONNECTION_ERROR",TIMEOUT_ERROR:"DAPR_TIMEOUT_ERROR",STATE_ERROR:"DAPR_STATE_ERROR",PUBSUB_ERROR:"DAPR_PUBSUB_ERROR",BINDING_ERROR:"DAPR_BINDING_ERROR",SECRET_ERROR:"DAPR_SECRET_ERROR",CONFIG_ERROR:"DAPR_CONFIG_ERROR",INVOKE_ERROR:"DAPR_INVOKE_ERROR",CRYPTO_ERROR:"DAPR_CRYPTO_ERROR",LOCK_ERROR:"DAPR_LOCK_ERROR",WORKFLOW_ERROR:"DAPR_WORKFLOW_ERROR",VALIDATION_ERROR:"DAPR_VALIDATION_ERROR"}});var DaprManagerError,createConnectionError=(message,details)=>new DaprManagerError(ERROR_CODES.CONNECTION_ERROR,message,details),createTimeoutError=(message,details)=>new DaprManagerError(ERROR_CODES.TIMEOUT_ERROR,message,details),createStateError=(message,details)=>new DaprManagerError(ERROR_CODES.STATE_ERROR,message,details),createPubSubError=(message,details)=>new DaprManagerError(ERROR_CODES.PUBSUB_ERROR,message,details),createBindingError=(message,details)=>new DaprManagerError(ERROR_CODES.BINDING_ERROR,message,details),createSecretError=(message,details)=>new DaprManagerError(ERROR_CODES.SECRET_ERROR,message,details),createConfigError=(message,details)=>new DaprManagerError(ERROR_CODES.CONFIG_ERROR,message,details),createInvokeError=(message,details)=>new DaprManagerError(ERROR_CODES.INVOKE_ERROR,message,details),createCryptoError=(message,details)=>new DaprManagerError(ERROR_CODES.CRYPTO_ERROR,message,details),createLockError=(message,details)=>new DaprManagerError(ERROR_CODES.LOCK_ERROR,message,details),createWorkflowError=(message,details)=>new DaprManagerError(ERROR_CODES.WORKFLOW_ERROR,message,details),safeExecute=async(operation,errorCreator)=>{try{return await operation()}catch(error){let errorMessage=error instanceof Error?error.message:String(error);throw errorCreator(errorMessage,error)}};var init_error_handling=__esm(()=>{init_constants();DaprManagerError=class DaprManagerError extends Error{code;details;constructor(code,message,details){super(message);this.name="DaprManagerError",this.code=code,this.details=details}toJSON(){return{code:this.code,message:this.message,details:this.details}}}});var LOG_LEVEL_PRIORITY2,createDefaultLogger=(minLevel="info")=>{let minPriority=LOG_LEVEL_PRIORITY2[minLevel],scoped=logger.scoped("dapr.client"),logWithLevel=(level)=>(message,...meta)=>{if(LOG_LEVEL_PRIORITY2[level]<minPriority)return;let context=meta.length>0?{meta}:void 0;if(level==="error")scoped.error(message,void 0,context);else scoped[level](message,context)};return{debug:logWithLevel("debug"),info:logWithLevel("info"),warn:logWithLevel("warn"),error:logWithLevel("error")}},withTimeout=async(fn,timeoutMs,errorMessage="Operation timed out")=>{return Promise.race([fn(),new Promise((_,reject)=>{setTimeout(()=>{reject(createTimeoutError(errorMessage))},timeoutMs)})])},validateRequired=(params,requiredKeys,entityName)=>{let missingKeys=requiredKeys.filter((key)=>params[key]===void 0);if(missingKeys.length>0)throw Error(`Missing required ${entityName} parameters: ${missingKeys.join(", ")}`)};var init_utils3=__esm(()=>{init_Logger2();init_constants();init_error_handling();LOG_LEVEL_PRIORITY2={debug:0,info:1,warn:2,error:3}});class DaprBindingClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async invoke(name,operation,data,options={}){return validateRequired({name,operation},["name","operation"],"binding invoke"),safeExecute(async()=>{this.logger.debug("Invoking binding",{name,operation});let response=await(await this.client()).binding.send(name,operation,data,options.metadata);return this.logger.debug("Binding invoked successfully",{name,operation}),response},(message,details)=>createBindingError(`Failed to invoke binding ${name}: ${message}`,details))}}var init_binding_client=__esm(()=>{init_error_handling();init_utils3()});class DaprConfigClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async get(keys,storeName=DEFAULT_CONFIG_STORE){if(validateRequired({keys,storeName},["keys","storeName"],"config get"),keys.length===0)return{};return safeExecute(async()=>{this.logger.debug("Getting configuration",{keys,storeName});let response=await(await this.client()).configuration.get(storeName,keys);return this.logger.debug("Configuration retrieved",{keys,storeName,itemCount:Object.keys(response.items||{}).length}),response.items||{}},(message,details)=>createConfigError(`Failed to get configuration: ${message}`,details))}async subscribeWithKeys(keys,callback,storeName=DEFAULT_CONFIG_STORE){if(validateRequired({keys,callback,storeName},["keys","callback","storeName"],"config subscribeWithKeys"),keys.length===0)throw createConfigError("At least one key must be provided for subscription");return safeExecute(async()=>{this.logger.debug("Subscribing to configuration updates",{keys,storeName});let stream=await(await this.client()).configuration.subscribeWithKeys(storeName,keys,async(data)=>{try{this.logger.debug("Received configuration update",{storeName,updatedKeys:Object.keys(data.items||{})}),await callback(data)}catch(error){this.logger.error("Error in configuration subscription callback",error)}});return this.logger.debug("Configuration subscription established",{keys,storeName}),{stop:()=>{this.logger.debug("Stopping configuration subscription",{keys,storeName}),stream.stop()}}},(message,details)=>createConfigError(`Failed to subscribe to configuration updates: ${message}`,details))}async getValue(key,storeName=DEFAULT_CONFIG_STORE){return(await this.get([key],storeName))[key]?.value}async getValues(keys,storeName=DEFAULT_CONFIG_STORE){let items=await this.get(keys,storeName),values={};for(let key in items)if(items[key]?.value!==void 0)values[key]=items[key].value;return values}}var init_config_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprCryptoClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async encrypt(data,options){return validateRequired({data,componentName:options.componentName},["data","componentName"],"crypto encrypt"),safeExecute(async()=>{this.logger.debug("Encrypting data",{componentName:options.componentName,keyName:options.keyName,keyWrapAlgorithm:options.keyWrapAlgorithm});let client=await this.client(),inputData=typeof data==="string"?Buffer.from(data):data,cryptoOptions={componentName:options.componentName};if(options.keyName)cryptoOptions.keyName=options.keyName;if(options.keyWrapAlgorithm)cryptoOptions.keyWrapAlgorithm=options.keyWrapAlgorithm;let encryptedData=await client.crypto.encrypt(inputData,cryptoOptions);return this.logger.debug("Data encrypted successfully",{componentName:options.componentName,inputSize:inputData.length,outputSize:encryptedData.length}),encryptedData},(message,details)=>createCryptoError(`Failed to encrypt data: ${message}`,details))}async decrypt(data,options){return validateRequired({data,componentName:options.componentName},["data","componentName"],"crypto decrypt"),safeExecute(async()=>{this.logger.debug("Decrypting data",{componentName:options.componentName});let client=await this.client(),inputData=typeof data==="string"?Buffer.from(data):data,cryptoOptions={componentName:options.componentName};if(options.keyName)cryptoOptions.keyName=options.keyName;if(options.keyWrapAlgorithm)cryptoOptions.keyWrapAlgorithm=options.keyWrapAlgorithm;let decryptedData=await client.crypto.decrypt(inputData,cryptoOptions);return this.logger.debug("Data decrypted successfully",{componentName:options.componentName,inputSize:inputData.length,outputSize:decryptedData.length}),decryptedData},(message,details)=>createCryptoError(`Failed to decrypt data: ${message}`,details))}async encryptString(plaintext,options){return(await this.encrypt(plaintext,options)).toString("base64")}async decryptString(ciphertext,options){let encryptedBuffer=Buffer.from(ciphertext,"base64");return(await this.decrypt(encryptedBuffer,options)).toString("utf-8")}}var init_crypto_client=__esm(()=>{init_error_handling();init_utils3()});import{HttpMethod}from"@dapr/dapr";class DaprInvokeClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async invoke(appId,methodName,httpMethod=HttpMethod.POST,data,options={}){validateRequired({appId,methodName,httpMethod},["appId","methodName","httpMethod"],"invoke service");let timeoutMs=options.timeout||DEFAULT_OPERATION_TIMEOUT_MS;return safeExecute(async()=>{this.logger.debug("Invoking service",{appId,methodName,httpMethod,hasData:data!==void 0});let fullMethodName=methodName;if(options.queryParams&&Object.keys(options.queryParams).length>0){let queryString=Object.entries(options.queryParams).map(([key,value])=>`${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");fullMethodName=`${methodName}?${queryString}`}let client=await this.client(),response=await withTimeout(()=>client.invoker.invoke(appId,fullMethodName,httpMethod,data,options.headers),timeoutMs,`Service invocation timed out after ${timeoutMs}ms`);if(this.logger.debug("Service invoked successfully",{appId,methodName,httpMethod,status:response?.status}),!response)return;if("data"in response)return response.data;return response},(message,details)=>createInvokeError(`Failed to invoke service ${appId}.${methodName}: ${message}`,details))}async get(appId,methodName,options={}){return this.invoke(appId,methodName,HttpMethod.GET,void 0,options)}async post(appId,methodName,data,options={}){return this.invoke(appId,methodName,HttpMethod.POST,data,options)}async put(appId,methodName,data,options={}){return this.invoke(appId,methodName,HttpMethod.PUT,data,options)}async delete(appId,methodName,options={}){return this.invoke(appId,methodName,HttpMethod.DELETE,void 0,options)}}var init_invoke_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprLockClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async lock(storeName,resourceId,lockOwner,options){return validateRequired({storeName,resourceId,lockOwner,expiryInSeconds:options.expiryInSeconds},["storeName","resourceId","lockOwner","expiryInSeconds"],"lock"),safeExecute(async()=>{this.logger.debug("Acquiring lock",{storeName,resourceId,lockOwner});let response=await(await this.client()).lock.lock(storeName,resourceId,lockOwner,options.expiryInSeconds);return this.logger.debug("Lock acquisition result",{storeName,resourceId,lockOwner,success:response.success}),{success:response.success}},(message,details)=>createLockError(`Failed to acquire lock for resource ${resourceId}: ${message}`,details))}async unlock(storeName,resourceId,lockOwner){return validateRequired({storeName,resourceId,lockOwner},["storeName","resourceId","lockOwner"],"unlock"),safeExecute(async()=>{this.logger.debug("Releasing lock",{storeName,resourceId,lockOwner});let response=await(await this.client()).lock.unlock(storeName,resourceId,lockOwner);return this.logger.debug("Lock release result",{storeName,resourceId,lockOwner,status:this.getLockStatusName(response.status)}),{status:response.status}},(message,details)=>createLockError(`Failed to release lock for resource ${resourceId}: ${message}`,details))}getLockStatusName(status){switch(status){case 0:return"Success";case 1:return"LockDoesNotExist";case 2:return"LockBelongsToOthers";default:return"InternalError"}}}var init_lock_client=__esm(()=>{init_error_handling();init_utils3()});class DaprPubSubClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async publish(topic,data,options={},pubsubName=DEFAULT_PUBSUB_NAME){return validateRequired({topic,data,pubsubName},["topic","data","pubsubName"],"pubsub publish"),safeExecute(async()=>{this.logger.debug("Publishing message to topic",{topic,pubsubName}),await(await this.client()).pubsub.publish(pubsubName,topic,data,{metadata:options.metadata,contentType:options.contentType}),this.logger.debug("Message published successfully",{topic,pubsubName})},(message,details)=>createPubSubError(`Failed to publish message to topic ${topic}: ${message}`,details))}async publishBulk(topic,messages,pubsubName=DEFAULT_PUBSUB_NAME){if(validateRequired({topic,messages,pubsubName},["topic","messages","pubsubName"],"pubsub publishBulk"),messages.length===0)return{failedEntries:[]};return safeExecute(async()=>{this.logger.debug("Publishing bulk messages to topic",{topic,pubsubName,messageCount:messages.length});let client=await this.client(),daprMessages=messages.map((msg)=>{if(typeof msg==="object"&&"event"in msg)return{entryID:msg.entryId,event:msg.event,contentType:msg.contentType,metadata:msg.metadata};return{event:msg}}),response=await client.pubsub.publishBulk(pubsubName,topic,daprMessages),failedCount=response.failedMessages?.length||0;if(failedCount>0)this.logger.warn("Some messages failed to publish",{topic,pubsubName,failedCount,totalCount:messages.length});else this.logger.debug("All bulk messages published successfully",{topic,pubsubName,messageCount:messages.length});return{failedEntries:(response.failedMessages||[]).map((failed)=>({entryId:failed.message.entryID||"",error:failed.error?.message||"Unknown error"}))}},(message,details)=>createPubSubError(`Failed to publish bulk messages to topic ${topic}: ${message}`,details))}createBulkPublishMessage(event,entryId,contentType,metadata){return{entryId,event,contentType,metadata}}}var init_pubsub_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprSecretClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async get(key,options={},storeName=DEFAULT_SECRET_STORE){return validateRequired({key,storeName},["key","storeName"],"secret get"),safeExecute(async()=>{this.logger.debug("Getting secret",{key,storeName});let client=await this.client(),metadataStr=options.metadata?JSON.stringify(options.metadata):void 0,result=await client.secret.get(storeName,key,metadataStr);return this.logger.debug("Secret retrieved",{key,storeName}),result},(message,details)=>createSecretError(`Failed to get secret ${key}: ${message}`,details))}async getBulk(_options={},storeName=DEFAULT_SECRET_STORE){return validateRequired({storeName},["storeName"],"secret getBulk"),safeExecute(async()=>{this.logger.debug("Getting all secrets",{storeName});let result=await(await this.client()).secret.getBulk(storeName);return this.logger.debug("All secrets retrieved",{storeName,secretCount:Object.keys(result).length}),result},(message,details)=>createSecretError(`Failed to get all secrets: ${message}`,details))}}var init_secret_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprStateClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async save(stateItems,options={},storeName=DEFAULT_STATE_STORE){if(validateRequired({stateItems,storeName},["stateItems","storeName"],"state save"),stateItems.length===0)return;return safeExecute(async()=>{this.logger.debug("Saving state items",{count:stateItems.length,storeName}),await(await this.client()).state.save(storeName,stateItems,options),this.logger.debug("State items saved successfully",{count:stateItems.length,storeName})},(message,details)=>createStateError(`Failed to save state items: ${message}`,details))}async get(key,storeName=DEFAULT_STATE_STORE){return validateRequired({key,storeName},["key","storeName"],"state get"),safeExecute(async()=>{this.logger.debug("Getting state item",{key,storeName});let result=await(await this.client()).state.get(storeName,key);if(this.logger.debug("State item retrieved",{key,storeName,found:result!==void 0}),result===void 0||result===null)return;if(typeof result==="string")try{return JSON.parse(result)}catch{return result}if(typeof result==="object")return result;return result},(message,details)=>createStateError(`Failed to get state item ${key}: ${message}`,details))}async getBulk(keys,storeName=DEFAULT_STATE_STORE){if(validateRequired({keys,storeName},["keys","storeName"],"state getBulk"),keys.length===0)return{};return safeExecute(async()=>{this.logger.debug("Getting bulk state items",{count:keys.length,storeName});let results=await(await this.client()).state.getBulk(storeName,keys),resultMap={};return results.forEach((item)=>{if(item.data!==void 0)resultMap[item.key]=item.data}),this.logger.debug("Bulk state items retrieved",{count:keys.length,found:Object.keys(resultMap).length,storeName}),resultMap},(message,details)=>createStateError(`Failed to get bulk state items: ${message}`,details))}async delete(key,etag,metadata,storeName=DEFAULT_STATE_STORE){return validateRequired({key,storeName},["key","storeName"],"state delete"),safeExecute(async()=>{this.logger.debug("Deleting state item",{key,storeName});let client=await this.client(),options={};if(etag)options.etag=etag;if(metadata)options.metadata=metadata;await client.state.delete(storeName,key,options),this.logger.debug("State item deleted",{key,storeName})},(message,details)=>createStateError(`Failed to delete state item ${key}: ${message}`,details))}async transaction(operations,storeName=DEFAULT_STATE_STORE){if(validateRequired({operations,storeName},["operations","storeName"],"state transaction"),operations.length===0)return;return safeExecute(async()=>{this.logger.debug("Executing state transaction",{operationCount:operations.length,storeName});let client=await this.client(),daprOperations=operations.map((op)=>({operation:op.operation,request:{key:op.request.key,value:op.request.value,etag:op.request.etag?{value:op.request.etag}:void 0,metadata:op.request.metadata}}));await client.state.transaction(storeName,daprOperations),this.logger.debug("State transaction executed successfully",{operationCount:operations.length,storeName})},(message,details)=>createStateError(`Failed to execute state transaction: ${message}`,details))}async query(query,storeName=DEFAULT_STATE_STORE){return validateRequired({query,storeName},["query","storeName"],"state query"),safeExecute(async()=>{this.logger.debug("Querying state store",{storeName});let result=await(await this.client()).state.query(storeName,query);return this.logger.debug("State query executed",{storeName,resultCount:result.results?.length||0}),(result.results||[]).map((item)=>item.data)},(message,details)=>createStateError(`Failed to query state store: ${message}`,details))}async saveItem(key,value,options={},storeName=DEFAULT_STATE_STORE){let stateItem={key,value};return this.save([stateItem],options,storeName)}async upsert(key,value,options={},storeName=DEFAULT_STATE_STORE){return this.saveItem(key,value,options,storeName)}}var init_state_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprWorkflowClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async start(workflowName,input,options={}){return validateRequired({workflowName},["workflowName"],"workflow start"),safeExecute(async()=>{this.logger.debug("Starting workflow",{workflowName,instanceId:options.instanceId||"auto-generated",workflowComponent:options.workflowComponent});let instanceId=await(await this.client()).workflow.start(workflowName,input,options.instanceId);return this.logger.debug("Workflow started",{workflowName,instanceId}),instanceId},(message,details)=>createWorkflowError(`Failed to start workflow ${workflowName}: ${message}`,details))}async get(instanceId){return validateRequired({instanceId},["instanceId"],"workflow get"),safeExecute(async()=>{this.logger.debug("Getting workflow instance",{instanceId});let instance=await(await this.client()).workflow.get(instanceId);return this.logger.debug("Workflow instance retrieved",{instanceId,workflowName:instance.workflowName,runtimeStatus:instance.runtimeStatus}),{instanceId:instance.instanceID,workflowName:instance.workflowName,createdAt:new Date(instance.createdAt),lastUpdatedAt:new Date(instance.lastUpdatedAt),runtimeStatus:instance.runtimeStatus,properties:instance.properties||{}}},(message,details)=>createWorkflowError(`Failed to get workflow instance ${instanceId}: ${message}`,details))}async terminate(instanceId){return validateRequired({instanceId},["instanceId"],"workflow terminate"),safeExecute(async()=>{this.logger.debug("Terminating workflow instance",{instanceId}),await(await this.client()).workflow.terminate(instanceId),this.logger.debug("Workflow instance terminated",{instanceId})},(message,details)=>createWorkflowError(`Failed to terminate workflow instance ${instanceId}: ${message}`,details))}async pause(instanceId){return validateRequired({instanceId},["instanceId"],"workflow pause"),safeExecute(async()=>{this.logger.debug("Pausing workflow instance",{instanceId}),await(await this.client()).workflow.pause(instanceId),this.logger.debug("Workflow instance paused",{instanceId})},(message,details)=>createWorkflowError(`Failed to pause workflow instance ${instanceId}: ${message}`,details))}async resume(instanceId){return validateRequired({instanceId},["instanceId"],"workflow resume"),safeExecute(async()=>{this.logger.debug("Resuming workflow instance",{instanceId}),await(await this.client()).workflow.resume(instanceId),this.logger.debug("Workflow instance resumed",{instanceId})},(message,details)=>createWorkflowError(`Failed to resume workflow instance ${instanceId}: ${message}`,details))}async purge(instanceId){return validateRequired({instanceId},["instanceId"],"workflow purge"),safeExecute(async()=>{this.logger.debug("Purging workflow instance",{instanceId}),await(await this.client()).workflow.purge(instanceId),this.logger.debug("Workflow instance purged",{instanceId})},(message,details)=>createWorkflowError(`Failed to purge workflow instance ${instanceId}: ${message}`,details))}async raiseEvent(instanceId,eventName,eventData){return validateRequired({instanceId,eventName},["instanceId","eventName"],"workflow raiseEvent"),safeExecute(async()=>{this.logger.debug("Raising event for workflow instance",{instanceId,eventName}),await(await this.client()).workflow.raise(instanceId,eventName,eventData),this.logger.debug("Event raised for workflow instance",{instanceId,eventName})},(message,details)=>createWorkflowError(`Failed to raise event ${eventName} for workflow instance ${instanceId}: ${message}`,details))}}var init_workflow_client=__esm(()=>{init_error_handling();init_utils3()});import{CommunicationProtocolEnum,DaprClient,HttpMethod as HttpMethod2,LogLevel}from"@dapr/dapr";class DaprConnectionManager{client=null;daprHost;daprPort;communicationProtocol;maxBodySizeMb;daprApiToken;logger;connectionStatus=CONNECTION_STATUS.DISCONNECTED;connectionPromise=null;constructor(options={}){this.daprHost=options.daprHost||process.env[ENV_DAPR_HOST]||DEFAULT_DAPR_HOST,this.daprPort=options.daprPort||process.env[ENV_DAPR_HTTP_PORT]||DEFAULT_DAPR_PORT,this.communicationProtocol=options.communicationProtocol||CommunicationProtocolEnum.HTTP,this.maxBodySizeMb=options.maxBodySizeMb||DEFAULT_MAX_BODY_SIZE_MB,this.daprApiToken=options.daprApiToken||process.env[ENV_DAPR_API_TOKEN],this.logger=options.logger||createDefaultLogger(),this.logger.info("DaprConnectionManager initialized",{daprHost:this.daprHost,daprPort:this.daprPort,communicationProtocol:this.communicationProtocol})}async getClient(){if(!this.client||this.connectionStatus!==CONNECTION_STATUS.CONNECTED)await this.connect();if(!this.client)throw createConnectionError("Not connected to Dapr sidecar");return this.client}async connect(){if(this.connectionPromise)return this.connectionPromise;if(this.client&&this.connectionStatus===CONNECTION_STATUS.CONNECTED)return Promise.resolve();this.connectionStatus=CONNECTION_STATUS.CONNECTING,this.connectionPromise=this.establishConnection();try{await this.connectionPromise,this.connectionStatus=CONNECTION_STATUS.CONNECTED}catch(error){throw this.connectionStatus=CONNECTION_STATUS.ERROR,error}finally{this.connectionPromise=null}}async establishConnection(){try{this.logger.info("Connecting to Dapr sidecar",{daprHost:this.daprHost,daprPort:this.daprPort,protocol:this.communicationProtocol});let useEndpointFromEnv=process.env[ENV_DAPR_HTTP_ENDPOINT]&&this.communicationProtocol===CommunicationProtocolEnum.HTTP||process.env[ENV_DAPR_GRPC_ENDPOINT]&&this.communicationProtocol===CommunicationProtocolEnum.GRPC,clientOptions={communicationProtocol:this.communicationProtocol,maxBodySizeMb:this.maxBodySizeMb,logger:{level:LogLevel.Warn}};if(!useEndpointFromEnv)clientOptions.daprHost=this.daprHost,clientOptions.daprPort=this.daprPort;if(this.daprApiToken)clientOptions.daprApiToken=this.daprApiToken;await withTimeout(async()=>{this.client=new DaprClient(clientOptions)},DEFAULT_CONNECTION_TIMEOUT_MS,"Connection to Dapr sidecar timed out"),await this.healthCheck(),this.logger.info("Successfully connected to Dapr sidecar")}catch(error){throw this.logger.error("Failed to connect to Dapr sidecar",error),this.client=null,createConnectionError(`Failed to connect to Dapr sidecar at ${this.daprHost}:${this.daprPort}`,error)}}async disconnect(){if(!this.client)return;try{this.logger.info("Disconnecting from Dapr sidecar"),this.client=null,this.connectionStatus=CONNECTION_STATUS.DISCONNECTED,this.logger.info("Disconnected from Dapr sidecar")}catch(error){throw this.logger.error("Error during disconnect",error),createConnectionError("Failed to disconnect from Dapr sidecar",error)}}isConnected(){return this.client!==null&&this.connectionStatus===CONNECTION_STATUS.CONNECTED}getConnectionStatus(){return this.connectionStatus}async healthCheck(){if(!this.client)throw createConnectionError("Not connected to Dapr sidecar");try{return await withTimeout(async()=>{if(!this.client)throw createConnectionError("Not connected to Dapr sidecar");let response=await this.client.invoker.invoke("healthz","healthz",HttpMethod2.GET);return{status:response.status===204?HEALTH_STATUS.HEALTHY:HEALTH_STATUS.UNHEALTHY,version:response.headers?.["dapr-version"]||"unknown"}},DEFAULT_HEALTH_CHECK_TIMEOUT_MS,"Health check timed out")}catch(error){return this.logger.error("Health check failed",error),{status:HEALTH_STATUS.UNHEALTHY,version:"unknown"}}}getClientConfig(){return{daprHost:this.daprHost,daprPort:this.daprPort,communicationProtocol:this.communicationProtocol,maxBodySizeMb:this.maxBodySizeMb,hasApiToken:!!this.daprApiToken,connectionStatus:this.connectionStatus}}}var init_connection_manager=__esm(()=>{init_constants();init_error_handling();init_utils3()});var init_types2=()=>{};class DaprManager{connectionManager;logger;_state;_pubsub;_binding;_secret;_config;_invoke;_lock;_crypto;_workflow;constructor(options={}){this.logger=options.logger||createDefaultLogger(),this.connectionManager=new DaprConnectionManager(options);let clientProvider=async()=>{return this.connectionManager.getClient()};this._state=new DaprStateClient(clientProvider,this.logger),this._pubsub=new DaprPubSubClient(clientProvider,this.logger),this._binding=new DaprBindingClient(clientProvider,this.logger),this._secret=new DaprSecretClient(clientProvider,this.logger),this._config=new DaprConfigClient(clientProvider,this.logger),this._invoke=new DaprInvokeClient(clientProvider,this.logger),this._lock=new DaprLockClient(clientProvider,this.logger),this._crypto=new DaprCryptoClient(clientProvider,this.logger),this._workflow=new DaprWorkflowClient(clientProvider,this.logger)}async connect(){await this.connectionManager.connect()}async disconnect(){await this.connectionManager.disconnect()}isConnected(){return this.connectionManager.isConnected()}getConnectionStatus(){return this.connectionManager.getConnectionStatus()}async healthCheck(){return this.connectionManager.healthCheck()}getClientConfig(){return this.connectionManager.getClientConfig()}get state(){return this._state}get pubsub(){return this._pubsub}get binding(){return this._binding}get secret(){return this._secret}get config(){return this._config}get invoke(){return this._invoke}get lock(){return this._lock}get crypto(){return this._crypto}get workflow(){return this._workflow}}var daprManager;var init_Dapr=__esm(()=>{init_binding_client();init_config_client();init_crypto_client();init_invoke_client();init_lock_client();init_pubsub_client();init_secret_client();init_state_client();init_workflow_client();init_connection_manager();init_utils3();init_binding_client();init_config_client();init_crypto_client();init_invoke_client();init_lock_client();init_pubsub_client();init_secret_client();init_state_client();init_workflow_client();init_constants();init_error_handling();init_types2();daprManager=new DaprManager});import Redis from"ioredis";class DirectRedisStore{client;constructor(client){this.client=client}async create(key,value,ttlSeconds){try{return{success:!0,data:ttlSeconds?await this.client.set(key,JSON.stringify(value),"EX",ttlSeconds):await this.client.set(key,JSON.stringify(value))}}catch(error){return{success:!1,error:error.message}}}async read(key){try{let raw=await this.client.get(key);return{success:!0,data:raw?JSON.parse(raw):null}}catch(error){return{success:!1,error:error.message}}}async update(key,value,preserveTtl=!0){try{return{success:!0,data:preserveTtl?await this.client.set(key,JSON.stringify(value),"KEEPTTL"):await this.client.set(key,JSON.stringify(value))}}catch(error){return{success:!1,error:error.message}}}async remove(key){try{return{success:!0,data:await this.client.del(key)}}catch(error){return{success:!1,error:error.message}}}async exists(key){try{return{success:!0,data:await this.client.exists(key)===1}}catch(error){return{success:!1,error:error.message}}}getClient(){return this.client}}class DaprRedisStore{storeName;dapr;constructor(storeName){this.storeName=storeName;this.dapr=new DaprManager}async create(key,value,ttlSeconds){try{let metadata=ttlSeconds?{ttlInSeconds:String(ttlSeconds)}:void 0;return await this.dapr.state.save([{key,value,metadata}],void 0,this.storeName),{success:!0,data:"OK"}}catch(error){return{success:!1,error:error.message}}}async read(key){try{return{success:!0,data:await this.dapr.state.get(key,this.storeName)??null}}catch(error){return{success:!1,error:error.message}}}async update(key,value,_preserveTtl=!0){try{return await this.dapr.state.save([{key,value}],void 0,this.storeName),{success:!0,data:"OK"}}catch(error){return{success:!1,error:error.message}}}async remove(key){try{return await this.dapr.state.delete(key,void 0,void 0,this.storeName),{success:!0,data:1}}catch(error){return{success:!1,error:error.message}}}async exists(key){try{let data=await this.dapr.state.get(key,this.storeName);return{success:!0,data:data!==void 0&&data!==null}}catch(error){return{success:!1,error:error.message}}}}class RedisManager{static instance=null;store;directClient=null;useDapr;constructor(config){if(RedisManager.instance){this.store=RedisManager.instance.store,this.directClient=RedisManager.instance.directClient,this.useDapr=RedisManager.instance.useDapr;return}if(!config)throw Error("Redis config must be provided for first initialization.");if(assertRedisConfig(config),this.useDapr=config.withDapr??!1,config.withDapr)this.store=new DaprRedisStore(config.stateStoreName??"statestore");else{let client=config.url?new Redis(config.url):new Redis({host:config.host,port:config.port,...config.password?{password:config.password}:{},...config.username?{username:config.username}:{},...config.tls?{tls:{}}:{}});this.directClient=client,this.store=new DirectRedisStore(client)}RedisManager.instance=this}async create(key,value,ttlSeconds){return this.store.create(key,value,ttlSeconds)}async read(key){return this.store.read(key)}async update(key,value,preserveTtl=!0){return this.store.update(key,value,preserveTtl)}async remove(key){return this.store.remove(key)}async exists(key){return this.store.exists(key)}async readCounters(keys){return(await Promise.all(keys.map((k)=>this.read(k)))).map((r)=>{let v=r.success?r.data:null,n=typeof v==="number"?v:Number.parseFloat(String(v??""));return Number.isFinite(n)?n:0})}async incrementCounter(key,delta,ttlSeconds){if(!this.useDapr&&this.directClient){let v=await this.directClient.incrbyfloat(key,delta);if(ttlSeconds&&ttlSeconds>0)try{await this.directClient.expire(key,ttlSeconds)}catch{}return Number(v)}let cur=await this.read(key),raw=cur.success?cur.data:null,base=typeof raw==="number"?raw:Number.parseFloat(String(raw??"")),next=(Number.isFinite(base)?base:0)+delta;return await this.create(key,next,ttlSeconds),next}getDirectClient(){return this.directClient}async reauthenticate(username,password){if(this.directClient)await this.directClient.auth(username,password)}async keys(pattern){if(this.useDapr||!this.directClient)return logger.scoped("database.redis").warn("keys() not supported in Dapr mode",{pattern}),[];try{return await this.directClient.keys(pattern)}catch(error){return logger.scoped("database.redis").error("keys() failed",error,{pattern}),[]}}async acquireLock(lockKey,ttlSeconds=10){if(this.useDapr||!this.directClient){let existsResult=await this.exists(lockKey);if(!existsResult.success)return{success:!1,error:existsResult.error};if(existsResult.data)return{success:!0,data:!1};if((await this.create(lockKey,"1",ttlSeconds)).success)return{success:!0,data:!0};return{success:!1,error:"Failed to acquire lock"}}try{return{success:!0,data:await this.directClient.set(lockKey,"1","EX",ttlSeconds,"NX")==="OK"}}catch(error){return{success:!1,error:error.message}}}async releaseLock(lockKey){return this.remove(lockKey)}async waitForLock(lockKey,timeoutMs=5000,pollIntervalMs=50){let startTime=Date.now();while(Date.now()-startTime<timeoutMs){let existsResult=await this.exists(lockKey);if(!existsResult.success)return{success:!1,error:existsResult.error};if(!existsResult.data)return{success:!0,data:!0};await new Promise((resolve)=>setTimeout(resolve,pollIntervalMs))}return{success:!0,data:!1}}async getOrWait(key,timeoutMs=5000,pollIntervalMs=50){let startTime=Date.now();while(Date.now()-startTime<timeoutMs){let readResult=await this.read(key);if(!readResult.success)return{success:!1,error:readResult.error};if(readResult.data!==null)return{success:!0,data:readResult.data};await new Promise((resolve)=>setTimeout(resolve,pollIntervalMs))}return{success:!0,data:null}}}var assertRedisConfig=(config)=>{if(!config)throw Error("Redis config must be provided.");if(config.withDapr){if(!config.stateStoreName)throw Error("Dapr mode requires stateStoreName.");return}let hasUrl=Boolean(config.url),hasHostPort=Boolean(config.host)&&typeof config.port==="number";if(!hasUrl&&!hasHostPort)throw Error("Redis config requires either url or host and port.")};var init_Redis=__esm(()=>{init_Logger2();init_Dapr()});var init_Delete=__esm(()=>{init_Redis()});var init_Generate3=__esm(()=>{init_Redis();init_JWT()});var init_Read=__esm(()=>{init_Redis();init_JWT();init_Delete()});var init_Validate2=__esm(()=>{init_Read()});var init_RefreshToken=__esm(()=>{init_Delete();init_Generate3();init_Read();init_Validate2()});var DEFAULT_EXPIRY_SECONDS=86400,buildSessionKey=(sessionId)=>`session:${sessionId}`,serializeSession=(record)=>JSON.stringify(record),deserializeSession=(data)=>{if(!data)return null;if(typeof data==="object")return data;try{return JSON.parse(data)}catch{return null}};var deleteSession=async(options)=>{let manager=new RedisManager,key=buildSessionKey(options.sessionId),removeResult=await manager.remove(key);return removeResult.success&&removeResult.data>0};var init_Delete2=__esm(()=>{init_Redis()});import crypto4 from"crypto";var generateSession=async(options)=>{let manager=new RedisManager,sessionId=options.sessionId??crypto4.randomUUID(),now=Date.now(),expiresIn=(options.expiresInSeconds??DEFAULT_EXPIRY_SECONDS)*1000,nowIso=new Date(now).toISOString(),record={id:sessionId,userId:options.userId,createdAt:nowIso,expiresAt:new Date(now+expiresIn).toISOString(),lastActiveAt:nowIso,clientMeta:options.clientMeta,fingerprintHash:options.fingerprintHash,deviceInfo:options.deviceInfo,refreshTokenHash:options.refreshTokenHash,loginMethod:options.loginMethod,rememberMe:options.rememberMe},ttlSeconds=options.expiresInSeconds??DEFAULT_EXPIRY_SECONDS,writeResult=await manager.create(buildSessionKey(sessionId),serializeSession(record),ttlSeconds);if(!writeResult.success)return{success:!1,error:writeResult.error};return{success:!0,session:record}};var init_Generate4=__esm(()=>{init_Redis()});var init_Issue=__esm(()=>{init_JWT();init_Generate3();init_Delete2();init_Generate4()});var init_Session=__esm(()=>{init_Issue()});var readSession=async(options)=>{let manager=new RedisManager,key=buildSessionKey(options.sessionId),readResult=await manager.read(key);if(!readResult.success||!readResult.data)return null;let record=deserializeSession(readResult.data);if(!record)return null;if(new Date(record.expiresAt).getTime()<=Date.now())return await deleteSession({sessionId:options.sessionId}),null;return record};var init_Read2=__esm(()=>{init_Redis();init_Delete2()});var updateSession=async(options)=>{let existing=await readSession({sessionId:options.sessionId});if(!existing)return{success:!1,error:"Session not found"};let updated={...existing,...options.updates,lastActiveAt:options.updates.lastActiveAt??new Date().toISOString()},manager=new RedisManager,remainingMs=new Date(updated.expiresAt).getTime()-Date.now(),remainingTtlSeconds=Math.max(60,Math.ceil(remainingMs/1000)),writeResult=await manager.create(buildSessionKey(options.sessionId),serializeSession(updated),remainingTtlSeconds);if(!writeResult.success)return{success:!1,error:writeResult.error};return{success:!0,session:updated}},updateLastActiveAt=async(sessionId)=>{return updateSession({sessionId,updates:{lastActiveAt:new Date().toISOString()}})};var init_Update=__esm(()=>{init_Redis();init_Read2()});var validateSession=async(options)=>{let jwtResult=verifyJWT(options.jwtToken,options.jwtSecret);if(!jwtResult.valid)return{isValid:!1,reason:jwtResult.error};let session=await readSession({sessionId:options.sessionId});if(!session)return{isValid:!1,reason:"Session not found"};let fingerprintValid;if(options.savedFingerprint&&options.headers&&options.requestIp){let sanitizedHeaders={};for(let[key,value]of Object.entries(options.headers))if(value!==void 0)sanitizedHeaders[key]=value;let fingerprintResult=validateDeviceFingerprint({savedFingerprint:options.savedFingerprint,headers:sanitizedHeaders,requestIp:options.requestIp});if(fingerprintValid=fingerprintResult.isValid,!fingerprintResult.isValid)return{isValid:!1,reason:fingerprintResult.reason??"Fingerprint mismatch"}}return{isValid:!0,context:{userId:session.userId,sessionId:session.id,fingerprintValid}}};var init_Validate3=__esm(()=>{init_Validate();init_JWT();init_Read2()});var exports_SessionStore={};__export(exports_SessionStore,{validateSession:()=>validateSession,updateSession:()=>updateSession,updateLastActiveAt:()=>updateLastActiveAt,readSession:()=>readSession,generateSession:()=>generateSession,deleteSession:()=>deleteSession});var init_SessionStore=__esm(()=>{init_Delete2();init_Generate4();init_Read2();init_Update();init_Validate3()});var init_Auth=__esm(()=>{init_Fingerprint();init_JWT();init_Password();init_RefreshToken();init_Session();init_SessionStore()});import{eq}from"drizzle-orm";function buildClaimAction(method,entity,field,relation,relationField,isBulk){let parts=[method.toLowerCase()];if(isBulk)parts.push("bulk");if(parts.push(entity),relation){if(parts.push("with"),parts.push(relation),relationField)parts.push(relationField)}else if(field)parts.push(field);return parts.join(".")}function buildClaimPath(entity,isBulk,hasId){if(isBulk)return`/${entity}/bulk`;if(hasId)return`/${entity}/:id`;return`/${entity}`}function generateEntityClaims(entity,config,schemaRelations){let claims=[],tableName=entity.table_name,excludedMethods=entity.excluded_methods||[];for(let method of HTTP_METHODS){if(excludedMethods.includes(method))continue;let needsId=method==="PUT"||method==="PATCH"||method==="DELETE";if(claims.push({action:buildClaimAction(method,tableName),description:`${method} access to ${tableName}`,path:buildClaimPath(tableName,!1,needsId&&method!=="DELETE"),method}),method==="GET"&&entity.columns){for(let column of entity.columns){if(config.skipColumns.includes(column.name))continue;claims.push({action:buildClaimAction(method,tableName,column.name),description:`${method} access to ${tableName}.${column.name}`,path:buildClaimPath(tableName),method})}let relationKey=`${tableName.replace(/_([a-z])/g,(_,l)=>l.toUpperCase())}Relations`;if(schemaRelations[relationKey]){let relationConfig=schemaRelations[relationKey];if(relationConfig?.config?.referencedTable?._?.name){let relationName=relationConfig.config.referencedTable._.name;claims.push({action:buildClaimAction(method,tableName,void 0,relationName),description:`${method} access to ${tableName} with ${relationName}`,path:buildClaimPath(tableName),method})}}}if(method==="POST"||method==="PUT"||method==="PATCH"){if(entity.columns)for(let column of entity.columns){if(config.skipColumns.includes(column.name))continue;claims.push({action:buildClaimAction(method,tableName,column.name),description:`${method} access to ${tableName}.${column.name}`,path:buildClaimPath(tableName,!1,method!=="POST"),method})}}}if(entity.bulk_endpoints_enabled===!0)for(let method of BULK_METHODS){if(excludedMethods.includes(method))continue;claims.push({action:buildClaimAction(method,tableName,void 0,void 0,void 0,!0),description:`Bulk ${method} access to ${tableName}`,path:buildClaimPath(tableName,!0),method})}return claims}async function seedClaims(db,schemaTables,schemaRelations,entities,config,logger2){let claimsTable=schemaTables.claims;if(!claimsTable)return logger2.warn("[Authorization] Claims table not found in schema"),{total:0,created:0,existing:0,claims:[]};let allClaims=[];for(let entity of entities){if(config.skipTables.includes(entity.table_name))continue;let entityClaims=generateEntityClaims(entity,config,schemaRelations);allClaims.push(...entityClaims)}let uniqueClaims=allClaims.filter((claim,index,self2)=>index===self2.findIndex((c)=>c.action===claim.action)),created=0,existing=0,claimActions=[];for(let claim of uniqueClaims)try{if((await db.select().from(claimsTable).where(eq(claimsTable.action,claim.action)).limit(1)).length===0)await db.insert(claimsTable).values(claim),created++,claimActions.push(claim.action),logger2.debug(`[Authorization] Created claim: ${claim.action}`);else existing++}catch(error){logger2.error(`[Authorization] Failed to create claim: ${claim.action}`,error)}return logger2.info(`[Authorization] Claims seeded: ${created} created, ${existing} existing, ${uniqueClaims.length} total`),{total:uniqueClaims.length,created,existing,claims:claimActions}}var HTTP_METHODS,BULK_METHODS;var init_ClaimSeeder=__esm(()=>{HTTP_METHODS=["GET","POST","PUT","PATCH","DELETE"],BULK_METHODS=["POST","PUT","DELETE"]});var exports_ClaimsCache={};__export(exports_ClaimsCache,{ClaimsCache:()=>ClaimsCache});import{eq as eq2}from"drizzle-orm";class ClaimsCache{prefix;redis;db;schemaTables;logger;constructor(config){this.prefix=config.prefix||DEFAULT_PREFIX,this.redis=config.redis,this.db=config.db,this.schemaTables=config.schemaTables,this.logger=config.logger}key(suffix){return`${this.prefix}:${suffix}`}async buildCache(){let rolesTable=this.schemaTables.roles,roleClaimsTable=this.schemaTables.roleClaims,claimsTable=this.schemaTables.claims;if(!rolesTable||!roleClaimsTable||!claimsTable)return this.logger.warn("[ClaimsCache] Required tables not found, skipping cache build"),{version:0,roleCount:0,totalMappings:0};let allRoles=await this.db.select().from(rolesTable),roleNames=[],totalMappings=0;for(let role of allRoles){let r=role,roleId=r.id,roleName=r.name;roleNames.push(roleName);let roleClaimRows=await this.db.select().from(roleClaimsTable).innerJoin(claimsTable,eq2(roleClaimsTable.claimId,claimsTable.id)).where(eq2(roleClaimsTable.roleId,roleId)),claimActions=[];for(let row of roleClaimRows){let action=row.claims?.action;if(action)claimActions.push(action)}await this.redis.set(this.key(`role:${roleName}`),JSON.stringify(claimActions)),totalMappings+=claimActions.length}await this.redis.set(this.key("roles"),JSON.stringify(roleNames));let versionStr=await this.redis.get(this.key("version")),newVersion=(parseInt(versionStr||"0",10)||0)+1;return await this.redis.set(this.key("version"),String(newVersion)),this.logger.info("[ClaimsCache] Cache built",{version:newVersion,roleCount:roleNames.length,totalMappings}),{version:newVersion,roleCount:roleNames.length,totalMappings}}async getVersion(){let v=await this.redis.get(this.key("version"));return parseInt(v||"0",10)||0}async resolveClaimsForRoles(roleNames){let allClaims=new Set;for(let roleName of roleNames){let cached=await this.redis.get(this.key(`role:${roleName}`));if(cached){let claims=JSON.parse(cached);for(let c of claims)allClaims.add(c)}}return Array.from(allClaims)}async invalidate(){return(await this.buildCache()).version}getPrefix(){return this.prefix}}var DEFAULT_PREFIX="nucleus:claims";var init_ClaimsCache=()=>{};var DEFAULT_AUTHORIZATION_CONFIG,AUTHORIZATION_TABLE_KEYS,GODMIN_ROLE_NAME="godmin";var init_types3=__esm(()=>{DEFAULT_AUTHORIZATION_CONFIG={enabled:!1,autoSeedClaims:!0,skipTables:["audit_logs"],skipColumns:["id","created_at","updated_at","is_active","password","version"],excludedPaths:[],publicPaths:["/auth/login","/auth/register"]},AUTHORIZATION_TABLE_KEYS={users:"users",roles:"roles",claims:"claims",userRoles:"userRoles",roleClaims:"roleClaims"}});var{password}=globalThis.Bun;import{and,eq as eq3}from"drizzle-orm";async function setupGodmin(db,schemaTables,config,logger2){if(!config.godminEmail||!config.godminPassword)return logger2.warn("[Authorization] Godmin email or password not configured, skipping godmin setup"),{success:!1};let{roles:rolesTable,users:usersTable,userRoles:userRolesTable}=schemaTables;if(!rolesTable||!usersTable||!userRolesTable)return logger2.error("[Authorization] Required tables not found for godmin setup"),{success:!1};try{let roleId,existingRole=await db.select().from(rolesTable).where(eq3(rolesTable.name,GODMIN_ROLE_NAME)).limit(1);if(existingRole.length===0){let[newRole]=await db.insert(rolesTable).values({name:GODMIN_ROLE_NAME,description:"God mode administrator - bypasses all authorization checks"}).returning();roleId=newRole.id,logger2.info(`[Authorization] Created godmin role: ${roleId}`)}else roleId=existingRole[0].id,logger2.debug(`[Authorization] Godmin role already exists: ${roleId}`);let userId,existingUser=await db.select().from(usersTable).where(eq3(usersTable.email,config.godminEmail)).limit(1);if(existingUser.length===0){let hashedPassword=await password.hash(config.godminPassword,{algorithm:"bcrypt",cost:10}),[newUser]=await db.insert(usersTable).values({email:config.godminEmail,password:hashedPassword,verifiedAt:new Date,isActive:!0,isGod:!0}).returning();userId=newUser.id,logger2.info(`[Authorization] Created godmin user: ${userId}`)}else{if(userId=existingUser[0].id,!existingUser[0].isGod)await db.update(usersTable).set({isGod:!0}).where(eq3(usersTable.id,userId)),logger2.info(`[Authorization] Marked existing godmin user as isGod=true: ${userId}`);logger2.debug(`[Authorization] Godmin user already exists: ${userId}`)}if(!((await db.select().from(userRolesTable).where(and(eq3(userRolesTable.userId,userId),eq3(userRolesTable.roleId,roleId))).limit(1)).length>0))await db.insert(userRolesTable).values({userId,roleId}),logger2.info(`[Authorization] Assigned godmin role to user: ${userId}`);return{success:!0,userId,roleId}}catch(error){return logger2.error("[Authorization] Failed to setup godmin",error),{success:!1}}}function isGodminRole(roleName){return roleName===GODMIN_ROLE_NAME}var init_GodminSetup=__esm(()=>{init_types3()});import{eq as eq4,inArray,sql}from"drizzle-orm";function isSelfReference(value){return value.startsWith(SELF_PREFIX)}function parseSelfReference(value){return{field:value.slice(SELF_PREFIX.length)}}function parseScopeWithSelf(scope){if(!scope)return{};let params=new URLSearchParams(scope),result={};for(let[key,value]of params.entries())if(isSelfReference(value))result[key]=parseSelfReference(value);else result[key]=value;return result}function resolveScopeWithSelf(parsedScope,userData,logger2){let resolved={},unresolved=[];for(let[key,value]of Object.entries(parsedScope))if(typeof value==="object"&&"field"in value){if(!userData){logger2.warn(`[Authorization] Cannot resolve self:${value.field} - userData not provided`),unresolved.push(key);continue}let lookup=lookupUserDataField(userData,value.field);if(!lookup.found){logger2.warn(`[Authorization] Cannot resolve self:${value.field} - field not found in userData`),unresolved.push(key);continue}resolved[key]=lookup.value,logger2.debug(`[Authorization] Resolved self:${value.field} -> ${String(lookup.value)}`)}else resolved[key]=value;return{resolved,unresolved}}function resolveClaimScopes(rows,userData,logger2){let claimScopes={},dropped=new Set;for(let{action,scope}of rows){if(!scope)continue;if(!scope.includes("="))continue;let parsed=parseScopeWithSelf(scope),{resolved,unresolved}=resolveScopeWithSelf(parsed,userData,logger2);if(unresolved.length>0){dropped.add(action);continue}claimScopes[action]={...claimScopes[action]??{},...resolved}}for(let a of dropped)delete claimScopes[a];return{claimScopes,dropped:Array.from(dropped)}}function mergeGrantingScopes(grantingActions,claimScopes){if(!claimScopes)return;let merged={},any=!1;for(let action of grantingActions){let s=claimScopes[action];if(s&&Object.keys(s).length>0)Object.assign(merged,s),any=!0}return any?merged:void 0}function buildClaimPattern(method,entity,field,relation){let parts=[method.toLowerCase(),entity];if(relation)parts.push("with",relation);else if(field)parts.push(field);return parts.join(".")}function claimMatches(userClaim,requiredPattern,requireSpecificity=!1){if(userClaim===requiredPattern)return!0;let userParts=userClaim.split("."),requiredParts=requiredPattern.split(".");if(userParts.length>requiredParts.length)return!1;if(requireSpecificity&&userParts.length<2&&requiredParts.length>=2)return!1;for(let i=0;i<userParts.length;i++)if(userParts[i]!==requiredParts[i])return!1;return!0}async function checkAuthorization(params){let{userId,method,entity,requestedFields,requestedRelations,db,schemaTables,logger:logger2,getUserData}=params,reqSpec=params.requireClaimSpecificity??!1,userData=params.userData,ensureUserData=async()=>{if(userData!==void 0)return;if(getUserData)try{userData=await getUserData()}catch(err){logger2.warn("[Authorization] getUserData callback failed",{userId,error:err instanceof Error?err.message:String(err)})}},rolesTable=schemaTables[AUTHORIZATION_TABLE_KEYS.roles],userRolesTable=schemaTables[AUTHORIZATION_TABLE_KEYS.userRoles],roleClaimsTable=schemaTables[AUTHORIZATION_TABLE_KEYS.roleClaims],claimsTable=schemaTables[AUTHORIZATION_TABLE_KEYS.claims];if(!rolesTable||!userRolesTable||!roleClaimsTable||!claimsTable)return logger2.error("[Authorization] Required tables not found"),{authorized:!1,reason:"Authorization tables not configured"};try{let userRolesCols=userRolesTable,rolesCols=rolesTable,userRoles=await db.select({roleId:userRolesCols.roleId,roleName:rolesCols.name}).from(userRolesTable).innerJoin(rolesTable,eq4(userRolesCols.roleId,rolesCols.id)).where(eq4(userRolesCols.userId,userId));if(userRoles.length===0)return{authorized:!1,reason:"User has no roles assigned"};if(userRoles.some((ur)=>isGodminRole(ur.roleName)))return logger2.debug(`[Authorization] User ${userId} has godmin role, bypassing checks`),{authorized:!0};let roleIds=userRoles.map((ur)=>ur.roleId),roleClaimsCols=roleClaimsTable,claimsCols=claimsTable,roleClaims=await db.select({claimAction:claimsCols.action,scope:roleClaimsCols.scope}).from(roleClaimsTable).innerJoin(claimsTable,eq4(roleClaimsCols.claimId,claimsCols.id)).where(inArray(roleClaimsCols.roleId,roleIds));if(roleClaims.length===0)return{authorized:!1,reason:"User roles have no claims assigned"};let entityClaimPattern=buildClaimPattern(method,entity),hasEntityAccess=roleClaims.some((rc)=>claimMatches(rc.claimAction,entityClaimPattern,reqSpec)),allowedFields=[],allowedRelations=[],scopeFilters={},unresolvedSelf=[],fieldPatterns=(requestedFields??[]).map((field)=>({field,pattern:buildClaimPattern(method,entity,field)})),relationPatterns=(requestedRelations??[]).map((relation)=>({relation,pattern:buildClaimPattern(method,entity,void 0,relation)})),claimCouldGrant=(action)=>claimMatches(action,entityClaimPattern,reqSpec)||fieldPatterns.some((f)=>claimMatches(action,f.pattern,reqSpec))||relationPatterns.some((r)=>claimMatches(action,r.pattern,reqSpec));if(roleClaims.some((rc)=>{let scope=rc.scope;return!!scope&&scope.includes("self:")&&claimCouldGrant(rc.claimAction)}))await ensureUserData();let applyClaimScope=(rc)=>{let parsedScope=parseScopeWithSelf(rc.scope),{resolved,unresolved}=resolveScopeWithSelf(parsedScope,userData,logger2);Object.assign(scopeFilters,resolved),unresolvedSelf.push(...unresolved)},denyOnUnresolvedSelf=()=>{if(unresolvedSelf.length===0)return null;return logger2.warn("[Authorization] Denying request: unresolvable self: scope (failing closed)",{userId,method,entity,unresolved:unresolvedSelf}),{authorized:!1,reason:"Ownership scope could not be resolved"}};if(hasEntityAccess){for(let rc of roleClaims)if(claimMatches(rc.claimAction,entityClaimPattern,reqSpec))applyClaimScope(rc);let denied2=denyOnUnresolvedSelf();if(denied2)return denied2;return{authorized:!0,scopeFilters:Object.keys(scopeFilters).length>0?scopeFilters:void 0}}for(let{field,pattern}of fieldPatterns){let granting=roleClaims.filter((rc)=>claimMatches(rc.claimAction,pattern,reqSpec));if(granting.length>0){allowedFields.push(field);for(let rc of granting)applyClaimScope(rc)}}for(let{relation,pattern}of relationPatterns){let granting=roleClaims.filter((rc)=>claimMatches(rc.claimAction,pattern,reqSpec));if(granting.length>0){allowedRelations.push(relation);for(let rc of granting)applyClaimScope(rc)}}let denied=denyOnUnresolvedSelf();if(denied)return denied;if(!(allowedFields.length>0||allowedRelations.length>0))return{authorized:!1,reason:`No access to ${method} ${entity}`};return{authorized:!0,allowedFields:allowedFields.length>0?allowedFields:["id"],allowedRelations,scopeFilters:Object.keys(scopeFilters).length>0?scopeFilters:void 0}}catch(error){return logger2.error("[Authorization] Check failed",error),{authorized:!1,reason:"Authorization check failed"}}}function checkAuthorizationFromJWT(params){let{userClaims,userRoles,method,entity,requestedFields,requestedRelations,logger:logger2}=params,reqSpec=params.requireClaimSpecificity??!1,claimScopes=params.claimScopes;if(userClaims.length===0&&userRoles.length===0)return{authorized:!1,reason:"No roles or claims in token"};if(userRoles.some((r)=>isGodminRole(r)))return logger2.debug("[Authorization:JWT] User has godmin role, bypassing checks"),{authorized:!0};let entityClaimPattern=buildClaimPattern(method,entity),entityGranting=userClaims.filter((c)=>claimMatches(c,entityClaimPattern,reqSpec));if(entityGranting.length>0){let scopeFilters2=mergeGrantingScopes(entityGranting,claimScopes);return{authorized:!0,...scopeFilters2?{scopeFilters:scopeFilters2}:{}}}let allowedFields=[],allowedRelations=[],grantingActions=[];if(requestedFields)for(let field of requestedFields){let fieldPattern=buildClaimPattern(method,entity,field),granting=userClaims.filter((c)=>claimMatches(c,fieldPattern,reqSpec));if(granting.length>0)allowedFields.push(field),grantingActions.push(...granting)}if(requestedRelations)for(let relation of requestedRelations){let relationPattern=buildClaimPattern(method,entity,void 0,relation),granting=userClaims.filter((c)=>claimMatches(c,relationPattern,reqSpec));if(granting.length>0)allowedRelations.push(relation),grantingActions.push(...granting)}if(!(allowedFields.length>0||allowedRelations.length>0))return{authorized:!1,reason:`No access to ${method} ${entity}`};let scopeFilters=mergeGrantingScopes(grantingActions,claimScopes);return{authorized:!0,allowedFields:allowedFields.length>0?allowedFields:["id"],allowedRelations,...scopeFilters?{scopeFilters}:{}}}async function checkAuthorizationViaIDP(params){let{idpUrl,accessToken,method,entity,requestedFields,requestedRelations,logger:logger2}=params;try{let response=await fetch(`${idpUrl}/auth/check`,{method:"POST",headers:{"Content-Type":"application/json",Cookie:`access_token=${accessToken}`},body:JSON.stringify({entity,method,fields:requestedFields,relations:requestedRelations})});if(!response.ok)return logger2.warn(`[Authorization:IDP] IDP /auth/check returned ${response.status}`),{authorized:!1,reason:`IDP authorization check failed (${response.status})`};let payload=await response.json();return unwrapIdpCheckResponse(payload)}catch(error){let msg=error instanceof Error?error.message:String(error);return logger2.error(`[Authorization:IDP] Failed to reach IDP: ${msg}`),{authorized:!1,reason:"IDP authorization service unavailable"}}}function filterResponseFields(data,allowedFields){if(!allowedFields||allowedFields.length===0)return data;let fieldsToInclude=[...new Set([...["id"],...allowedFields])],filterSingle=(item)=>{let filtered={};for(let field of fieldsToInclude)if(field in item)filtered[field]=item[field];return filtered};if(Array.isArray(data))return data.map(filterSingle);return filterSingle(data)}function filterResponseRelations(data,allowedRelations){if(!allowedRelations)return data;let filterSingle=(item)=>{let filtered={...item};for(let key of Object.keys(filtered))if(typeof filtered[key]==="object"&&filtered[key]!==null&&!allowedRelations.includes(key))delete filtered[key];return filtered};if(Array.isArray(data))return data.map(filterSingle);return filterSingle(data)}function buildScopeConditions(scopeFilters,resolveColumn){let conditions=[],unresolvedFields=[];if(!scopeFilters)return{conditions,unresolvedFields};for(let[field,value]of Object.entries(scopeFilters)){let col=resolveColumn(field);if(col)conditions.push(eq4(col,value));else unresolvedFields.push(field),conditions.push(sql`1 = 0`)}return{conditions,unresolvedFields}}var SELF_PREFIX="self:",toCamelCase2=(value)=>value.replace(/_([a-z])/g,(_,c)=>c.toUpperCase()),toSnakeCase=(value)=>value.replace(/([A-Z])/g,(_,c)=>`_${c.toLowerCase()}`),lookupUserDataField=(userData,fieldName)=>{if(fieldName in userData)return{found:!0,value:userData[fieldName]};let camel=toCamelCase2(fieldName);if(camel!==fieldName&&camel in userData)return{found:!0,value:userData[camel]};let snake=toSnakeCase(fieldName);if(snake!==fieldName&&snake in userData)return{found:!0,value:userData[snake]};return{found:!1}},unwrapIdpCheckResponse=(payload)=>{if(!payload||typeof payload!=="object")return{authorized:!1,reason:"IDP returned malformed response"};let envelope=payload;if(envelope.data&&typeof envelope.data==="object"){let data=envelope.data;if(typeof data.authorized==="boolean")return data}let flat=payload;if(typeof flat.authorized==="boolean")return flat;return{authorized:!1,reason:"IDP returned unrecognised response shape"}};var init_Middleware=__esm(()=>{init_GodminSetup();init_types3()});var exports_SeedRunner={};__export(exports_SeedRunner,{runSeed:()=>runSeed,expandClaimPatterns:()=>expandClaimPatterns});import{and as and2,eq as eq5}from"drizzle-orm";function expandClaimPatterns(patterns,allActions){let out=new Set;for(let pattern of patterns)if(pattern.endsWith(".*")){let prefix=pattern.slice(0,-2);for(let action of allActions)if(action===prefix||action.startsWith(`${prefix}.`))out.add(action)}else out.add(pattern);return[...out]}async function runSeed(db,schemaTables,seedConfig,logger2){let{roles:rolesTable,claims:claimsTable,roleClaims:roleClaimsTable}=schemaTables,result={rolesCreated:0,rolesExisting:0,claimsCreated:0,claimsExisting:0,assignmentsCreated:0,assignmentsExisting:0,assignmentsUpdated:0};if(seedConfig.roles?.length&&rolesTable)for(let roleDef of seedConfig.roles)try{if((await db.select().from(rolesTable).where(eq5(rolesTable.name,roleDef.name)).limit(1)).length===0)await db.insert(rolesTable).values({name:roleDef.name,description:roleDef.description||""}),result.rolesCreated++,logger2.info(`[Seed] Created role: ${roleDef.name}`);else result.rolesExisting++}catch(error){logger2.error(`[Seed] Failed to seed role: ${roleDef.name}`,error)}if(seedConfig.claims?.length&&claimsTable)for(let claimDef of seedConfig.claims)try{let existing=await db.select().from(claimsTable).where(eq5(claimsTable.action,claimDef.action)).limit(1);if(existing.length===0)await db.insert(claimsTable).values({action:claimDef.action,path:claimDef.path,method:claimDef.method,description:claimDef.description||`${claimDef.method} ${claimDef.path}`,...claimDef.policy!==void 0?{policy:claimDef.policy}:{}}),result.claimsCreated++,logger2.info(`[Seed] Created claim: ${claimDef.action}`);else if(claimDef.policy!==void 0){let existingRow=existing[0],currentPolicy=JSON.stringify(existingRow.policy??null),desiredPolicy=JSON.stringify(claimDef.policy??null);if(currentPolicy!==desiredPolicy)await db.update(claimsTable).set({policy:claimDef.policy}).where(eq5(claimsTable.action,claimDef.action)),result.claimsExisting++,logger2.warn(`[Seed] Reconciled policy for claim: ${claimDef.action}`);else result.claimsExisting++}else result.claimsExisting++}catch(error){logger2.error(`[Seed] Failed to seed claim: ${claimDef.action}`,error)}if(seedConfig.roleClaimAssignments?.length&&rolesTable&&claimsTable&&roleClaimsTable){let allClaimActions=(await db.select().from(claimsTable)).map((c)=>String(c.action??""));for(let assignment of seedConfig.roleClaimAssignments){let role=(await db.select().from(rolesTable).where(eq5(rolesTable.name,assignment.role)).limit(1))[0];if(!role){logger2.warn(`[Seed] Role not found for assignment: ${assignment.role}`);continue}let roleId=role.id,resolvedActions=expandClaimPatterns(assignment.claims,allClaimActions);for(let pattern of assignment.claims)if(pattern.endsWith(".*")&&!resolvedActions.some((a)=>a.startsWith(pattern.slice(0,-1))))logger2.warn(`[Seed] No claim matched prefix pattern: ${pattern}`);for(let claimAction of resolvedActions)try{let claim=(await db.select().from(claimsTable).where(eq5(claimsTable.action,claimAction)).limit(1))[0];if(!claim){logger2.warn(`[Seed] Claim not found for assignment: ${claimAction}`);continue}let claimId=claim.id,existingAssignment=await db.select().from(roleClaimsTable).where(and2(eq5(roleClaimsTable.roleId,roleId),eq5(roleClaimsTable.claimId,claimId))).limit(1);if(existingAssignment.length===0)await db.insert(roleClaimsTable).values({roleId,claimId,scope:assignment.scope||null}),result.assignmentsCreated++;else{let existingRow=existingAssignment[0],desiredScope=assignment.scope||null,currentScope=existingRow.scope??null;if(currentScope!==desiredScope)await db.update(roleClaimsTable).set({scope:desiredScope}).where(and2(eq5(roleClaimsTable.roleId,roleId),eq5(roleClaimsTable.claimId,claimId))),result.assignmentsUpdated++,logger2.warn(`[Seed] Reconciled scope for ${assignment.role} -> ${claimAction}: ${JSON.stringify(currentScope)} => ${JSON.stringify(desiredScope)}`);else result.assignmentsExisting++}}catch(error){logger2.error(`[Seed] Failed to assign claim ${claimAction} to role ${assignment.role}`,error)}if(result.assignmentsCreated>0)logger2.info(`[Seed] Role "${assignment.role}": assigned ${result.assignmentsCreated} claims`)}}return result}var init_SeedRunner=()=>{};var init_Authorization=__esm(()=>{init_ClaimSeeder();init_ClaimsCache();init_GodminSetup();init_Middleware();init_SeedRunner();init_types3()});import{createCipheriv,createDecipheriv,randomBytes as randomBytes2,scryptSync}from"crypto";var MAGIC,IV_LEN=12,TAG_LEN=16,deriveKey=(secret)=>scryptSync(secret,"nucleus-backup-v1",32),encryptBackup=(plaintext,secret)=>{if(!secret)throw Error("backup encryption key is empty");let key=deriveKey(secret),iv=randomBytes2(IV_LEN),cipher=createCipheriv("aes-256-gcm",key,iv),ciphertext=Buffer.concat([cipher.update(plaintext,"utf-8"),cipher.final()]),tag=cipher.getAuthTag();return Buffer.concat([MAGIC,iv,tag,ciphertext])},isEncryptedBackup=(buf)=>buf.length>=MAGIC.length+IV_LEN+TAG_LEN&&buf.subarray(0,MAGIC.length).equals(MAGIC),decryptBackup=(blob,secret)=>{if(!secret)throw Error("backup encryption key is empty");if(!isEncryptedBackup(blob))throw Error("not an encrypted backup");let key=deriveKey(secret),iv=blob.subarray(MAGIC.length,MAGIC.length+IV_LEN),tag=blob.subarray(MAGIC.length+IV_LEN,MAGIC.length+IV_LEN+TAG_LEN),ciphertext=blob.subarray(MAGIC.length+IV_LEN+TAG_LEN),decipher=createDecipheriv("aes-256-gcm",key,iv);return decipher.setAuthTag(tag),Buffer.concat([decipher.update(ciphertext),decipher.final()]).toString("utf-8")};var init_encryption=__esm(()=>{MAGIC=Buffer.from("NXB1")});import{mkdir,readFile,stat,unlink,writeFile}from"fs/promises";import{join}from"path";import{eq as eq6,sql as sql2}from"drizzle-orm";class BackupService{db;logger;config;schemaTables;schemaName;backupLogsTable;cronTimer=null;schedulerActive=!1;constructor(serviceConfig){this.db=serviceConfig.db,this.logger=serviceConfig.logger,this.config=serviceConfig.config,this.schemaTables=serviceConfig.schemaTables,this.schemaName=serviceConfig.schemaName,this.backupLogsTable=serviceConfig.backupLogsTable}async createBackup(trigger="manual",performedBy,targetSchemaName,targetSchemaTables){let resolvedSchema=targetSchemaName||this.schemaName,resolvedTables=targetSchemaTables||this.schemaTables,now=new Date,backupId=crypto.randomUUID(),timestamp=now.toISOString().replace(/[:.]/g,"-"),backupName=`${resolvedSchema}_${timestamp}`,fileName=`${backupName}.json`,filePath=join(this.config.storagePath,fileName),logRecord={id:backupId,backupName,fileName,schemaName:resolvedSchema,format:this.config.format,status:"running",trigger,sizeBytes:null,tableCount:null,rowCount:null,includedTables:[],excludedTables:this.config.excludeTables,errorMessage:null,startedAt:now.toISOString(),completedAt:null,performedBy:performedBy||null,cronExpression:trigger==="scheduled"?this.config.schedule.cron:null,retentionDays:this.config.schedule.retentionDays};await this.insertLogRecord(logRecord);try{await mkdir(this.config.storagePath,{recursive:!0});let tableNames=this.getBackupTableNames(resolvedTables),backupData=[],totalRows=0;for(let tableName of tableNames){let table=resolvedTables[tableName];if(!table)continue;try{let rows=await this.db.select().from(table),columns=Object.keys(table).filter((k)=>!k.startsWith("_")&&typeof table[k]!=="function");backupData.push({tableName,columns,rows}),totalRows+=rows.length}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to export table ${tableName}: ${msg}`)}}let backupFile={manifest:{version:"1.0",createdAt:now.toISOString(),schemaName:resolvedSchema,format:this.config.format,tables:backupData.map((t)=>({tableName:t.tableName,rowCount:t.rows.length,columns:t.columns})),totalRows},data:backupData},jsonContent=JSON.stringify(backupFile,null,2);if(this.config.encryptionKey)await writeFile(filePath,encryptBackup(jsonContent,this.config.encryptionKey));else await writeFile(filePath,jsonContent,"utf-8");let fileStats=await stat(filePath);return logRecord.status="completed",logRecord.completedAt=new Date().toISOString(),logRecord.tableCount=backupData.length,logRecord.rowCount=totalRows,logRecord.sizeBytes=fileStats.size,logRecord.includedTables=tableNames,await this.updateLogRecord(logRecord),this.logger.info("[Backup] Backup completed",{backupId,schemaName:resolvedSchema,tables:backupData.length,rows:totalRows,sizeBytes:fileStats.size}),await this.enforceMaxBackups(),logRecord}catch(err){let msg=err instanceof Error?err.message:String(err);return logRecord.status="failed",logRecord.errorMessage=msg,logRecord.completedAt=new Date().toISOString(),await this.updateLogRecord(logRecord),this.logger.error("[Backup] Backup failed",err,{backupId,schemaName:resolvedSchema}),logRecord}}async restoreFromBackup(backupId,performedBy,targetSchemaName,targetSchemaTables){if(!this.config.allowRestore)return{success:!1,message:"Restore is disabled in configuration"};let resolvedTables=targetSchemaTables||this.schemaTables,logRecord=await this.getLogRecord(backupId);if(!logRecord)return{success:!1,message:"Backup not found"};if(logRecord.status!=="completed")return{success:!1,message:`Cannot restore from backup with status: ${logRecord.status}`};let filePath=join(this.config.storagePath,logRecord.fileName);try{let raw=await readFile(filePath),content;if(isEncryptedBackup(raw)){if(!this.config.encryptionKey)return{success:!1,message:"Backup is encrypted but no encryption key is configured"};content=decryptBackup(raw,this.config.encryptionKey)}else content=raw.toString("utf-8");let backupFile=JSON.parse(content);await this.createBackup("pre_restore",performedBy,targetSchemaName,targetSchemaTables);let tablesRestored=0,rowsRestored=0;return await this.db.transaction(async(tx)=>{await tx.execute(sql2`SET CONSTRAINTS ALL DEFERRED`);for(let tableData of backupFile.data){let table=resolvedTables[tableData.tableName];if(!table){this.logger.warn(`[Backup] Skipping restore for ${tableData.tableName}: table not found in schema`);continue}if(tableData.rows.length===0)continue;await tx.delete(table);let chunkSize=500;for(let i=0;i<tableData.rows.length;i+=chunkSize){let chunk=tableData.rows.slice(i,i+chunkSize);await tx.insert(table).values(chunk)}tablesRestored++,rowsRestored+=tableData.rows.length}}),logRecord.status="restored",await this.updateLogRecord(logRecord),this.logger.info("[Backup] Restore completed",{backupId,tablesRestored,rowsRestored}),{success:!0,message:`Restored ${tablesRestored} tables with ${rowsRestored} rows`,tablesRestored,rowsRestored}}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.error("[Backup] Restore failed",err,{backupId}),{success:!1,message:`Restore failed: ${msg}`}}}async listBackups(){if(!this.backupLogsTable)return[];return await this.db.select().from(this.backupLogsTable).orderBy(sql2`created_at DESC`).limit(100)}async getBackupFilePath(backupId){let record=await this.getLogRecord(backupId);if(!record)return null;return join(this.config.storagePath,record.fileName)}async deleteBackup(backupId){let record=await this.getLogRecord(backupId);if(!record)return!1;let filePath=join(this.config.storagePath,record.fileName);try{await unlink(filePath)}catch{}if(this.backupLogsTable)await this.db.delete(this.backupLogsTable).where(eq6(col(this.backupLogsTable,"id"),backupId));return!0}startScheduler(){if(!this.config.schedule.enabled||!this.config.schedule.cron)return;this.logger.info("[Backup] Scheduler started",{cron:this.config.schedule.cron,retentionDays:this.config.schedule.retentionDays}),this.schedulerActive=!0,this.scheduleNextRun()}scheduleNextRun(){if(!this.schedulerActive)return;let delayMs=this.getNextDelayMs(this.config.schedule.cron);this.logger.debug?.("[Backup] Next scheduled backup",{inMs:delayMs}),this.cronTimer=setTimeout(async()=>{try{this.logger.info("[Backup] Scheduled backup starting..."),await this.createBackup("scheduled"),await this.cleanupExpiredBackups()}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.error("[Backup] Scheduled backup failed",{error:msg})}finally{this.scheduleNextRun()}},delayMs)}stopScheduler(){if(this.schedulerActive=!1,this.cronTimer)clearTimeout(this.cronTimer),this.cronTimer=null,this.logger.info("[Backup] Scheduler stopped")}getBackupTableNames(tables){return Object.keys(tables).filter((name)=>{if(this.config.excludeTables.includes(name))return!1;let val=tables[name];if(!val||typeof val!=="object")return!1;return Object.getOwnPropertySymbols(val).length>0})}async insertLogRecord(record){if(!this.backupLogsTable)return;try{await this.db.insert(this.backupLogsTable).values({id:record.id,backupName:record.backupName,fileName:record.fileName,schemaName:record.schemaName,format:record.format,status:record.status,trigger:record.trigger,sizeBytes:record.sizeBytes,tableCount:record.tableCount,rowCount:record.rowCount,includedTables:JSON.stringify(record.includedTables),excludedTables:JSON.stringify(record.excludedTables),errorMessage:record.errorMessage,startedAt:record.startedAt?new Date(record.startedAt):null,completedAt:record.completedAt?new Date(record.completedAt):null,performedBy:record.performedBy,cronExpression:record.cronExpression,retentionDays:record.retentionDays,createdAt:new Date,updatedAt:new Date})}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to insert backup log: ${msg}`)}}async updateLogRecord(record){if(!this.backupLogsTable)return;try{await this.db.update(this.backupLogsTable).set({status:record.status,sizeBytes:record.sizeBytes,tableCount:record.tableCount,rowCount:record.rowCount,includedTables:JSON.stringify(record.includedTables),errorMessage:record.errorMessage,completedAt:record.completedAt?new Date(record.completedAt):null,updatedAt:new Date}).where(eq6(col(this.backupLogsTable,"id"),record.id))}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to update backup log: ${msg}`)}}async getLogRecord(backupId){if(!this.backupLogsTable)return null;return(await this.db.select().from(this.backupLogsTable).where(eq6(col(this.backupLogsTable,"id"),backupId)).limit(1))[0]||null}async enforceMaxBackups(){if(!this.backupLogsTable)return;let allBackups=await this.db.select().from(this.backupLogsTable).where(eq6(col(this.backupLogsTable,"status"),"completed")).orderBy(sql2`created_at DESC`);if(allBackups.length>this.config.maxBackups){let toDelete=allBackups.slice(this.config.maxBackups);for(let backup of toDelete){let b=backup;await this.deleteBackup(b.id)}this.logger.info("[Backup] Old backups cleaned up",{deleted:toDelete.length})}}async cleanupExpiredBackups(){if(!this.backupLogsTable||!this.config.schedule.retentionDays)return;let cutoff=new Date;cutoff.setDate(cutoff.getDate()-this.config.schedule.retentionDays);let{lt}=await import("drizzle-orm"),expired=await this.db.select().from(this.backupLogsTable).where(lt(col(this.backupLogsTable,"createdAt"),cutoff));for(let backup of expired){let b=backup;await this.deleteBackup(b.id)}if(expired.length>0)this.logger.info("[Backup] Expired backups cleaned up",{deleted:expired.length,retentionDays:this.config.schedule.retentionDays})}getNextDelayMs(cron){let parts=cron.trim().split(/\s+/);if(parts.length!==5)return 86400000;let[min,hour]=parts;if(hour?.startsWith("*/")){let h2=Number.parseInt(hour.slice(2),10);return Number.isFinite(h2)&&h2>0?h2*60*60*1000:86400000}if(min?.startsWith("*/")){let m2=Number.parseInt(min.slice(2),10);return Number.isFinite(m2)&&m2>0?m2*60*1000:3600000}let m=Number.parseInt(min??"",10),h=Number.parseInt(hour??"",10);if(Number.isFinite(m)&&m>=0&&m<60&&Number.isFinite(h)&&h>=0&&h<24){let now=new Date,next=new Date(now);if(next.setHours(h,m,0,0),next.getTime()<=now.getTime())next.setDate(next.getDate()+1);return next.getTime()-now.getTime()}return 86400000}}var col=(table,name)=>table[name];var init_BackupService=__esm(()=>{init_encryption()});var init_Backup=__esm(()=>{init_BackupService()});function parseTimeToSeconds(time){let match=time.match(/^(\d+)(s|m|h|d)$/);if(!match||!match[1]||!match[2])return 300;let value=Number.parseInt(match[1],10);switch(match[2]){case"s":return value;case"m":return value*60;case"h":return value*3600;case"d":return value*86400;default:return 300}}function generateSecureId(){let bytes=new Uint8Array(24);return crypto.getRandomValues(bytes),Array.from(bytes).map((b)=>b.toString(16).padStart(2,"0")).join("")}function hashAnswer(answer){let hasher=new Bun.CryptoHasher("sha256");return hasher.update(answer),hasher.digest("hex")}function timingSafeEqual(a,b){if(a.length!==b.length){let dummy=new Uint8Array(32);return crypto.getRandomValues(dummy),!1}let encoder=new TextEncoder,bufA=encoder.encode(a),bufB=encoder.encode(b),result=0;for(let i=0;i<bufA.length;i++)result|=(bufA[i]??0)^(bufB[i]??0);return result===0}function getSecureRandomInt(min,max){let range=max-min+1,bytesNeeded=Math.ceil(Math.log2(range)/8)||1,maxValue=256**bytesNeeded,limit=maxValue-maxValue%range,randomValue,bytes=new Uint8Array(bytesNeeded);do crypto.getRandomValues(bytes),randomValue=bytes.reduce((acc,byte,i)=>acc+byte*256**i,0);while(randomValue>=limit);return min+randomValue%range}function generateMathChallenge(difficulty){let config=DIFFICULTY_CONFIG[difficulty],{min,max}=config.mathRange,operations=["+","-","\xD7"],operation=operations[getSecureRandomInt(0,operations.length-1)],num1=getSecureRandomInt(min,max),num2=getSecureRandomInt(min,max),answer;switch(operation){case"+":answer=num1+num2;break;case"-":if(num1<num2)[num1,num2]=[num2,num1];answer=num1-num2;break;case"\xD7":num1=getSecureRandomInt(1,12),num2=getSecureRandomInt(1,12),answer=num1*num2;break;default:answer=num1+num2}return{question:`${num1} ${operation} ${num2} = ?`,answer:answer.toString()}}function generateTextChallenge(difficulty){let config=DIFFICULTY_CONFIG[difficulty],text="";for(let i=0;i<config.textLength;i++)text+="ABCDEFGHJKLMNPQRSTUVWXYZ23456789".charAt(getSecureRandomInt(0,31));return{question:text,answer:text}}function generateImageChallenge(difficulty){let textChallenge=generateTextChallenge(difficulty),width=200,height=60,svgContent=generateCaptchaSVG(textChallenge.answer,200,60),imageData=`data:image/svg+xml;base64,${Buffer.from(svgContent).toString("base64")}`;return{question:"Enter the text shown in the image",answer:textChallenge.answer,imageData}}function getSecureFloat(){let bytes=new Uint32Array(1);return crypto.getRandomValues(bytes),(bytes[0]??0)/4294967295}function generateCaptchaSVG(text,width,height){let bgR=240+getSecureFloat()*15,bgG=240+getSecureFloat()*15,bgB=240+getSecureFloat()*15,bgColor=`rgb(${bgR}, ${bgG}, ${bgB})`,noiseLines="";for(let i=0;i<12;i++){let x1=getSecureFloat()*width,y1=getSecureFloat()*height,x2=getSecureFloat()*width,y2=getSecureFloat()*height,r=getSecureFloat()*100+100,g=getSecureFloat()*100+100,b=getSecureFloat()*100+100,strokeWidth=1+getSecureFloat()*2;noiseLines+=`<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="rgb(${r},${g},${b})" stroke-width="${strokeWidth}"/>`}let noiseCurves="";for(let i=0;i<4;i++){let startX2=getSecureFloat()*width,startY=getSecureFloat()*height,cp1X=getSecureFloat()*width,cp1Y=getSecureFloat()*height,cp2X=getSecureFloat()*width,cp2Y=getSecureFloat()*height,endX=getSecureFloat()*width,endY=getSecureFloat()*height,r=getSecureFloat()*80+80,g=getSecureFloat()*80+80,b=getSecureFloat()*80+80;noiseCurves+=`<path d="M${startX2},${startY} C${cp1X},${cp1Y} ${cp2X},${cp2Y} ${endX},${endY}" stroke="rgb(${r},${g},${b})" stroke-width="2" fill="none"/>`}let noiseDots="";for(let i=0;i<80;i++){let x=getSecureFloat()*width,y=getSecureFloat()*height,r=getSecureFloat()*150+50,g=getSecureFloat()*150+50,b=getSecureFloat()*150+50,radius=getSecureFloat()*3+1;noiseDots+=`<circle cx="${x}" cy="${y}" r="${radius}" fill="rgb(${r},${g},${b})"/>`}let textElements="",charWidth=width/(text.length+2),startX=charWidth;for(let i=0;i<text.length;i++){let x=startX+i*charWidth+(getSecureFloat()-0.5)*15,y=height/2+8+(getSecureFloat()-0.5)*12,rotation=(getSecureFloat()-0.5)*40,fontSize=22+getSecureFloat()*10,r=getSecureFloat()*80,g=getSecureFloat()*80,b=getSecureFloat()*80,skewX=(getSecureFloat()-0.5)*15,scaleY=0.9+getSecureFloat()*0.3;textElements+=`<text x="${x}" y="${y}" font-family="Arial, Helvetica, sans-serif" font-size="${fontSize}" font-weight="bold" fill="rgb(${r},${g},${b})" transform="rotate(${rotation}, ${x}, ${y}) skewX(${skewX}) scale(1, ${scaleY})" style="font-style: ${getSecureFloat()>0.5?"italic":"normal"}">${text[i]}</text>`}let overlayLines="";for(let i=0;i<3;i++){let y=10+getSecureFloat()*(height-20),r=getSecureFloat()*60+60,g=getSecureFloat()*60+60,b=getSecureFloat()*60+60;overlayLines+=`<line x1="0" y1="${y}" x2="${width}" y2="${y+(getSecureFloat()-0.5)*20}" stroke="rgb(${r},${g},${b})" stroke-width="1.5"/>`}return`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
|
|
17
|
+
`).slice(1,4);for(let stackLine of stackLines)method(` ${dim}${stackLine.trim()}${reset}`)}}}getConsoleMethod(level){switch(level){case"debug":return console.debug.bind(console);case"info":return console.info.bind(console);case"warn":return console.warn.bind(console);case"error":case"fatal":return console.error.bind(console);default:return console.log.bind(console)}}}class DatabaseAuditTransport{name="database";db;table;enabled;dedupEnabled;dedupWindowMs;dedupSlots=new Map;lastSweep=0;constructor(options){this.db=options.db,this.table=options.table,this.enabled=options.enabled??!0,this.dedupEnabled=options.dedup?.enabled??!1,this.dedupWindowMs=Math.max(1,options.dedup?.windowSeconds??60)*1000}setDb(db){this.db=db}setTable(table){this.table=table}setEnabled(enabled){this.enabled=enabled}setDedup(dedup){if(this.dedupEnabled=dedup.enabled??this.dedupEnabled,dedup.windowSeconds!=null)this.dedupWindowMs=Math.max(1,dedup.windowSeconds)*1000}isDedupable(entry){return this.dedupEnabled&&(entry.category==="auth"||entry.category==="authz"||entry.category==="security_anomaly")}sweep(now){if(now-this.lastSweep<this.dedupWindowMs)return;this.lastSweep=now;for(let[key,slot]of this.dedupSlots)if(slot.expiresAt<=now)this.dedupSlots.delete(key)}async write(entry){if(!this.enabled||!this.db||!this.table)return;try{let now=Date.now();if(this.isDedupable(entry)){this.sweep(now);let key=`${entry.ipAddress}|${entry.operation}|${entry.summary}|${entry.userId??""}`,slot=this.dedupSlots.get(key);if(slot&&slot.expiresAt>now){slot.count+=1,await this.bumpOccurrence(slot.rowId,slot.count,now);return}this.dedupSlots.set(key,{rowId:entry.id,count:1,expiresAt:now+this.dedupWindowMs})}await this.db.insert(this.table).values({id:entry.id,entityId:entry.entityId,entityName:entry.entityName,operationType:entry.operation,userId:entry.userId,ipAddress:entry.ipAddress,userAgent:entry.userAgent,summary:entry.summary,severity:entry.severity,category:entry.category,occurrenceCount:1,oldValues:entry.oldValues,newValues:entry.newValues,path:entry.path,query:entry.query})}catch(error){console.error("Audit log write failed:",error)}}async bumpOccurrence(rowId,count,nowMs){try{let{eq}=await import("drizzle-orm"),idCol=this.table.id;await this.db.update(this.table).set({occurrenceCount:count,lastOccurrenceAt:new Date(nowMs)}).where(eq(idCol,rowId))}catch(error){console.error("Audit dedup update failed:",error)}}}class ConsoleAuditTransport{name="console-audit";enabled;constructor(options={}){this.enabled=options.enabled??!0}write(entry){if(!this.enabled)return;let reset=RESET_COLOR,dim=DIM_COLOR,color={info:"\x1B[35m",low:"\x1B[90m",medium:"\x1B[33m",high:"\x1B[31m",critical:"\x1B[1m\x1B[31m"}[entry.severity]??"\x1B[35m",sev=entry.severity.toUpperCase(),actor=entry.userId||"anonymous",cat=entry.category;console.log(`${dim}${entry.timestamp}${reset} ${color}AUDIT\xB7${sev}${reset} ${dim}(${cat})${reset} [${entry.operation}] ${entry.entityName}${entry.entityId?`:${entry.entityId}`:""} ${dim}by ${actor}${reset}${entry.summary?` ${dim}\u2014${reset} ${entry.summary}`:""}`)}}var init_transports=__esm(()=>{init_types();init_utils()});import{randomUUID}from"crypto";class Logger{config;transports;auditTransports;context;correlationId;static instance=null;constructor(config={},context={},correlationId){this.config={...DEFAULT_CONFIG,...config},this.config.redactKeys=[...new Set([...DEFAULT_REDACT_KEYS,...config.redactKeys||[]])],this.context=context,this.correlationId=correlationId,this.transports=[new ConsoleTransport({colorize:this.config.colorize,prettyPrint:this.config.prettyPrint})],this.auditTransports=[new ConsoleAuditTransport({enabled:this.config.prettyPrint})]}static getInstance(config){if(!Logger.instance)Logger.instance=new Logger(config);return Logger.instance}static resetInstance(){Logger.instance=null}configure(config){return this.config={...this.config,...config},this.config.redactKeys=[...new Set([...DEFAULT_REDACT_KEYS,...config.redactKeys||this.config.redactKeys||[]])],this.transports=[new ConsoleTransport({colorize:this.config.colorize,prettyPrint:this.config.prettyPrint}),...this.transports.filter((t)=>t.name!=="console")],this}child(context,correlationId){let childLogger=new Logger(this.config,mergeContext(this.context,context)||{},correlationId||this.correlationId);return childLogger.transports=this.transports,childLogger.auditTransports=this.auditTransports,childLogger}withCorrelationId(correlationId){return this.child({},correlationId)}addTransport(transport){this.transports.push(transport)}addAuditTransport(transport){this.auditTransports.push(transport)}setLevel(level){this.config.level=level}setAuditEnabled(enabled){this.config.auditEnabled=enabled}isAuditEnabled(){return this.config.auditEnabled}setAuditSuppressReasons(reasons){this.config.auditSuppressReasons=reasons}setAuditMinSeverity(severity){this.config.auditMinSeverity=severity}shouldLog(level){return LOG_LEVEL_PRIORITY[level]>=LOG_LEVEL_PRIORITY[this.config.level]}shouldLogScope(scope){if(!scope)return!0;return matchesScope(scope,this.config.enabledScopes)}setEnabledScopes(scopes){this.config.enabledScopes=scopes}getEnabledScopes(){return this.config.enabledScopes}scoped(scope){return new ScopedLogger(this,scope)}createEntry(level,message,context,error,startTime,scope){let entry={timestamp:new Date().toISOString(),level,message,scope,service:this.config.service,correlationId:this.correlationId},mergedContext=mergeContext(this.context,context);if(mergedContext&&Object.keys(mergedContext).length>0)entry.context=redactSensitiveData(mergedContext,this.config.redactKeys);if(this.config.includeCallerInfo)entry.caller=getCallerInfo();if(error)entry.error=formatError(error);if(startTime!==void 0)entry.duration=performance.now()-startTime;return entry}log(level,message,context,error,startTime,scope){if(!this.shouldLog(level))return;if(!this.shouldLogScope(scope))return;let entry=this.createEntry(level,message,context,error,startTime,scope);for(let transport of this.transports)try{transport.log(entry)}catch(err){console.error(`Logger transport "${transport.name}" failed:`,err)}}debug(message,context){this.log("debug",message,context)}info(message,context){this.log("info",message,context)}warn(message,context){this.log("warn",message,context)}error(message,error,context){this.log("error",message,context,error)}fatal(message,error,context){this.log("fatal",message,context,error)}time(label){let start=performance.now();return()=>{this.log("debug",`${label} completed`,void 0,void 0,start)}}async timeAsync(label,fn,context){let start=performance.now();try{let result=await fn();return this.log("debug",`${label} completed`,context,void 0,start),result}catch(error){throw this.log("error",`${label} failed`,context,error,start),error}}request(options){let level=options.statusCode>=500?"error":options.statusCode>=400?"warn":"info";this.log(level,`${options.method} ${options.path} ${options.statusCode}`,{method:options.method,path:options.path,statusCode:options.statusCode,durationMs:options.duration,correlationId:options.correlationId,userId:options.userId,ip:options.ip,userAgent:options.userAgent})}db(options){let level=options.error?"error":"debug";this.log(level,`DB ${options.operation} on ${options.table}`,{operation:options.operation,table:options.table,durationMs:options.duration,rowCount:options.rowCount},options.error)}async flush(){for(let transport of this.transports)if(transport.flush)await transport.flush()}async audit(options){let summary=options.summary||`${options.operation} on ${options.entityName}`;if(this.config.auditSuppressReasons?.includes(summary))return;let derived=classifyAudit(options.operation,summary),severity=options.severity??derived.severity,category=options.category??derived.category;if(severityRank(severity)<severityRank(this.config.auditMinSeverity))return;let entry={id:randomUUID(),timestamp:new Date().toISOString(),entityName:options.entityName,entityId:options.entityId??null,operation:options.operation,userId:options.userId??null,summary,severity,category,oldValues:redactSensitiveData(options.oldValues||{}),newValues:redactSensitiveData(options.newValues||{}),ipAddress:options.ipAddress||"unknown",userAgent:options.userAgent||"unknown",path:options.path||"",query:options.query||"",correlationId:this.correlationId};for(let transport of this.auditTransports)try{await transport.write(entry)}catch(err){console.error(`Audit transport "${transport.name}" failed:`,err)}}auditOnly(options){this.audit(options)}async trace(options){let shouldLog=options.log!==!1,shouldAudit=options.writeAudit===!0||options.writeAudit!==!1&&this.config.auditEnabled&&options.audit;if(shouldLog)this.log(options.level||"info",options.message,options.context,options.error);if(shouldAudit&&options.audit)await this.audit(options.audit)}traceSync(options){let shouldLog=options.log!==!1,shouldAudit=options.writeAudit===!0||options.writeAudit!==!1&&this.config.auditEnabled&&options.audit;if(shouldLog)this.log(options.level||"info",options.message,options.context,options.error);if(shouldAudit&&options.audit)this.audit(options.audit)}}class ScopedLogger{parent;scope;constructor(parent,scope){this.parent=parent,this.scope=scope}debug(message,context){this.parent.log("debug",message,context,void 0,void 0,this.scope)}info(message,context){this.parent.log("info",message,context,void 0,void 0,this.scope)}warn(message,context){this.parent.log("warn",message,context,void 0,void 0,this.scope)}error(message,error,context){this.parent.log("error",message,context,error,void 0,this.scope)}}var DEFAULT_CONFIG,logger;var init_Logger=__esm(()=>{init_auditTaxonomy();init_scopes();init_transports();init_types();init_utils();DEFAULT_CONFIG={level:"info",service:"nucleus",environment:"development",redactKeys:[],colorize:!0,prettyPrint:!0,includeCallerInfo:!0,asyncBufferSize:100,flushIntervalMs:1000,auditEnabled:!1,auditSuppressReasons:DEFAULT_AUDIT_SUPPRESS_REASONS,auditMinSeverity:"info",enabledScopes:["*"]};logger=Logger.getInstance()});var require_fast_decode_uri_component=__commonJS((exports,module)=>{var UTF8_ACCEPT=12,UTF8_REJECT=0,UTF8_DATA=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,7,7,7,7,7,7,7,7,7,7,7,7,8,7,7,10,9,9,9,11,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,24,36,48,60,72,84,96,0,12,12,12,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,24,24,24,0,0,0,0,0,0,0,0,0,24,24,0,0,0,0,0,0,0,0,0,0,48,48,48,0,0,0,0,0,0,0,0,0,0,48,48,0,0,0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0,127,63,63,63,0,31,15,15,15,7,7,7];function decodeURIComponent2(uri){var percentPosition=uri.indexOf("%");if(percentPosition===-1)return uri;var length=uri.length,decoded="",last=0,codepoint=0,startOfOctets=percentPosition,state=UTF8_ACCEPT;while(percentPosition>-1&&percentPosition<length){var high=hexCodeToInt(uri[percentPosition+1],4),low=hexCodeToInt(uri[percentPosition+2],0),byte=high|low,type=UTF8_DATA[byte];if(state=UTF8_DATA[256+state+type],codepoint=codepoint<<6|byte&UTF8_DATA[364+type],state===UTF8_ACCEPT)decoded+=uri.slice(last,startOfOctets),decoded+=codepoint<=65535?String.fromCharCode(codepoint):String.fromCharCode(55232+(codepoint>>10),56320+(codepoint&1023)),codepoint=0,last=percentPosition+3,percentPosition=startOfOctets=uri.indexOf("%",last);else if(state===UTF8_REJECT)return null;else{if(percentPosition+=3,percentPosition<length&&uri.charCodeAt(percentPosition)===37)continue;return null}}return decoded+uri.slice(last)}var HEX={"0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};function hexCodeToInt(c,shift){var i=HEX[c];return i===void 0?255:i<<shift}module.exports=decodeURIComponent2});import{createHash,randomBytes}from"crypto";var API_KEY_BYTE_LENGTH=32,HASH_ALGORITHM="sha256",generateApiKey=(prefix="nk_live")=>{let randomPart=randomBytes(API_KEY_BYTE_LENGTH).toString("hex"),rawKey=`${prefix}_${randomPart}`,keyHash=hashApiKey(rawKey),keyPreview=`${prefix}_...${randomPart.slice(-4)}`;return{rawKey,keyHash,keyPreview}},hashApiKey=(rawKey)=>{return createHash(HASH_ALGORITHM).update(rawKey).digest("hex")},validateApiKeyFormat=(rawKey)=>{return/^nk_(live|test)_[a-f0-9]{64}$/.test(rawKey)},extractApiKeyFromHeader=(headers)=>{let apiKeyHeader=headers.get("x-api-key");if(apiKeyHeader&&validateApiKeyFormat(apiKeyHeader))return apiKeyHeader;let authHeader=headers.get("authorization");if(authHeader){let bearerMatch=authHeader.match(/^Bearer\s+(nk_(?:live|test)_[a-f0-9]{64})$/);if(bearerMatch?.[1])return bearerMatch[1]}return null},validateApiKeyRecord=(record)=>{if(!record.isActive)return{valid:!1,reason:"API key is inactive"};if(record.revokedAt)return{valid:!1,reason:"API key has been revoked"};if(record.expiresAt&&new Date(record.expiresAt)<new Date)return{valid:!1,reason:"API key has expired"};return{valid:!0,record}},intersectPermissions=(userPermissions,keyPermissions)=>{let userSet=new Set(userPermissions);return keyPermissions.filter((p)=>userSet.has(p))};var init_ApiKey=()=>{};var normalize=(value)=>{return value?.trim().toLowerCase()||"unknown"},extractHeaderValue=(headers,key)=>{return headers[key.toLowerCase()]??headers[key]};import crypto2 from"crypto";var generateDeviceFingerprint=(input)=>{let payload=JSON.stringify({userAgent:normalize(input.userAgent),extra:input.extra??{}});return{hash:crypto2.createHash("sha256").update(payload).digest("base64url"),components:input}};var init_Generate=()=>{};var validateDeviceFingerprint=({savedFingerprint,requestIp,headers})=>{let userAgent=extractHeaderValue(headers,"user-agent"),forwardedFor=extractHeaderValue(headers,"x-forwarded-for")??requestIp??void 0,currentFingerprint=generateDeviceFingerprint({userAgent,ipAddress:forwardedFor}),componentMismatch=[{field:"userAgent",saved:savedFingerprint.components.userAgent,received:userAgent},{field:"ipAddress",saved:savedFingerprint.components.ipAddress,received:forwardedFor}].find(({saved,received})=>saved??(received??"")!=="");if(componentMismatch)return{isValid:!1,reason:`${componentMismatch.field} mismatch`,currentFingerprint};return{isValid:!0,currentFingerprint}};var init_Validate=__esm(()=>{init_Generate()});var init_Fingerprint=__esm(()=>{init_Generate();init_Validate()});import crypto3 from"crypto";var base64UrlEncode=(data)=>{return(Buffer.isBuffer(data)?data.toString("base64"):Buffer.from(data).toString("base64")).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},base64UrlDecode=(data)=>{let padding="=".repeat((4-data.length%4)%4),base64=data.replace(/-/g,"+").replace(/_/g,"/")+padding;return Buffer.from(base64,"base64").toString("utf-8")},createSignature=(data,secret,algorithm)=>{let hmacAlgorithm=algorithm.replace("HS","sha"),hmac=crypto3.createHmac(hmacAlgorithm,secret);return hmac.update(data),base64UrlEncode(hmac.digest())},verifySignature=(data,signature,secret,algorithm)=>{let expectedSignature=createSignature(data,secret,algorithm),sigBuf=Buffer.from(signature),expBuf=Buffer.from(expectedSignature);if(sigBuf.length!==expBuf.length)return!1;return crypto3.timingSafeEqual(sigBuf,expBuf)},encodeHeader=(header)=>{return base64UrlEncode(JSON.stringify(header))},encodePayload=(payload)=>{return base64UrlEncode(JSON.stringify(payload))},decodeHeader=(encoded)=>{try{return JSON.parse(base64UrlDecode(encoded))}catch{return null}},decodePayload=(encoded)=>{try{return JSON.parse(base64UrlDecode(encoded))}catch{return null}};var init_utils2=()=>{};var decodeJWT=(token)=>{let parts=token.split(".");if(parts.length!==3)return null;let[encodedHeader,encodedPayload,signature]=parts;if(!encodedHeader||!encodedPayload||!signature)return null;let header=decodeHeader(encodedHeader),payload=decodePayload(encodedPayload);if(!header||!payload)return null;return{header,payload,signature}};var init_Decode=__esm(()=>{init_utils2()});var signJWT=(options,secret,algorithm="HS256")=>{let header={alg:algorithm,typ:"JWT"},now=Math.floor(Date.now()/1000),payload={sub:options.subject,iat:now,exp:now+options.expiresInSeconds,iss:options.issuer,aud:options.audience,jti:options.jwtId,sessionId:options.sessionId,...options.customClaims},encodedHeader=encodeHeader(header),encodedPayload=encodePayload(payload),dataToSign=`${encodedHeader}.${encodedPayload}`,signature=createSignature(dataToSign,secret,algorithm);return`${dataToSign}.${signature}`};var init_Sign=__esm(()=>{init_utils2()});var audienceMatches=(aud,expected)=>{if(typeof aud==="string")return aud===expected;if(Array.isArray(aud))return aud.includes(expected);return!1},verifyJWT=(token,secret,expected)=>{let parts=token.split(".");if(parts.length!==3)return{valid:!1,error:"Invalid token format: expected 3 parts"};let[encodedHeader,encodedPayload,signature]=parts;if(!encodedHeader||!encodedPayload||!signature)return{valid:!1,error:"Invalid token format: missing parts"};let header=decodeHeader(encodedHeader);if(!header)return{valid:!1,error:"Invalid header: failed to decode"};if(header.typ!=="JWT")return{valid:!1,error:"Invalid header: typ must be JWT"};if(!["HS256","HS384","HS512"].includes(header.alg))return{valid:!1,error:`Unsupported algorithm: ${header.alg}`};let dataToVerify=`${encodedHeader}.${encodedPayload}`;if(!verifySignature(dataToVerify,signature,secret,header.alg))return{valid:!1,error:"Invalid signature"};let payload=decodePayload(encodedPayload);if(!payload)return{valid:!1,error:"Invalid payload: failed to decode"};let now=Math.floor(Date.now()/1000);if(payload.exp&&payload.exp<now)return{valid:!1,error:"Token expired"};if(payload.iat&&payload.iat>now+60)return{valid:!1,error:"Token issued in the future"};if(expected?.issuer&&payload.iss!==expected.issuer)return{valid:!1,error:"Invalid issuer"};if(expected?.audience&&!audienceMatches(payload.aud,expected.audience))return{valid:!1,error:"Invalid audience"};return{valid:!0,payload}};var init_Verify=__esm(()=>{init_utils2()});var exports_JWT={};__export(exports_JWT,{verifyJWT:()=>verifyJWT,signJWT:()=>signJWT,decodeJWT:()=>decodeJWT});var init_JWT=__esm(()=>{init_Decode();init_Sign();init_Verify()});var init_Generate2=()=>{};var init_Password=__esm(()=>{init_Generate2()});var init_Logger2=__esm(()=>{init_auditTaxonomy();init_Logger();init_transports();init_utils();init_scopes()});var DEFAULT_DAPR_HOST="127.0.0.1",DEFAULT_DAPR_PORT="3500",DEFAULT_MAX_BODY_SIZE_MB=4,DEFAULT_STATE_STORE="statestore-redis",DEFAULT_PUBSUB_NAME="pubsub-rabbitmq",DEFAULT_SECRET_STORE="secretstore",DEFAULT_CONFIG_STORE="configstore-redis",ENV_DAPR_HOST="DAPR_HOST",ENV_DAPR_HTTP_PORT="DAPR_HTTP_PORT",ENV_DAPR_HTTP_ENDPOINT="DAPR_HTTP_ENDPOINT",ENV_DAPR_GRPC_ENDPOINT="DAPR_GRPC_ENDPOINT",ENV_DAPR_API_TOKEN="DAPR_API_TOKEN",DEFAULT_OPERATION_TIMEOUT_MS=30000,DEFAULT_CONNECTION_TIMEOUT_MS=1e4,DEFAULT_HEALTH_CHECK_TIMEOUT_MS=5000,CONNECTION_STATUS,HEALTH_STATUS,ERROR_CODES;var init_constants=__esm(()=>{CONNECTION_STATUS={CONNECTED:"connected",DISCONNECTED:"disconnected",CONNECTING:"connecting",ERROR:"error"},HEALTH_STATUS={HEALTHY:"healthy",UNHEALTHY:"unhealthy"},ERROR_CODES={CONNECTION_ERROR:"DAPR_CONNECTION_ERROR",TIMEOUT_ERROR:"DAPR_TIMEOUT_ERROR",STATE_ERROR:"DAPR_STATE_ERROR",PUBSUB_ERROR:"DAPR_PUBSUB_ERROR",BINDING_ERROR:"DAPR_BINDING_ERROR",SECRET_ERROR:"DAPR_SECRET_ERROR",CONFIG_ERROR:"DAPR_CONFIG_ERROR",INVOKE_ERROR:"DAPR_INVOKE_ERROR",CRYPTO_ERROR:"DAPR_CRYPTO_ERROR",LOCK_ERROR:"DAPR_LOCK_ERROR",WORKFLOW_ERROR:"DAPR_WORKFLOW_ERROR",VALIDATION_ERROR:"DAPR_VALIDATION_ERROR"}});var DaprManagerError,createConnectionError=(message,details)=>new DaprManagerError(ERROR_CODES.CONNECTION_ERROR,message,details),createTimeoutError=(message,details)=>new DaprManagerError(ERROR_CODES.TIMEOUT_ERROR,message,details),createStateError=(message,details)=>new DaprManagerError(ERROR_CODES.STATE_ERROR,message,details),createPubSubError=(message,details)=>new DaprManagerError(ERROR_CODES.PUBSUB_ERROR,message,details),createBindingError=(message,details)=>new DaprManagerError(ERROR_CODES.BINDING_ERROR,message,details),createSecretError=(message,details)=>new DaprManagerError(ERROR_CODES.SECRET_ERROR,message,details),createConfigError=(message,details)=>new DaprManagerError(ERROR_CODES.CONFIG_ERROR,message,details),createInvokeError=(message,details)=>new DaprManagerError(ERROR_CODES.INVOKE_ERROR,message,details),createCryptoError=(message,details)=>new DaprManagerError(ERROR_CODES.CRYPTO_ERROR,message,details),createLockError=(message,details)=>new DaprManagerError(ERROR_CODES.LOCK_ERROR,message,details),createWorkflowError=(message,details)=>new DaprManagerError(ERROR_CODES.WORKFLOW_ERROR,message,details),safeExecute=async(operation,errorCreator)=>{try{return await operation()}catch(error){let errorMessage=error instanceof Error?error.message:String(error);throw errorCreator(errorMessage,error)}};var init_error_handling=__esm(()=>{init_constants();DaprManagerError=class DaprManagerError extends Error{code;details;constructor(code,message,details){super(message);this.name="DaprManagerError",this.code=code,this.details=details}toJSON(){return{code:this.code,message:this.message,details:this.details}}}});var LOG_LEVEL_PRIORITY2,createDefaultLogger=(minLevel="info")=>{let minPriority=LOG_LEVEL_PRIORITY2[minLevel],scoped=logger.scoped("dapr.client"),logWithLevel=(level)=>(message,...meta)=>{if(LOG_LEVEL_PRIORITY2[level]<minPriority)return;let context=meta.length>0?{meta}:void 0;if(level==="error")scoped.error(message,void 0,context);else scoped[level](message,context)};return{debug:logWithLevel("debug"),info:logWithLevel("info"),warn:logWithLevel("warn"),error:logWithLevel("error")}},withTimeout=async(fn,timeoutMs,errorMessage="Operation timed out")=>{return Promise.race([fn(),new Promise((_,reject)=>{setTimeout(()=>{reject(createTimeoutError(errorMessage))},timeoutMs)})])},validateRequired=(params,requiredKeys,entityName)=>{let missingKeys=requiredKeys.filter((key)=>params[key]===void 0);if(missingKeys.length>0)throw Error(`Missing required ${entityName} parameters: ${missingKeys.join(", ")}`)};var init_utils3=__esm(()=>{init_Logger2();init_constants();init_error_handling();LOG_LEVEL_PRIORITY2={debug:0,info:1,warn:2,error:3}});class DaprBindingClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async invoke(name,operation,data,options={}){return validateRequired({name,operation},["name","operation"],"binding invoke"),safeExecute(async()=>{this.logger.debug("Invoking binding",{name,operation});let response=await(await this.client()).binding.send(name,operation,data,options.metadata);return this.logger.debug("Binding invoked successfully",{name,operation}),response},(message,details)=>createBindingError(`Failed to invoke binding ${name}: ${message}`,details))}}var init_binding_client=__esm(()=>{init_error_handling();init_utils3()});class DaprConfigClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async get(keys,storeName=DEFAULT_CONFIG_STORE){if(validateRequired({keys,storeName},["keys","storeName"],"config get"),keys.length===0)return{};return safeExecute(async()=>{this.logger.debug("Getting configuration",{keys,storeName});let response=await(await this.client()).configuration.get(storeName,keys);return this.logger.debug("Configuration retrieved",{keys,storeName,itemCount:Object.keys(response.items||{}).length}),response.items||{}},(message,details)=>createConfigError(`Failed to get configuration: ${message}`,details))}async subscribeWithKeys(keys,callback,storeName=DEFAULT_CONFIG_STORE){if(validateRequired({keys,callback,storeName},["keys","callback","storeName"],"config subscribeWithKeys"),keys.length===0)throw createConfigError("At least one key must be provided for subscription");return safeExecute(async()=>{this.logger.debug("Subscribing to configuration updates",{keys,storeName});let stream=await(await this.client()).configuration.subscribeWithKeys(storeName,keys,async(data)=>{try{this.logger.debug("Received configuration update",{storeName,updatedKeys:Object.keys(data.items||{})}),await callback(data)}catch(error){this.logger.error("Error in configuration subscription callback",error)}});return this.logger.debug("Configuration subscription established",{keys,storeName}),{stop:()=>{this.logger.debug("Stopping configuration subscription",{keys,storeName}),stream.stop()}}},(message,details)=>createConfigError(`Failed to subscribe to configuration updates: ${message}`,details))}async getValue(key,storeName=DEFAULT_CONFIG_STORE){return(await this.get([key],storeName))[key]?.value}async getValues(keys,storeName=DEFAULT_CONFIG_STORE){let items=await this.get(keys,storeName),values={};for(let key in items)if(items[key]?.value!==void 0)values[key]=items[key].value;return values}}var init_config_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprCryptoClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async encrypt(data,options){return validateRequired({data,componentName:options.componentName},["data","componentName"],"crypto encrypt"),safeExecute(async()=>{this.logger.debug("Encrypting data",{componentName:options.componentName,keyName:options.keyName,keyWrapAlgorithm:options.keyWrapAlgorithm});let client=await this.client(),inputData=typeof data==="string"?Buffer.from(data):data,cryptoOptions={componentName:options.componentName};if(options.keyName)cryptoOptions.keyName=options.keyName;if(options.keyWrapAlgorithm)cryptoOptions.keyWrapAlgorithm=options.keyWrapAlgorithm;let encryptedData=await client.crypto.encrypt(inputData,cryptoOptions);return this.logger.debug("Data encrypted successfully",{componentName:options.componentName,inputSize:inputData.length,outputSize:encryptedData.length}),encryptedData},(message,details)=>createCryptoError(`Failed to encrypt data: ${message}`,details))}async decrypt(data,options){return validateRequired({data,componentName:options.componentName},["data","componentName"],"crypto decrypt"),safeExecute(async()=>{this.logger.debug("Decrypting data",{componentName:options.componentName});let client=await this.client(),inputData=typeof data==="string"?Buffer.from(data):data,cryptoOptions={componentName:options.componentName};if(options.keyName)cryptoOptions.keyName=options.keyName;if(options.keyWrapAlgorithm)cryptoOptions.keyWrapAlgorithm=options.keyWrapAlgorithm;let decryptedData=await client.crypto.decrypt(inputData,cryptoOptions);return this.logger.debug("Data decrypted successfully",{componentName:options.componentName,inputSize:inputData.length,outputSize:decryptedData.length}),decryptedData},(message,details)=>createCryptoError(`Failed to decrypt data: ${message}`,details))}async encryptString(plaintext,options){return(await this.encrypt(plaintext,options)).toString("base64")}async decryptString(ciphertext,options){let encryptedBuffer=Buffer.from(ciphertext,"base64");return(await this.decrypt(encryptedBuffer,options)).toString("utf-8")}}var init_crypto_client=__esm(()=>{init_error_handling();init_utils3()});import{HttpMethod}from"@dapr/dapr";class DaprInvokeClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async invoke(appId,methodName,httpMethod=HttpMethod.POST,data,options={}){validateRequired({appId,methodName,httpMethod},["appId","methodName","httpMethod"],"invoke service");let timeoutMs=options.timeout||DEFAULT_OPERATION_TIMEOUT_MS;return safeExecute(async()=>{this.logger.debug("Invoking service",{appId,methodName,httpMethod,hasData:data!==void 0});let fullMethodName=methodName;if(options.queryParams&&Object.keys(options.queryParams).length>0){let queryString=Object.entries(options.queryParams).map(([key,value])=>`${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");fullMethodName=`${methodName}?${queryString}`}let client=await this.client(),response=await withTimeout(()=>client.invoker.invoke(appId,fullMethodName,httpMethod,data,options.headers),timeoutMs,`Service invocation timed out after ${timeoutMs}ms`);if(this.logger.debug("Service invoked successfully",{appId,methodName,httpMethod,status:response?.status}),!response)return;if("data"in response)return response.data;return response},(message,details)=>createInvokeError(`Failed to invoke service ${appId}.${methodName}: ${message}`,details))}async get(appId,methodName,options={}){return this.invoke(appId,methodName,HttpMethod.GET,void 0,options)}async post(appId,methodName,data,options={}){return this.invoke(appId,methodName,HttpMethod.POST,data,options)}async put(appId,methodName,data,options={}){return this.invoke(appId,methodName,HttpMethod.PUT,data,options)}async delete(appId,methodName,options={}){return this.invoke(appId,methodName,HttpMethod.DELETE,void 0,options)}}var init_invoke_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprLockClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async lock(storeName,resourceId,lockOwner,options){return validateRequired({storeName,resourceId,lockOwner,expiryInSeconds:options.expiryInSeconds},["storeName","resourceId","lockOwner","expiryInSeconds"],"lock"),safeExecute(async()=>{this.logger.debug("Acquiring lock",{storeName,resourceId,lockOwner});let response=await(await this.client()).lock.lock(storeName,resourceId,lockOwner,options.expiryInSeconds);return this.logger.debug("Lock acquisition result",{storeName,resourceId,lockOwner,success:response.success}),{success:response.success}},(message,details)=>createLockError(`Failed to acquire lock for resource ${resourceId}: ${message}`,details))}async unlock(storeName,resourceId,lockOwner){return validateRequired({storeName,resourceId,lockOwner},["storeName","resourceId","lockOwner"],"unlock"),safeExecute(async()=>{this.logger.debug("Releasing lock",{storeName,resourceId,lockOwner});let response=await(await this.client()).lock.unlock(storeName,resourceId,lockOwner);return this.logger.debug("Lock release result",{storeName,resourceId,lockOwner,status:this.getLockStatusName(response.status)}),{status:response.status}},(message,details)=>createLockError(`Failed to release lock for resource ${resourceId}: ${message}`,details))}getLockStatusName(status){switch(status){case 0:return"Success";case 1:return"LockDoesNotExist";case 2:return"LockBelongsToOthers";default:return"InternalError"}}}var init_lock_client=__esm(()=>{init_error_handling();init_utils3()});class DaprPubSubClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async publish(topic,data,options={},pubsubName=DEFAULT_PUBSUB_NAME){return validateRequired({topic,data,pubsubName},["topic","data","pubsubName"],"pubsub publish"),safeExecute(async()=>{this.logger.debug("Publishing message to topic",{topic,pubsubName}),await(await this.client()).pubsub.publish(pubsubName,topic,data,{metadata:options.metadata,contentType:options.contentType}),this.logger.debug("Message published successfully",{topic,pubsubName})},(message,details)=>createPubSubError(`Failed to publish message to topic ${topic}: ${message}`,details))}async publishBulk(topic,messages,pubsubName=DEFAULT_PUBSUB_NAME){if(validateRequired({topic,messages,pubsubName},["topic","messages","pubsubName"],"pubsub publishBulk"),messages.length===0)return{failedEntries:[]};return safeExecute(async()=>{this.logger.debug("Publishing bulk messages to topic",{topic,pubsubName,messageCount:messages.length});let client=await this.client(),daprMessages=messages.map((msg)=>{if(typeof msg==="object"&&"event"in msg)return{entryID:msg.entryId,event:msg.event,contentType:msg.contentType,metadata:msg.metadata};return{event:msg}}),response=await client.pubsub.publishBulk(pubsubName,topic,daprMessages),failedCount=response.failedMessages?.length||0;if(failedCount>0)this.logger.warn("Some messages failed to publish",{topic,pubsubName,failedCount,totalCount:messages.length});else this.logger.debug("All bulk messages published successfully",{topic,pubsubName,messageCount:messages.length});return{failedEntries:(response.failedMessages||[]).map((failed)=>({entryId:failed.message.entryID||"",error:failed.error?.message||"Unknown error"}))}},(message,details)=>createPubSubError(`Failed to publish bulk messages to topic ${topic}: ${message}`,details))}createBulkPublishMessage(event,entryId,contentType,metadata){return{entryId,event,contentType,metadata}}}var init_pubsub_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprSecretClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async get(key,options={},storeName=DEFAULT_SECRET_STORE){return validateRequired({key,storeName},["key","storeName"],"secret get"),safeExecute(async()=>{this.logger.debug("Getting secret",{key,storeName});let client=await this.client(),metadataStr=options.metadata?JSON.stringify(options.metadata):void 0,result=await client.secret.get(storeName,key,metadataStr);return this.logger.debug("Secret retrieved",{key,storeName}),result},(message,details)=>createSecretError(`Failed to get secret ${key}: ${message}`,details))}async getBulk(_options={},storeName=DEFAULT_SECRET_STORE){return validateRequired({storeName},["storeName"],"secret getBulk"),safeExecute(async()=>{this.logger.debug("Getting all secrets",{storeName});let result=await(await this.client()).secret.getBulk(storeName);return this.logger.debug("All secrets retrieved",{storeName,secretCount:Object.keys(result).length}),result},(message,details)=>createSecretError(`Failed to get all secrets: ${message}`,details))}}var init_secret_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprStateClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async save(stateItems,options={},storeName=DEFAULT_STATE_STORE){if(validateRequired({stateItems,storeName},["stateItems","storeName"],"state save"),stateItems.length===0)return;return safeExecute(async()=>{this.logger.debug("Saving state items",{count:stateItems.length,storeName}),await(await this.client()).state.save(storeName,stateItems,options),this.logger.debug("State items saved successfully",{count:stateItems.length,storeName})},(message,details)=>createStateError(`Failed to save state items: ${message}`,details))}async get(key,storeName=DEFAULT_STATE_STORE){return validateRequired({key,storeName},["key","storeName"],"state get"),safeExecute(async()=>{this.logger.debug("Getting state item",{key,storeName});let result=await(await this.client()).state.get(storeName,key);if(this.logger.debug("State item retrieved",{key,storeName,found:result!==void 0}),result===void 0||result===null)return;if(typeof result==="string")try{return JSON.parse(result)}catch{return result}if(typeof result==="object")return result;return result},(message,details)=>createStateError(`Failed to get state item ${key}: ${message}`,details))}async getBulk(keys,storeName=DEFAULT_STATE_STORE){if(validateRequired({keys,storeName},["keys","storeName"],"state getBulk"),keys.length===0)return{};return safeExecute(async()=>{this.logger.debug("Getting bulk state items",{count:keys.length,storeName});let results=await(await this.client()).state.getBulk(storeName,keys),resultMap={};return results.forEach((item)=>{if(item.data!==void 0)resultMap[item.key]=item.data}),this.logger.debug("Bulk state items retrieved",{count:keys.length,found:Object.keys(resultMap).length,storeName}),resultMap},(message,details)=>createStateError(`Failed to get bulk state items: ${message}`,details))}async delete(key,etag,metadata,storeName=DEFAULT_STATE_STORE){return validateRequired({key,storeName},["key","storeName"],"state delete"),safeExecute(async()=>{this.logger.debug("Deleting state item",{key,storeName});let client=await this.client(),options={};if(etag)options.etag=etag;if(metadata)options.metadata=metadata;await client.state.delete(storeName,key,options),this.logger.debug("State item deleted",{key,storeName})},(message,details)=>createStateError(`Failed to delete state item ${key}: ${message}`,details))}async transaction(operations,storeName=DEFAULT_STATE_STORE){if(validateRequired({operations,storeName},["operations","storeName"],"state transaction"),operations.length===0)return;return safeExecute(async()=>{this.logger.debug("Executing state transaction",{operationCount:operations.length,storeName});let client=await this.client(),daprOperations=operations.map((op)=>({operation:op.operation,request:{key:op.request.key,value:op.request.value,etag:op.request.etag?{value:op.request.etag}:void 0,metadata:op.request.metadata}}));await client.state.transaction(storeName,daprOperations),this.logger.debug("State transaction executed successfully",{operationCount:operations.length,storeName})},(message,details)=>createStateError(`Failed to execute state transaction: ${message}`,details))}async query(query,storeName=DEFAULT_STATE_STORE){return validateRequired({query,storeName},["query","storeName"],"state query"),safeExecute(async()=>{this.logger.debug("Querying state store",{storeName});let result=await(await this.client()).state.query(storeName,query);return this.logger.debug("State query executed",{storeName,resultCount:result.results?.length||0}),(result.results||[]).map((item)=>item.data)},(message,details)=>createStateError(`Failed to query state store: ${message}`,details))}async saveItem(key,value,options={},storeName=DEFAULT_STATE_STORE){let stateItem={key,value};return this.save([stateItem],options,storeName)}async upsert(key,value,options={},storeName=DEFAULT_STATE_STORE){return this.saveItem(key,value,options,storeName)}}var init_state_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprWorkflowClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async start(workflowName,input,options={}){return validateRequired({workflowName},["workflowName"],"workflow start"),safeExecute(async()=>{this.logger.debug("Starting workflow",{workflowName,instanceId:options.instanceId||"auto-generated",workflowComponent:options.workflowComponent});let instanceId=await(await this.client()).workflow.start(workflowName,input,options.instanceId);return this.logger.debug("Workflow started",{workflowName,instanceId}),instanceId},(message,details)=>createWorkflowError(`Failed to start workflow ${workflowName}: ${message}`,details))}async get(instanceId){return validateRequired({instanceId},["instanceId"],"workflow get"),safeExecute(async()=>{this.logger.debug("Getting workflow instance",{instanceId});let instance=await(await this.client()).workflow.get(instanceId);return this.logger.debug("Workflow instance retrieved",{instanceId,workflowName:instance.workflowName,runtimeStatus:instance.runtimeStatus}),{instanceId:instance.instanceID,workflowName:instance.workflowName,createdAt:new Date(instance.createdAt),lastUpdatedAt:new Date(instance.lastUpdatedAt),runtimeStatus:instance.runtimeStatus,properties:instance.properties||{}}},(message,details)=>createWorkflowError(`Failed to get workflow instance ${instanceId}: ${message}`,details))}async terminate(instanceId){return validateRequired({instanceId},["instanceId"],"workflow terminate"),safeExecute(async()=>{this.logger.debug("Terminating workflow instance",{instanceId}),await(await this.client()).workflow.terminate(instanceId),this.logger.debug("Workflow instance terminated",{instanceId})},(message,details)=>createWorkflowError(`Failed to terminate workflow instance ${instanceId}: ${message}`,details))}async pause(instanceId){return validateRequired({instanceId},["instanceId"],"workflow pause"),safeExecute(async()=>{this.logger.debug("Pausing workflow instance",{instanceId}),await(await this.client()).workflow.pause(instanceId),this.logger.debug("Workflow instance paused",{instanceId})},(message,details)=>createWorkflowError(`Failed to pause workflow instance ${instanceId}: ${message}`,details))}async resume(instanceId){return validateRequired({instanceId},["instanceId"],"workflow resume"),safeExecute(async()=>{this.logger.debug("Resuming workflow instance",{instanceId}),await(await this.client()).workflow.resume(instanceId),this.logger.debug("Workflow instance resumed",{instanceId})},(message,details)=>createWorkflowError(`Failed to resume workflow instance ${instanceId}: ${message}`,details))}async purge(instanceId){return validateRequired({instanceId},["instanceId"],"workflow purge"),safeExecute(async()=>{this.logger.debug("Purging workflow instance",{instanceId}),await(await this.client()).workflow.purge(instanceId),this.logger.debug("Workflow instance purged",{instanceId})},(message,details)=>createWorkflowError(`Failed to purge workflow instance ${instanceId}: ${message}`,details))}async raiseEvent(instanceId,eventName,eventData){return validateRequired({instanceId,eventName},["instanceId","eventName"],"workflow raiseEvent"),safeExecute(async()=>{this.logger.debug("Raising event for workflow instance",{instanceId,eventName}),await(await this.client()).workflow.raise(instanceId,eventName,eventData),this.logger.debug("Event raised for workflow instance",{instanceId,eventName})},(message,details)=>createWorkflowError(`Failed to raise event ${eventName} for workflow instance ${instanceId}: ${message}`,details))}}var init_workflow_client=__esm(()=>{init_error_handling();init_utils3()});import{CommunicationProtocolEnum,DaprClient,HttpMethod as HttpMethod2,LogLevel}from"@dapr/dapr";class DaprConnectionManager{client=null;daprHost;daprPort;communicationProtocol;maxBodySizeMb;daprApiToken;logger;connectionStatus=CONNECTION_STATUS.DISCONNECTED;connectionPromise=null;constructor(options={}){this.daprHost=options.daprHost||process.env[ENV_DAPR_HOST]||DEFAULT_DAPR_HOST,this.daprPort=options.daprPort||process.env[ENV_DAPR_HTTP_PORT]||DEFAULT_DAPR_PORT,this.communicationProtocol=options.communicationProtocol||CommunicationProtocolEnum.HTTP,this.maxBodySizeMb=options.maxBodySizeMb||DEFAULT_MAX_BODY_SIZE_MB,this.daprApiToken=options.daprApiToken||process.env[ENV_DAPR_API_TOKEN],this.logger=options.logger||createDefaultLogger(),this.logger.info("DaprConnectionManager initialized",{daprHost:this.daprHost,daprPort:this.daprPort,communicationProtocol:this.communicationProtocol})}async getClient(){if(!this.client||this.connectionStatus!==CONNECTION_STATUS.CONNECTED)await this.connect();if(!this.client)throw createConnectionError("Not connected to Dapr sidecar");return this.client}async connect(){if(this.connectionPromise)return this.connectionPromise;if(this.client&&this.connectionStatus===CONNECTION_STATUS.CONNECTED)return Promise.resolve();this.connectionStatus=CONNECTION_STATUS.CONNECTING,this.connectionPromise=this.establishConnection();try{await this.connectionPromise,this.connectionStatus=CONNECTION_STATUS.CONNECTED}catch(error){throw this.connectionStatus=CONNECTION_STATUS.ERROR,error}finally{this.connectionPromise=null}}async establishConnection(){try{this.logger.info("Connecting to Dapr sidecar",{daprHost:this.daprHost,daprPort:this.daprPort,protocol:this.communicationProtocol});let useEndpointFromEnv=process.env[ENV_DAPR_HTTP_ENDPOINT]&&this.communicationProtocol===CommunicationProtocolEnum.HTTP||process.env[ENV_DAPR_GRPC_ENDPOINT]&&this.communicationProtocol===CommunicationProtocolEnum.GRPC,clientOptions={communicationProtocol:this.communicationProtocol,maxBodySizeMb:this.maxBodySizeMb,logger:{level:LogLevel.Warn}};if(!useEndpointFromEnv)clientOptions.daprHost=this.daprHost,clientOptions.daprPort=this.daprPort;if(this.daprApiToken)clientOptions.daprApiToken=this.daprApiToken;await withTimeout(async()=>{this.client=new DaprClient(clientOptions)},DEFAULT_CONNECTION_TIMEOUT_MS,"Connection to Dapr sidecar timed out"),await this.healthCheck(),this.logger.info("Successfully connected to Dapr sidecar")}catch(error){throw this.logger.error("Failed to connect to Dapr sidecar",error),this.client=null,createConnectionError(`Failed to connect to Dapr sidecar at ${this.daprHost}:${this.daprPort}`,error)}}async disconnect(){if(!this.client)return;try{this.logger.info("Disconnecting from Dapr sidecar"),this.client=null,this.connectionStatus=CONNECTION_STATUS.DISCONNECTED,this.logger.info("Disconnected from Dapr sidecar")}catch(error){throw this.logger.error("Error during disconnect",error),createConnectionError("Failed to disconnect from Dapr sidecar",error)}}isConnected(){return this.client!==null&&this.connectionStatus===CONNECTION_STATUS.CONNECTED}getConnectionStatus(){return this.connectionStatus}async healthCheck(){if(!this.client)throw createConnectionError("Not connected to Dapr sidecar");try{return await withTimeout(async()=>{if(!this.client)throw createConnectionError("Not connected to Dapr sidecar");let response=await this.client.invoker.invoke("healthz","healthz",HttpMethod2.GET);return{status:response.status===204?HEALTH_STATUS.HEALTHY:HEALTH_STATUS.UNHEALTHY,version:response.headers?.["dapr-version"]||"unknown"}},DEFAULT_HEALTH_CHECK_TIMEOUT_MS,"Health check timed out")}catch(error){return this.logger.error("Health check failed",error),{status:HEALTH_STATUS.UNHEALTHY,version:"unknown"}}}getClientConfig(){return{daprHost:this.daprHost,daprPort:this.daprPort,communicationProtocol:this.communicationProtocol,maxBodySizeMb:this.maxBodySizeMb,hasApiToken:!!this.daprApiToken,connectionStatus:this.connectionStatus}}}var init_connection_manager=__esm(()=>{init_constants();init_error_handling();init_utils3()});var init_types2=()=>{};class DaprManager{connectionManager;logger;_state;_pubsub;_binding;_secret;_config;_invoke;_lock;_crypto;_workflow;constructor(options={}){this.logger=options.logger||createDefaultLogger(),this.connectionManager=new DaprConnectionManager(options);let clientProvider=async()=>{return this.connectionManager.getClient()};this._state=new DaprStateClient(clientProvider,this.logger),this._pubsub=new DaprPubSubClient(clientProvider,this.logger),this._binding=new DaprBindingClient(clientProvider,this.logger),this._secret=new DaprSecretClient(clientProvider,this.logger),this._config=new DaprConfigClient(clientProvider,this.logger),this._invoke=new DaprInvokeClient(clientProvider,this.logger),this._lock=new DaprLockClient(clientProvider,this.logger),this._crypto=new DaprCryptoClient(clientProvider,this.logger),this._workflow=new DaprWorkflowClient(clientProvider,this.logger)}async connect(){await this.connectionManager.connect()}async disconnect(){await this.connectionManager.disconnect()}isConnected(){return this.connectionManager.isConnected()}getConnectionStatus(){return this.connectionManager.getConnectionStatus()}async healthCheck(){return this.connectionManager.healthCheck()}getClientConfig(){return this.connectionManager.getClientConfig()}get state(){return this._state}get pubsub(){return this._pubsub}get binding(){return this._binding}get secret(){return this._secret}get config(){return this._config}get invoke(){return this._invoke}get lock(){return this._lock}get crypto(){return this._crypto}get workflow(){return this._workflow}}var daprManager;var init_Dapr=__esm(()=>{init_binding_client();init_config_client();init_crypto_client();init_invoke_client();init_lock_client();init_pubsub_client();init_secret_client();init_state_client();init_workflow_client();init_connection_manager();init_utils3();init_binding_client();init_config_client();init_crypto_client();init_invoke_client();init_lock_client();init_pubsub_client();init_secret_client();init_state_client();init_workflow_client();init_constants();init_error_handling();init_types2();daprManager=new DaprManager});import Redis from"ioredis";class DirectRedisStore{client;constructor(client){this.client=client}async create(key,value,ttlSeconds){try{return{success:!0,data:ttlSeconds?await this.client.set(key,JSON.stringify(value),"EX",ttlSeconds):await this.client.set(key,JSON.stringify(value))}}catch(error){return{success:!1,error:error.message}}}async read(key){try{let raw=await this.client.get(key);return{success:!0,data:raw?JSON.parse(raw):null}}catch(error){return{success:!1,error:error.message}}}async update(key,value,preserveTtl=!0){try{return{success:!0,data:preserveTtl?await this.client.set(key,JSON.stringify(value),"KEEPTTL"):await this.client.set(key,JSON.stringify(value))}}catch(error){return{success:!1,error:error.message}}}async remove(key){try{return{success:!0,data:await this.client.del(key)}}catch(error){return{success:!1,error:error.message}}}async exists(key){try{return{success:!0,data:await this.client.exists(key)===1}}catch(error){return{success:!1,error:error.message}}}getClient(){return this.client}}class DaprRedisStore{storeName;keyPrefix;dapr;constructor(storeName,keyPrefix=""){this.storeName=storeName;this.keyPrefix=keyPrefix;this.dapr=new DaprManager}k(key){return this.keyPrefix+key}async create(key,value,ttlSeconds){try{let metadata=ttlSeconds?{ttlInSeconds:String(ttlSeconds)}:void 0;return await this.dapr.state.save([{key:this.k(key),value,metadata}],void 0,this.storeName),{success:!0,data:"OK"}}catch(error){return{success:!1,error:error.message}}}async read(key){try{return{success:!0,data:await this.dapr.state.get(this.k(key),this.storeName)??null}}catch(error){return{success:!1,error:error.message}}}async update(key,value,_preserveTtl=!0){try{return await this.dapr.state.save([{key:this.k(key),value}],void 0,this.storeName),{success:!0,data:"OK"}}catch(error){return{success:!1,error:error.message}}}async remove(key){try{return await this.dapr.state.delete(this.k(key),void 0,void 0,this.storeName),{success:!0,data:1}}catch(error){return{success:!1,error:error.message}}}async exists(key){try{let data=await this.dapr.state.get(this.k(key),this.storeName);return{success:!0,data:data!==void 0&&data!==null}}catch(error){return{success:!1,error:error.message}}}}class RedisManager{static instance=null;store;directClient=null;useDapr;constructor(config){if(RedisManager.instance){this.store=RedisManager.instance.store,this.directClient=RedisManager.instance.directClient,this.useDapr=RedisManager.instance.useDapr;return}if(!config)throw Error("Redis config must be provided for first initialization.");assertRedisConfig(config),this.useDapr=config.withDapr??!1;let keyPrefix=config.keyPrefix||"";if(config.withDapr)this.store=new DaprRedisStore(config.stateStoreName??"statestore",keyPrefix);else{let client=config.url?new Redis(config.url,keyPrefix?{keyPrefix}:{}):new Redis({host:config.host,port:config.port,...config.password?{password:config.password}:{},...config.username?{username:config.username}:{},...config.tls?{tls:{}}:{},...keyPrefix?{keyPrefix}:{}});this.directClient=client,this.store=new DirectRedisStore(client)}RedisManager.instance=this}async create(key,value,ttlSeconds){return this.store.create(key,value,ttlSeconds)}async read(key){return this.store.read(key)}async update(key,value,preserveTtl=!0){return this.store.update(key,value,preserveTtl)}async remove(key){return this.store.remove(key)}async exists(key){return this.store.exists(key)}async readCounters(keys){return(await Promise.all(keys.map((k)=>this.read(k)))).map((r)=>{let v=r.success?r.data:null,n=typeof v==="number"?v:Number.parseFloat(String(v??""));return Number.isFinite(n)?n:0})}async incrementCounter(key,delta,ttlSeconds){if(!this.useDapr&&this.directClient){let v=await this.directClient.incrbyfloat(key,delta);if(ttlSeconds&&ttlSeconds>0)try{await this.directClient.expire(key,ttlSeconds)}catch{}return Number(v)}let cur=await this.read(key),raw=cur.success?cur.data:null,base=typeof raw==="number"?raw:Number.parseFloat(String(raw??"")),next=(Number.isFinite(base)?base:0)+delta;return await this.create(key,next,ttlSeconds),next}getDirectClient(){return this.directClient}async reauthenticate(username,password){if(this.directClient)await this.directClient.auth(username,password)}async keys(pattern){if(this.useDapr||!this.directClient)return logger.scoped("database.redis").warn("keys() not supported in Dapr mode",{pattern}),[];try{return await this.directClient.keys(pattern)}catch(error){return logger.scoped("database.redis").error("keys() failed",error,{pattern}),[]}}async acquireLock(lockKey,ttlSeconds=10){if(this.useDapr||!this.directClient){let existsResult=await this.exists(lockKey);if(!existsResult.success)return{success:!1,error:existsResult.error};if(existsResult.data)return{success:!0,data:!1};if((await this.create(lockKey,"1",ttlSeconds)).success)return{success:!0,data:!0};return{success:!1,error:"Failed to acquire lock"}}try{return{success:!0,data:await this.directClient.set(lockKey,"1","EX",ttlSeconds,"NX")==="OK"}}catch(error){return{success:!1,error:error.message}}}async releaseLock(lockKey){return this.remove(lockKey)}async waitForLock(lockKey,timeoutMs=5000,pollIntervalMs=50){let startTime=Date.now();while(Date.now()-startTime<timeoutMs){let existsResult=await this.exists(lockKey);if(!existsResult.success)return{success:!1,error:existsResult.error};if(!existsResult.data)return{success:!0,data:!0};await new Promise((resolve)=>setTimeout(resolve,pollIntervalMs))}return{success:!0,data:!1}}async getOrWait(key,timeoutMs=5000,pollIntervalMs=50){let startTime=Date.now();while(Date.now()-startTime<timeoutMs){let readResult=await this.read(key);if(!readResult.success)return{success:!1,error:readResult.error};if(readResult.data!==null)return{success:!0,data:readResult.data};await new Promise((resolve)=>setTimeout(resolve,pollIntervalMs))}return{success:!0,data:null}}}var assertRedisConfig=(config)=>{if(!config)throw Error("Redis config must be provided.");if(config.withDapr){if(!config.stateStoreName)throw Error("Dapr mode requires stateStoreName.");return}let hasUrl=Boolean(config.url),hasHostPort=Boolean(config.host)&&typeof config.port==="number";if(!hasUrl&&!hasHostPort)throw Error("Redis config requires either url or host and port.")};var init_Redis=__esm(()=>{init_Logger2();init_Dapr()});var init_Delete=__esm(()=>{init_Redis()});var init_Generate3=__esm(()=>{init_Redis();init_JWT()});var init_Read=__esm(()=>{init_Redis();init_JWT();init_Delete()});var init_Validate2=__esm(()=>{init_Read()});var init_RefreshToken=__esm(()=>{init_Delete();init_Generate3();init_Read();init_Validate2()});var DEFAULT_EXPIRY_SECONDS=86400,buildSessionKey=(sessionId)=>`session:${sessionId}`,serializeSession=(record)=>JSON.stringify(record),deserializeSession=(data)=>{if(!data)return null;if(typeof data==="object")return data;try{return JSON.parse(data)}catch{return null}};var deleteSession=async(options)=>{let manager=new RedisManager,key=buildSessionKey(options.sessionId),removeResult=await manager.remove(key);return removeResult.success&&removeResult.data>0};var init_Delete2=__esm(()=>{init_Redis()});import crypto4 from"crypto";var generateSession=async(options)=>{let manager=new RedisManager,sessionId=options.sessionId??crypto4.randomUUID(),now=Date.now(),expiresIn=(options.expiresInSeconds??DEFAULT_EXPIRY_SECONDS)*1000,nowIso=new Date(now).toISOString(),record={id:sessionId,userId:options.userId,createdAt:nowIso,expiresAt:new Date(now+expiresIn).toISOString(),lastActiveAt:nowIso,clientMeta:options.clientMeta,fingerprintHash:options.fingerprintHash,deviceInfo:options.deviceInfo,refreshTokenHash:options.refreshTokenHash,loginMethod:options.loginMethod,rememberMe:options.rememberMe},ttlSeconds=options.expiresInSeconds??DEFAULT_EXPIRY_SECONDS,writeResult=await manager.create(buildSessionKey(sessionId),serializeSession(record),ttlSeconds);if(!writeResult.success)return{success:!1,error:writeResult.error};return{success:!0,session:record}};var init_Generate4=__esm(()=>{init_Redis()});var init_Issue=__esm(()=>{init_JWT();init_Generate3();init_Delete2();init_Generate4()});var init_Session=__esm(()=>{init_Issue()});var readSession=async(options)=>{let manager=new RedisManager,key=buildSessionKey(options.sessionId),readResult=await manager.read(key);if(!readResult.success||!readResult.data)return null;let record=deserializeSession(readResult.data);if(!record)return null;if(new Date(record.expiresAt).getTime()<=Date.now())return await deleteSession({sessionId:options.sessionId}),null;return record};var init_Read2=__esm(()=>{init_Redis();init_Delete2()});var updateSession=async(options)=>{let existing=await readSession({sessionId:options.sessionId});if(!existing)return{success:!1,error:"Session not found"};let updated={...existing,...options.updates,lastActiveAt:options.updates.lastActiveAt??new Date().toISOString()},manager=new RedisManager,remainingMs=new Date(updated.expiresAt).getTime()-Date.now(),remainingTtlSeconds=Math.max(60,Math.ceil(remainingMs/1000)),writeResult=await manager.create(buildSessionKey(options.sessionId),serializeSession(updated),remainingTtlSeconds);if(!writeResult.success)return{success:!1,error:writeResult.error};return{success:!0,session:updated}},updateLastActiveAt=async(sessionId)=>{return updateSession({sessionId,updates:{lastActiveAt:new Date().toISOString()}})};var init_Update=__esm(()=>{init_Redis();init_Read2()});var validateSession=async(options)=>{let jwtResult=verifyJWT(options.jwtToken,options.jwtSecret);if(!jwtResult.valid)return{isValid:!1,reason:jwtResult.error};let session=await readSession({sessionId:options.sessionId});if(!session)return{isValid:!1,reason:"Session not found"};let fingerprintValid;if(options.savedFingerprint&&options.headers&&options.requestIp){let sanitizedHeaders={};for(let[key,value]of Object.entries(options.headers))if(value!==void 0)sanitizedHeaders[key]=value;let fingerprintResult=validateDeviceFingerprint({savedFingerprint:options.savedFingerprint,headers:sanitizedHeaders,requestIp:options.requestIp});if(fingerprintValid=fingerprintResult.isValid,!fingerprintResult.isValid)return{isValid:!1,reason:fingerprintResult.reason??"Fingerprint mismatch"}}return{isValid:!0,context:{userId:session.userId,sessionId:session.id,fingerprintValid}}};var init_Validate3=__esm(()=>{init_Validate();init_JWT();init_Read2()});var exports_SessionStore={};__export(exports_SessionStore,{validateSession:()=>validateSession,updateSession:()=>updateSession,updateLastActiveAt:()=>updateLastActiveAt,readSession:()=>readSession,generateSession:()=>generateSession,deleteSession:()=>deleteSession});var init_SessionStore=__esm(()=>{init_Delete2();init_Generate4();init_Read2();init_Update();init_Validate3()});var init_Auth=__esm(()=>{init_Fingerprint();init_JWT();init_Password();init_RefreshToken();init_Session();init_SessionStore()});import{eq}from"drizzle-orm";function buildClaimAction(method,entity,field,relation,relationField,isBulk){let parts=[method.toLowerCase()];if(isBulk)parts.push("bulk");if(parts.push(entity),relation){if(parts.push("with"),parts.push(relation),relationField)parts.push(relationField)}else if(field)parts.push(field);return parts.join(".")}function buildClaimPath(entity,isBulk,hasId){if(isBulk)return`/${entity}/bulk`;if(hasId)return`/${entity}/:id`;return`/${entity}`}function generateEntityClaims(entity,config,schemaRelations){let claims=[],tableName=entity.table_name,excludedMethods=entity.excluded_methods||[];for(let method of HTTP_METHODS){if(excludedMethods.includes(method))continue;let needsId=method==="PUT"||method==="PATCH"||method==="DELETE";if(claims.push({action:buildClaimAction(method,tableName),description:`${method} access to ${tableName}`,path:buildClaimPath(tableName,!1,needsId&&method!=="DELETE"),method}),method==="GET"&&entity.columns){for(let column of entity.columns){if(config.skipColumns.includes(column.name))continue;claims.push({action:buildClaimAction(method,tableName,column.name),description:`${method} access to ${tableName}.${column.name}`,path:buildClaimPath(tableName),method})}let relationKey=`${tableName.replace(/_([a-z])/g,(_,l)=>l.toUpperCase())}Relations`;if(schemaRelations[relationKey]){let relationConfig=schemaRelations[relationKey];if(relationConfig?.config?.referencedTable?._?.name){let relationName=relationConfig.config.referencedTable._.name;claims.push({action:buildClaimAction(method,tableName,void 0,relationName),description:`${method} access to ${tableName} with ${relationName}`,path:buildClaimPath(tableName),method})}}}if(method==="POST"||method==="PUT"||method==="PATCH"){if(entity.columns)for(let column of entity.columns){if(config.skipColumns.includes(column.name))continue;claims.push({action:buildClaimAction(method,tableName,column.name),description:`${method} access to ${tableName}.${column.name}`,path:buildClaimPath(tableName,!1,method!=="POST"),method})}}}if(entity.bulk_endpoints_enabled===!0)for(let method of BULK_METHODS){if(excludedMethods.includes(method))continue;claims.push({action:buildClaimAction(method,tableName,void 0,void 0,void 0,!0),description:`Bulk ${method} access to ${tableName}`,path:buildClaimPath(tableName,!0),method})}return claims}async function seedClaims(db,schemaTables,schemaRelations,entities,config,logger2){let claimsTable=schemaTables.claims;if(!claimsTable)return logger2.warn("[Authorization] Claims table not found in schema"),{total:0,created:0,existing:0,claims:[]};let allClaims=[];for(let entity of entities){if(config.skipTables.includes(entity.table_name))continue;let entityClaims=generateEntityClaims(entity,config,schemaRelations);allClaims.push(...entityClaims)}let uniqueClaims=allClaims.filter((claim,index,self2)=>index===self2.findIndex((c)=>c.action===claim.action)),created=0,existing=0,claimActions=[];for(let claim of uniqueClaims)try{if((await db.select().from(claimsTable).where(eq(claimsTable.action,claim.action)).limit(1)).length===0)await db.insert(claimsTable).values(claim),created++,claimActions.push(claim.action),logger2.debug(`[Authorization] Created claim: ${claim.action}`);else existing++}catch(error){logger2.error(`[Authorization] Failed to create claim: ${claim.action}`,error)}return logger2.info(`[Authorization] Claims seeded: ${created} created, ${existing} existing, ${uniqueClaims.length} total`),{total:uniqueClaims.length,created,existing,claims:claimActions}}var HTTP_METHODS,BULK_METHODS;var init_ClaimSeeder=__esm(()=>{HTTP_METHODS=["GET","POST","PUT","PATCH","DELETE"],BULK_METHODS=["POST","PUT","DELETE"]});var exports_ClaimsCache={};__export(exports_ClaimsCache,{ClaimsCache:()=>ClaimsCache});import{eq as eq2}from"drizzle-orm";class ClaimsCache{prefix;redis;db;schemaTables;logger;constructor(config){this.prefix=config.prefix||DEFAULT_PREFIX,this.redis=config.redis,this.db=config.db,this.schemaTables=config.schemaTables,this.logger=config.logger}key(suffix){return`${this.prefix}:${suffix}`}async buildCache(){let rolesTable=this.schemaTables.roles,roleClaimsTable=this.schemaTables.roleClaims,claimsTable=this.schemaTables.claims;if(!rolesTable||!roleClaimsTable||!claimsTable)return this.logger.warn("[ClaimsCache] Required tables not found, skipping cache build"),{version:0,roleCount:0,totalMappings:0};let allRoles=await this.db.select().from(rolesTable),roleNames=[],totalMappings=0;for(let role of allRoles){let r=role,roleId=r.id,roleName=r.name;roleNames.push(roleName);let roleClaimRows=await this.db.select().from(roleClaimsTable).innerJoin(claimsTable,eq2(roleClaimsTable.claimId,claimsTable.id)).where(eq2(roleClaimsTable.roleId,roleId)),claimActions=[];for(let row of roleClaimRows){let action=row.claims?.action;if(action)claimActions.push(action)}await this.redis.set(this.key(`role:${roleName}`),JSON.stringify(claimActions)),totalMappings+=claimActions.length}await this.redis.set(this.key("roles"),JSON.stringify(roleNames));let versionStr=await this.redis.get(this.key("version")),newVersion=(parseInt(versionStr||"0",10)||0)+1;return await this.redis.set(this.key("version"),String(newVersion)),this.logger.info("[ClaimsCache] Cache built",{version:newVersion,roleCount:roleNames.length,totalMappings}),{version:newVersion,roleCount:roleNames.length,totalMappings}}async getVersion(){let v=await this.redis.get(this.key("version"));return parseInt(v||"0",10)||0}async resolveClaimsForRoles(roleNames){let allClaims=new Set;for(let roleName of roleNames){let cached=await this.redis.get(this.key(`role:${roleName}`));if(cached){let claims=JSON.parse(cached);for(let c of claims)allClaims.add(c)}}return Array.from(allClaims)}async invalidate(){return(await this.buildCache()).version}getPrefix(){return this.prefix}}var DEFAULT_PREFIX="nucleus:claims";var init_ClaimsCache=()=>{};var DEFAULT_AUTHORIZATION_CONFIG,AUTHORIZATION_TABLE_KEYS,GODMIN_ROLE_NAME="godmin";var init_types3=__esm(()=>{DEFAULT_AUTHORIZATION_CONFIG={enabled:!1,autoSeedClaims:!0,skipTables:["audit_logs"],skipColumns:["id","created_at","updated_at","is_active","password","version"],excludedPaths:[],publicPaths:["/auth/login","/auth/register"]},AUTHORIZATION_TABLE_KEYS={users:"users",roles:"roles",claims:"claims",userRoles:"userRoles",roleClaims:"roleClaims"}});var{password}=globalThis.Bun;import{and,eq as eq3}from"drizzle-orm";async function setupGodmin(db,schemaTables,config,logger2){if(!config.godminEmail||!config.godminPassword)return logger2.warn("[Authorization] Godmin email or password not configured, skipping godmin setup"),{success:!1};let{roles:rolesTable,users:usersTable,userRoles:userRolesTable}=schemaTables;if(!rolesTable||!usersTable||!userRolesTable)return logger2.error("[Authorization] Required tables not found for godmin setup"),{success:!1};try{let roleId,existingRole=await db.select().from(rolesTable).where(eq3(rolesTable.name,GODMIN_ROLE_NAME)).limit(1);if(existingRole.length===0){let[newRole]=await db.insert(rolesTable).values({name:GODMIN_ROLE_NAME,description:"God mode administrator - bypasses all authorization checks"}).returning();roleId=newRole.id,logger2.info(`[Authorization] Created godmin role: ${roleId}`)}else roleId=existingRole[0].id,logger2.debug(`[Authorization] Godmin role already exists: ${roleId}`);let userId,existingUser=await db.select().from(usersTable).where(eq3(usersTable.email,config.godminEmail)).limit(1);if(existingUser.length===0){let hashedPassword=await password.hash(config.godminPassword,{algorithm:"bcrypt",cost:10}),[newUser]=await db.insert(usersTable).values({email:config.godminEmail,password:hashedPassword,verifiedAt:new Date,isActive:!0,isGod:!0}).returning();userId=newUser.id,logger2.info(`[Authorization] Created godmin user: ${userId}`)}else{if(userId=existingUser[0].id,!existingUser[0].isGod)await db.update(usersTable).set({isGod:!0}).where(eq3(usersTable.id,userId)),logger2.info(`[Authorization] Marked existing godmin user as isGod=true: ${userId}`);logger2.debug(`[Authorization] Godmin user already exists: ${userId}`)}if(!((await db.select().from(userRolesTable).where(and(eq3(userRolesTable.userId,userId),eq3(userRolesTable.roleId,roleId))).limit(1)).length>0))await db.insert(userRolesTable).values({userId,roleId}),logger2.info(`[Authorization] Assigned godmin role to user: ${userId}`);return{success:!0,userId,roleId}}catch(error){return logger2.error("[Authorization] Failed to setup godmin",error),{success:!1}}}function isGodminRole(roleName){return roleName===GODMIN_ROLE_NAME}var init_GodminSetup=__esm(()=>{init_types3()});import{eq as eq4,inArray,sql}from"drizzle-orm";function isSelfReference(value){return value.startsWith(SELF_PREFIX)}function parseSelfReference(value){return{field:value.slice(SELF_PREFIX.length)}}function parseScopeWithSelf(scope){if(!scope)return{};let params=new URLSearchParams(scope),result={};for(let[key,value]of params.entries())if(isSelfReference(value))result[key]=parseSelfReference(value);else result[key]=value;return result}function resolveScopeWithSelf(parsedScope,userData,logger2){let resolved={},unresolved=[];for(let[key,value]of Object.entries(parsedScope))if(typeof value==="object"&&"field"in value){if(!userData){logger2.warn(`[Authorization] Cannot resolve self:${value.field} - userData not provided`),unresolved.push(key);continue}let lookup=lookupUserDataField(userData,value.field);if(!lookup.found){logger2.warn(`[Authorization] Cannot resolve self:${value.field} - field not found in userData`),unresolved.push(key);continue}resolved[key]=lookup.value,logger2.debug(`[Authorization] Resolved self:${value.field} -> ${String(lookup.value)}`)}else resolved[key]=value;return{resolved,unresolved}}function resolveClaimScopes(rows,userData,logger2){let claimScopes={},dropped=new Set;for(let{action,scope}of rows){if(!scope)continue;if(!scope.includes("="))continue;let parsed=parseScopeWithSelf(scope),{resolved,unresolved}=resolveScopeWithSelf(parsed,userData,logger2);if(unresolved.length>0){dropped.add(action);continue}claimScopes[action]={...claimScopes[action]??{},...resolved}}for(let a of dropped)delete claimScopes[a];return{claimScopes,dropped:Array.from(dropped)}}function mergeGrantingScopes(grantingActions,claimScopes){if(!claimScopes)return;let merged={},any=!1;for(let action of grantingActions){let s=claimScopes[action];if(s&&Object.keys(s).length>0)Object.assign(merged,s),any=!0}return any?merged:void 0}function buildClaimPattern(method,entity,field,relation){let parts=[method.toLowerCase(),entity];if(relation)parts.push("with",relation);else if(field)parts.push(field);return parts.join(".")}function claimMatches(userClaim,requiredPattern,requireSpecificity=!1){if(userClaim===requiredPattern)return!0;let userParts=userClaim.split("."),requiredParts=requiredPattern.split(".");if(userParts.length>requiredParts.length)return!1;if(requireSpecificity&&userParts.length<2&&requiredParts.length>=2)return!1;for(let i=0;i<userParts.length;i++)if(userParts[i]!==requiredParts[i])return!1;return!0}async function checkAuthorization(params){let{userId,method,entity,requestedFields,requestedRelations,db,schemaTables,logger:logger2,getUserData}=params,reqSpec=params.requireClaimSpecificity??!1,userData=params.userData,ensureUserData=async()=>{if(userData!==void 0)return;if(getUserData)try{userData=await getUserData()}catch(err){logger2.warn("[Authorization] getUserData callback failed",{userId,error:err instanceof Error?err.message:String(err)})}},rolesTable=schemaTables[AUTHORIZATION_TABLE_KEYS.roles],userRolesTable=schemaTables[AUTHORIZATION_TABLE_KEYS.userRoles],roleClaimsTable=schemaTables[AUTHORIZATION_TABLE_KEYS.roleClaims],claimsTable=schemaTables[AUTHORIZATION_TABLE_KEYS.claims];if(!rolesTable||!userRolesTable||!roleClaimsTable||!claimsTable)return logger2.error("[Authorization] Required tables not found"),{authorized:!1,reason:"Authorization tables not configured"};try{let userRolesCols=userRolesTable,rolesCols=rolesTable,userRoles=await db.select({roleId:userRolesCols.roleId,roleName:rolesCols.name}).from(userRolesTable).innerJoin(rolesTable,eq4(userRolesCols.roleId,rolesCols.id)).where(eq4(userRolesCols.userId,userId));if(userRoles.length===0)return{authorized:!1,reason:"User has no roles assigned"};if(userRoles.some((ur)=>isGodminRole(ur.roleName)))return logger2.debug(`[Authorization] User ${userId} has godmin role, bypassing checks`),{authorized:!0};let roleIds=userRoles.map((ur)=>ur.roleId),roleClaimsCols=roleClaimsTable,claimsCols=claimsTable,roleClaims=await db.select({claimAction:claimsCols.action,scope:roleClaimsCols.scope}).from(roleClaimsTable).innerJoin(claimsTable,eq4(roleClaimsCols.claimId,claimsCols.id)).where(inArray(roleClaimsCols.roleId,roleIds));if(roleClaims.length===0)return{authorized:!1,reason:"User roles have no claims assigned"};let entityClaimPattern=buildClaimPattern(method,entity),hasEntityAccess=roleClaims.some((rc)=>claimMatches(rc.claimAction,entityClaimPattern,reqSpec)),allowedFields=[],allowedRelations=[],scopeFilters={},unresolvedSelf=[],fieldPatterns=(requestedFields??[]).map((field)=>({field,pattern:buildClaimPattern(method,entity,field)})),relationPatterns=(requestedRelations??[]).map((relation)=>({relation,pattern:buildClaimPattern(method,entity,void 0,relation)})),claimCouldGrant=(action)=>claimMatches(action,entityClaimPattern,reqSpec)||fieldPatterns.some((f)=>claimMatches(action,f.pattern,reqSpec))||relationPatterns.some((r)=>claimMatches(action,r.pattern,reqSpec));if(roleClaims.some((rc)=>{let scope=rc.scope;return!!scope&&scope.includes("self:")&&claimCouldGrant(rc.claimAction)}))await ensureUserData();let applyClaimScope=(rc)=>{let parsedScope=parseScopeWithSelf(rc.scope),{resolved,unresolved}=resolveScopeWithSelf(parsedScope,userData,logger2);Object.assign(scopeFilters,resolved),unresolvedSelf.push(...unresolved)},denyOnUnresolvedSelf=()=>{if(unresolvedSelf.length===0)return null;return logger2.warn("[Authorization] Denying request: unresolvable self: scope (failing closed)",{userId,method,entity,unresolved:unresolvedSelf}),{authorized:!1,reason:"Ownership scope could not be resolved"}};if(hasEntityAccess){for(let rc of roleClaims)if(claimMatches(rc.claimAction,entityClaimPattern,reqSpec))applyClaimScope(rc);let denied2=denyOnUnresolvedSelf();if(denied2)return denied2;return{authorized:!0,scopeFilters:Object.keys(scopeFilters).length>0?scopeFilters:void 0}}for(let{field,pattern}of fieldPatterns){let granting=roleClaims.filter((rc)=>claimMatches(rc.claimAction,pattern,reqSpec));if(granting.length>0){allowedFields.push(field);for(let rc of granting)applyClaimScope(rc)}}for(let{relation,pattern}of relationPatterns){let granting=roleClaims.filter((rc)=>claimMatches(rc.claimAction,pattern,reqSpec));if(granting.length>0){allowedRelations.push(relation);for(let rc of granting)applyClaimScope(rc)}}let denied=denyOnUnresolvedSelf();if(denied)return denied;if(!(allowedFields.length>0||allowedRelations.length>0))return{authorized:!1,reason:`No access to ${method} ${entity}`};return{authorized:!0,allowedFields:allowedFields.length>0?allowedFields:["id"],allowedRelations,scopeFilters:Object.keys(scopeFilters).length>0?scopeFilters:void 0}}catch(error){return logger2.error("[Authorization] Check failed",error),{authorized:!1,reason:"Authorization check failed"}}}function checkAuthorizationFromJWT(params){let{userClaims,userRoles,method,entity,requestedFields,requestedRelations,logger:logger2}=params,reqSpec=params.requireClaimSpecificity??!1,claimScopes=params.claimScopes;if(userClaims.length===0&&userRoles.length===0)return{authorized:!1,reason:"No roles or claims in token"};if(userRoles.some((r)=>isGodminRole(r)))return logger2.debug("[Authorization:JWT] User has godmin role, bypassing checks"),{authorized:!0};let entityClaimPattern=buildClaimPattern(method,entity),entityGranting=userClaims.filter((c)=>claimMatches(c,entityClaimPattern,reqSpec));if(entityGranting.length>0){let scopeFilters2=mergeGrantingScopes(entityGranting,claimScopes);return{authorized:!0,...scopeFilters2?{scopeFilters:scopeFilters2}:{}}}let allowedFields=[],allowedRelations=[],grantingActions=[];if(requestedFields)for(let field of requestedFields){let fieldPattern=buildClaimPattern(method,entity,field),granting=userClaims.filter((c)=>claimMatches(c,fieldPattern,reqSpec));if(granting.length>0)allowedFields.push(field),grantingActions.push(...granting)}if(requestedRelations)for(let relation of requestedRelations){let relationPattern=buildClaimPattern(method,entity,void 0,relation),granting=userClaims.filter((c)=>claimMatches(c,relationPattern,reqSpec));if(granting.length>0)allowedRelations.push(relation),grantingActions.push(...granting)}if(!(allowedFields.length>0||allowedRelations.length>0))return{authorized:!1,reason:`No access to ${method} ${entity}`};let scopeFilters=mergeGrantingScopes(grantingActions,claimScopes);return{authorized:!0,allowedFields:allowedFields.length>0?allowedFields:["id"],allowedRelations,...scopeFilters?{scopeFilters}:{}}}async function checkAuthorizationViaIDP(params){let{idpUrl,accessToken,method,entity,requestedFields,requestedRelations,logger:logger2}=params;try{let response=await fetch(`${idpUrl}/auth/check`,{method:"POST",headers:{"Content-Type":"application/json",Cookie:`access_token=${accessToken}`},body:JSON.stringify({entity,method,fields:requestedFields,relations:requestedRelations})});if(!response.ok)return logger2.warn(`[Authorization:IDP] IDP /auth/check returned ${response.status}`),{authorized:!1,reason:`IDP authorization check failed (${response.status})`};let payload=await response.json();return unwrapIdpCheckResponse(payload)}catch(error){let msg=error instanceof Error?error.message:String(error);return logger2.error(`[Authorization:IDP] Failed to reach IDP: ${msg}`),{authorized:!1,reason:"IDP authorization service unavailable"}}}function filterResponseFields(data,allowedFields){if(!allowedFields||allowedFields.length===0)return data;let fieldsToInclude=[...new Set([...["id"],...allowedFields])],filterSingle=(item)=>{let filtered={};for(let field of fieldsToInclude)if(field in item)filtered[field]=item[field];return filtered};if(Array.isArray(data))return data.map(filterSingle);return filterSingle(data)}function filterResponseRelations(data,allowedRelations){if(!allowedRelations)return data;let filterSingle=(item)=>{let filtered={...item};for(let key of Object.keys(filtered))if(typeof filtered[key]==="object"&&filtered[key]!==null&&!allowedRelations.includes(key))delete filtered[key];return filtered};if(Array.isArray(data))return data.map(filterSingle);return filterSingle(data)}function buildScopeConditions(scopeFilters,resolveColumn){let conditions=[],unresolvedFields=[];if(!scopeFilters)return{conditions,unresolvedFields};for(let[field,value]of Object.entries(scopeFilters)){let col=resolveColumn(field);if(col)conditions.push(eq4(col,value));else unresolvedFields.push(field),conditions.push(sql`1 = 0`)}return{conditions,unresolvedFields}}var SELF_PREFIX="self:",toCamelCase2=(value)=>value.replace(/_([a-z])/g,(_,c)=>c.toUpperCase()),toSnakeCase=(value)=>value.replace(/([A-Z])/g,(_,c)=>`_${c.toLowerCase()}`),lookupUserDataField=(userData,fieldName)=>{if(fieldName in userData)return{found:!0,value:userData[fieldName]};let camel=toCamelCase2(fieldName);if(camel!==fieldName&&camel in userData)return{found:!0,value:userData[camel]};let snake=toSnakeCase(fieldName);if(snake!==fieldName&&snake in userData)return{found:!0,value:userData[snake]};return{found:!1}},unwrapIdpCheckResponse=(payload)=>{if(!payload||typeof payload!=="object")return{authorized:!1,reason:"IDP returned malformed response"};let envelope=payload;if(envelope.data&&typeof envelope.data==="object"){let data=envelope.data;if(typeof data.authorized==="boolean")return data}let flat=payload;if(typeof flat.authorized==="boolean")return flat;return{authorized:!1,reason:"IDP returned unrecognised response shape"}};var init_Middleware=__esm(()=>{init_GodminSetup();init_types3()});var exports_SeedRunner={};__export(exports_SeedRunner,{runSeed:()=>runSeed,expandClaimPatterns:()=>expandClaimPatterns});import{and as and2,eq as eq5}from"drizzle-orm";function expandClaimPatterns(patterns,allActions){let out=new Set;for(let pattern of patterns)if(pattern.endsWith(".*")){let prefix=pattern.slice(0,-2);for(let action of allActions)if(action===prefix||action.startsWith(`${prefix}.`))out.add(action)}else out.add(pattern);return[...out]}async function runSeed(db,schemaTables,seedConfig,logger2){let{roles:rolesTable,claims:claimsTable,roleClaims:roleClaimsTable}=schemaTables,result={rolesCreated:0,rolesExisting:0,claimsCreated:0,claimsExisting:0,assignmentsCreated:0,assignmentsExisting:0,assignmentsUpdated:0};if(seedConfig.roles?.length&&rolesTable)for(let roleDef of seedConfig.roles)try{if((await db.select().from(rolesTable).where(eq5(rolesTable.name,roleDef.name)).limit(1)).length===0)await db.insert(rolesTable).values({name:roleDef.name,description:roleDef.description||""}),result.rolesCreated++,logger2.info(`[Seed] Created role: ${roleDef.name}`);else result.rolesExisting++}catch(error){logger2.error(`[Seed] Failed to seed role: ${roleDef.name}`,error)}if(seedConfig.claims?.length&&claimsTable)for(let claimDef of seedConfig.claims)try{let existing=await db.select().from(claimsTable).where(eq5(claimsTable.action,claimDef.action)).limit(1);if(existing.length===0)await db.insert(claimsTable).values({action:claimDef.action,path:claimDef.path,method:claimDef.method,description:claimDef.description||`${claimDef.method} ${claimDef.path}`,...claimDef.policy!==void 0?{policy:claimDef.policy}:{}}),result.claimsCreated++,logger2.info(`[Seed] Created claim: ${claimDef.action}`);else if(claimDef.policy!==void 0){let existingRow=existing[0],currentPolicy=JSON.stringify(existingRow.policy??null),desiredPolicy=JSON.stringify(claimDef.policy??null);if(currentPolicy!==desiredPolicy)await db.update(claimsTable).set({policy:claimDef.policy}).where(eq5(claimsTable.action,claimDef.action)),result.claimsExisting++,logger2.warn(`[Seed] Reconciled policy for claim: ${claimDef.action}`);else result.claimsExisting++}else result.claimsExisting++}catch(error){logger2.error(`[Seed] Failed to seed claim: ${claimDef.action}`,error)}if(seedConfig.roleClaimAssignments?.length&&rolesTable&&claimsTable&&roleClaimsTable){let allClaimActions=(await db.select().from(claimsTable)).map((c)=>String(c.action??""));for(let assignment of seedConfig.roleClaimAssignments){let role=(await db.select().from(rolesTable).where(eq5(rolesTable.name,assignment.role)).limit(1))[0];if(!role){logger2.warn(`[Seed] Role not found for assignment: ${assignment.role}`);continue}let roleId=role.id,resolvedActions=expandClaimPatterns(assignment.claims,allClaimActions);for(let pattern of assignment.claims)if(pattern.endsWith(".*")&&!resolvedActions.some((a)=>a.startsWith(pattern.slice(0,-1))))logger2.warn(`[Seed] No claim matched prefix pattern: ${pattern}`);for(let claimAction of resolvedActions)try{let claim=(await db.select().from(claimsTable).where(eq5(claimsTable.action,claimAction)).limit(1))[0];if(!claim){logger2.warn(`[Seed] Claim not found for assignment: ${claimAction}`);continue}let claimId=claim.id,existingAssignment=await db.select().from(roleClaimsTable).where(and2(eq5(roleClaimsTable.roleId,roleId),eq5(roleClaimsTable.claimId,claimId))).limit(1);if(existingAssignment.length===0)await db.insert(roleClaimsTable).values({roleId,claimId,scope:assignment.scope||null}),result.assignmentsCreated++;else{let existingRow=existingAssignment[0],desiredScope=assignment.scope||null,currentScope=existingRow.scope??null;if(currentScope!==desiredScope)await db.update(roleClaimsTable).set({scope:desiredScope}).where(and2(eq5(roleClaimsTable.roleId,roleId),eq5(roleClaimsTable.claimId,claimId))),result.assignmentsUpdated++,logger2.warn(`[Seed] Reconciled scope for ${assignment.role} -> ${claimAction}: ${JSON.stringify(currentScope)} => ${JSON.stringify(desiredScope)}`);else result.assignmentsExisting++}}catch(error){logger2.error(`[Seed] Failed to assign claim ${claimAction} to role ${assignment.role}`,error)}if(result.assignmentsCreated>0)logger2.info(`[Seed] Role "${assignment.role}": assigned ${result.assignmentsCreated} claims`)}}return result}var init_SeedRunner=()=>{};var init_Authorization=__esm(()=>{init_ClaimSeeder();init_ClaimsCache();init_GodminSetup();init_Middleware();init_SeedRunner();init_types3()});import{createCipheriv,createDecipheriv,randomBytes as randomBytes2,scryptSync}from"crypto";var MAGIC,IV_LEN=12,TAG_LEN=16,deriveKey=(secret)=>scryptSync(secret,"nucleus-backup-v1",32),encryptBackup=(plaintext,secret)=>{if(!secret)throw Error("backup encryption key is empty");let key=deriveKey(secret),iv=randomBytes2(IV_LEN),cipher=createCipheriv("aes-256-gcm",key,iv),ciphertext=Buffer.concat([cipher.update(plaintext,"utf-8"),cipher.final()]),tag=cipher.getAuthTag();return Buffer.concat([MAGIC,iv,tag,ciphertext])},isEncryptedBackup=(buf)=>buf.length>=MAGIC.length+IV_LEN+TAG_LEN&&buf.subarray(0,MAGIC.length).equals(MAGIC),decryptBackup=(blob,secret)=>{if(!secret)throw Error("backup encryption key is empty");if(!isEncryptedBackup(blob))throw Error("not an encrypted backup");let key=deriveKey(secret),iv=blob.subarray(MAGIC.length,MAGIC.length+IV_LEN),tag=blob.subarray(MAGIC.length+IV_LEN,MAGIC.length+IV_LEN+TAG_LEN),ciphertext=blob.subarray(MAGIC.length+IV_LEN+TAG_LEN),decipher=createDecipheriv("aes-256-gcm",key,iv);return decipher.setAuthTag(tag),Buffer.concat([decipher.update(ciphertext),decipher.final()]).toString("utf-8")};var init_encryption=__esm(()=>{MAGIC=Buffer.from("NXB1")});import{mkdir,readFile,stat,unlink,writeFile}from"fs/promises";import{join}from"path";import{eq as eq6,sql as sql2}from"drizzle-orm";class BackupService{db;logger;config;schemaTables;schemaName;backupLogsTable;cronTimer=null;schedulerActive=!1;constructor(serviceConfig){this.db=serviceConfig.db,this.logger=serviceConfig.logger,this.config=serviceConfig.config,this.schemaTables=serviceConfig.schemaTables,this.schemaName=serviceConfig.schemaName,this.backupLogsTable=serviceConfig.backupLogsTable}async createBackup(trigger="manual",performedBy,targetSchemaName,targetSchemaTables){let resolvedSchema=targetSchemaName||this.schemaName,resolvedTables=targetSchemaTables||this.schemaTables,now=new Date,backupId=crypto.randomUUID(),timestamp=now.toISOString().replace(/[:.]/g,"-"),backupName=`${resolvedSchema}_${timestamp}`,fileName=`${backupName}.json`,filePath=join(this.config.storagePath,fileName),logRecord={id:backupId,backupName,fileName,schemaName:resolvedSchema,format:this.config.format,status:"running",trigger,sizeBytes:null,tableCount:null,rowCount:null,includedTables:[],excludedTables:this.config.excludeTables,errorMessage:null,startedAt:now.toISOString(),completedAt:null,performedBy:performedBy||null,cronExpression:trigger==="scheduled"?this.config.schedule.cron:null,retentionDays:this.config.schedule.retentionDays};await this.insertLogRecord(logRecord);try{await mkdir(this.config.storagePath,{recursive:!0});let tableNames=this.getBackupTableNames(resolvedTables),backupData=[],totalRows=0;for(let tableName of tableNames){let table=resolvedTables[tableName];if(!table)continue;try{let rows=await this.db.select().from(table),columns=Object.keys(table).filter((k)=>!k.startsWith("_")&&typeof table[k]!=="function");backupData.push({tableName,columns,rows}),totalRows+=rows.length}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to export table ${tableName}: ${msg}`)}}let backupFile={manifest:{version:"1.0",createdAt:now.toISOString(),schemaName:resolvedSchema,format:this.config.format,tables:backupData.map((t)=>({tableName:t.tableName,rowCount:t.rows.length,columns:t.columns})),totalRows},data:backupData},jsonContent=JSON.stringify(backupFile,null,2);if(this.config.encryptionKey)await writeFile(filePath,encryptBackup(jsonContent,this.config.encryptionKey));else await writeFile(filePath,jsonContent,"utf-8");let fileStats=await stat(filePath);return logRecord.status="completed",logRecord.completedAt=new Date().toISOString(),logRecord.tableCount=backupData.length,logRecord.rowCount=totalRows,logRecord.sizeBytes=fileStats.size,logRecord.includedTables=tableNames,await this.updateLogRecord(logRecord),this.logger.info("[Backup] Backup completed",{backupId,schemaName:resolvedSchema,tables:backupData.length,rows:totalRows,sizeBytes:fileStats.size}),await this.enforceMaxBackups(),logRecord}catch(err){let msg=err instanceof Error?err.message:String(err);return logRecord.status="failed",logRecord.errorMessage=msg,logRecord.completedAt=new Date().toISOString(),await this.updateLogRecord(logRecord),this.logger.error("[Backup] Backup failed",err,{backupId,schemaName:resolvedSchema}),logRecord}}async restoreFromBackup(backupId,performedBy,targetSchemaName,targetSchemaTables){if(!this.config.allowRestore)return{success:!1,message:"Restore is disabled in configuration"};let resolvedTables=targetSchemaTables||this.schemaTables,logRecord=await this.getLogRecord(backupId);if(!logRecord)return{success:!1,message:"Backup not found"};if(logRecord.status!=="completed")return{success:!1,message:`Cannot restore from backup with status: ${logRecord.status}`};let filePath=join(this.config.storagePath,logRecord.fileName);try{let raw=await readFile(filePath),content;if(isEncryptedBackup(raw)){if(!this.config.encryptionKey)return{success:!1,message:"Backup is encrypted but no encryption key is configured"};content=decryptBackup(raw,this.config.encryptionKey)}else content=raw.toString("utf-8");let backupFile=JSON.parse(content);await this.createBackup("pre_restore",performedBy,targetSchemaName,targetSchemaTables);let tablesRestored=0,rowsRestored=0;return await this.db.transaction(async(tx)=>{await tx.execute(sql2`SET CONSTRAINTS ALL DEFERRED`);for(let tableData of backupFile.data){let table=resolvedTables[tableData.tableName];if(!table){this.logger.warn(`[Backup] Skipping restore for ${tableData.tableName}: table not found in schema`);continue}if(tableData.rows.length===0)continue;await tx.delete(table);let chunkSize=500;for(let i=0;i<tableData.rows.length;i+=chunkSize){let chunk=tableData.rows.slice(i,i+chunkSize);await tx.insert(table).values(chunk)}tablesRestored++,rowsRestored+=tableData.rows.length}}),logRecord.status="restored",await this.updateLogRecord(logRecord),this.logger.info("[Backup] Restore completed",{backupId,tablesRestored,rowsRestored}),{success:!0,message:`Restored ${tablesRestored} tables with ${rowsRestored} rows`,tablesRestored,rowsRestored}}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.error("[Backup] Restore failed",err,{backupId}),{success:!1,message:`Restore failed: ${msg}`}}}async listBackups(){if(!this.backupLogsTable)return[];return await this.db.select().from(this.backupLogsTable).orderBy(sql2`created_at DESC`).limit(100)}async getBackupFilePath(backupId){let record=await this.getLogRecord(backupId);if(!record)return null;return join(this.config.storagePath,record.fileName)}async deleteBackup(backupId){let record=await this.getLogRecord(backupId);if(!record)return!1;let filePath=join(this.config.storagePath,record.fileName);try{await unlink(filePath)}catch{}if(this.backupLogsTable)await this.db.delete(this.backupLogsTable).where(eq6(col(this.backupLogsTable,"id"),backupId));return!0}startScheduler(){if(!this.config.schedule.enabled||!this.config.schedule.cron)return;this.logger.info("[Backup] Scheduler started",{cron:this.config.schedule.cron,retentionDays:this.config.schedule.retentionDays}),this.schedulerActive=!0,this.scheduleNextRun()}scheduleNextRun(){if(!this.schedulerActive)return;let delayMs=this.getNextDelayMs(this.config.schedule.cron);this.logger.debug?.("[Backup] Next scheduled backup",{inMs:delayMs}),this.cronTimer=setTimeout(async()=>{try{this.logger.info("[Backup] Scheduled backup starting..."),await this.createBackup("scheduled"),await this.cleanupExpiredBackups()}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.error("[Backup] Scheduled backup failed",{error:msg})}finally{this.scheduleNextRun()}},delayMs)}stopScheduler(){if(this.schedulerActive=!1,this.cronTimer)clearTimeout(this.cronTimer),this.cronTimer=null,this.logger.info("[Backup] Scheduler stopped")}getBackupTableNames(tables){return Object.keys(tables).filter((name)=>{if(this.config.excludeTables.includes(name))return!1;let val=tables[name];if(!val||typeof val!=="object")return!1;return Object.getOwnPropertySymbols(val).length>0})}async insertLogRecord(record){if(!this.backupLogsTable)return;try{await this.db.insert(this.backupLogsTable).values({id:record.id,backupName:record.backupName,fileName:record.fileName,schemaName:record.schemaName,format:record.format,status:record.status,trigger:record.trigger,sizeBytes:record.sizeBytes,tableCount:record.tableCount,rowCount:record.rowCount,includedTables:JSON.stringify(record.includedTables),excludedTables:JSON.stringify(record.excludedTables),errorMessage:record.errorMessage,startedAt:record.startedAt?new Date(record.startedAt):null,completedAt:record.completedAt?new Date(record.completedAt):null,performedBy:record.performedBy,cronExpression:record.cronExpression,retentionDays:record.retentionDays,createdAt:new Date,updatedAt:new Date})}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to insert backup log: ${msg}`)}}async updateLogRecord(record){if(!this.backupLogsTable)return;try{await this.db.update(this.backupLogsTable).set({status:record.status,sizeBytes:record.sizeBytes,tableCount:record.tableCount,rowCount:record.rowCount,includedTables:JSON.stringify(record.includedTables),errorMessage:record.errorMessage,completedAt:record.completedAt?new Date(record.completedAt):null,updatedAt:new Date}).where(eq6(col(this.backupLogsTable,"id"),record.id))}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to update backup log: ${msg}`)}}async getLogRecord(backupId){if(!this.backupLogsTable)return null;return(await this.db.select().from(this.backupLogsTable).where(eq6(col(this.backupLogsTable,"id"),backupId)).limit(1))[0]||null}async enforceMaxBackups(){if(!this.backupLogsTable)return;let allBackups=await this.db.select().from(this.backupLogsTable).where(eq6(col(this.backupLogsTable,"status"),"completed")).orderBy(sql2`created_at DESC`);if(allBackups.length>this.config.maxBackups){let toDelete=allBackups.slice(this.config.maxBackups);for(let backup of toDelete){let b=backup;await this.deleteBackup(b.id)}this.logger.info("[Backup] Old backups cleaned up",{deleted:toDelete.length})}}async cleanupExpiredBackups(){if(!this.backupLogsTable||!this.config.schedule.retentionDays)return;let cutoff=new Date;cutoff.setDate(cutoff.getDate()-this.config.schedule.retentionDays);let{lt}=await import("drizzle-orm"),expired=await this.db.select().from(this.backupLogsTable).where(lt(col(this.backupLogsTable,"createdAt"),cutoff));for(let backup of expired){let b=backup;await this.deleteBackup(b.id)}if(expired.length>0)this.logger.info("[Backup] Expired backups cleaned up",{deleted:expired.length,retentionDays:this.config.schedule.retentionDays})}getNextDelayMs(cron){let parts=cron.trim().split(/\s+/);if(parts.length!==5)return 86400000;let[min,hour]=parts;if(hour?.startsWith("*/")){let h2=Number.parseInt(hour.slice(2),10);return Number.isFinite(h2)&&h2>0?h2*60*60*1000:86400000}if(min?.startsWith("*/")){let m2=Number.parseInt(min.slice(2),10);return Number.isFinite(m2)&&m2>0?m2*60*1000:3600000}let m=Number.parseInt(min??"",10),h=Number.parseInt(hour??"",10);if(Number.isFinite(m)&&m>=0&&m<60&&Number.isFinite(h)&&h>=0&&h<24){let now=new Date,next=new Date(now);if(next.setHours(h,m,0,0),next.getTime()<=now.getTime())next.setDate(next.getDate()+1);return next.getTime()-now.getTime()}return 86400000}}var col=(table,name)=>table[name];var init_BackupService=__esm(()=>{init_encryption()});var init_Backup=__esm(()=>{init_BackupService()});function parseTimeToSeconds(time){let match=time.match(/^(\d+)(s|m|h|d)$/);if(!match||!match[1]||!match[2])return 300;let value=Number.parseInt(match[1],10);switch(match[2]){case"s":return value;case"m":return value*60;case"h":return value*3600;case"d":return value*86400;default:return 300}}function generateSecureId(){let bytes=new Uint8Array(24);return crypto.getRandomValues(bytes),Array.from(bytes).map((b)=>b.toString(16).padStart(2,"0")).join("")}function hashAnswer(answer){let hasher=new Bun.CryptoHasher("sha256");return hasher.update(answer),hasher.digest("hex")}function timingSafeEqual(a,b){if(a.length!==b.length){let dummy=new Uint8Array(32);return crypto.getRandomValues(dummy),!1}let encoder=new TextEncoder,bufA=encoder.encode(a),bufB=encoder.encode(b),result=0;for(let i=0;i<bufA.length;i++)result|=(bufA[i]??0)^(bufB[i]??0);return result===0}function getSecureRandomInt(min,max){let range=max-min+1,bytesNeeded=Math.ceil(Math.log2(range)/8)||1,maxValue=256**bytesNeeded,limit=maxValue-maxValue%range,randomValue,bytes=new Uint8Array(bytesNeeded);do crypto.getRandomValues(bytes),randomValue=bytes.reduce((acc,byte,i)=>acc+byte*256**i,0);while(randomValue>=limit);return min+randomValue%range}function generateMathChallenge(difficulty){let config=DIFFICULTY_CONFIG[difficulty],{min,max}=config.mathRange,operations=["+","-","\xD7"],operation=operations[getSecureRandomInt(0,operations.length-1)],num1=getSecureRandomInt(min,max),num2=getSecureRandomInt(min,max),answer;switch(operation){case"+":answer=num1+num2;break;case"-":if(num1<num2)[num1,num2]=[num2,num1];answer=num1-num2;break;case"\xD7":num1=getSecureRandomInt(1,12),num2=getSecureRandomInt(1,12),answer=num1*num2;break;default:answer=num1+num2}return{question:`${num1} ${operation} ${num2} = ?`,answer:answer.toString()}}function generateTextChallenge(difficulty){let config=DIFFICULTY_CONFIG[difficulty],text="";for(let i=0;i<config.textLength;i++)text+="ABCDEFGHJKLMNPQRSTUVWXYZ23456789".charAt(getSecureRandomInt(0,31));return{question:text,answer:text}}function generateImageChallenge(difficulty){let textChallenge=generateTextChallenge(difficulty),width=200,height=60,svgContent=generateCaptchaSVG(textChallenge.answer,200,60),imageData=`data:image/svg+xml;base64,${Buffer.from(svgContent).toString("base64")}`;return{question:"Enter the text shown in the image",answer:textChallenge.answer,imageData}}function getSecureFloat(){let bytes=new Uint32Array(1);return crypto.getRandomValues(bytes),(bytes[0]??0)/4294967295}function generateCaptchaSVG(text,width,height){let bgR=240+getSecureFloat()*15,bgG=240+getSecureFloat()*15,bgB=240+getSecureFloat()*15,bgColor=`rgb(${bgR}, ${bgG}, ${bgB})`,noiseLines="";for(let i=0;i<12;i++){let x1=getSecureFloat()*width,y1=getSecureFloat()*height,x2=getSecureFloat()*width,y2=getSecureFloat()*height,r=getSecureFloat()*100+100,g=getSecureFloat()*100+100,b=getSecureFloat()*100+100,strokeWidth=1+getSecureFloat()*2;noiseLines+=`<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="rgb(${r},${g},${b})" stroke-width="${strokeWidth}"/>`}let noiseCurves="";for(let i=0;i<4;i++){let startX2=getSecureFloat()*width,startY=getSecureFloat()*height,cp1X=getSecureFloat()*width,cp1Y=getSecureFloat()*height,cp2X=getSecureFloat()*width,cp2Y=getSecureFloat()*height,endX=getSecureFloat()*width,endY=getSecureFloat()*height,r=getSecureFloat()*80+80,g=getSecureFloat()*80+80,b=getSecureFloat()*80+80;noiseCurves+=`<path d="M${startX2},${startY} C${cp1X},${cp1Y} ${cp2X},${cp2Y} ${endX},${endY}" stroke="rgb(${r},${g},${b})" stroke-width="2" fill="none"/>`}let noiseDots="";for(let i=0;i<80;i++){let x=getSecureFloat()*width,y=getSecureFloat()*height,r=getSecureFloat()*150+50,g=getSecureFloat()*150+50,b=getSecureFloat()*150+50,radius=getSecureFloat()*3+1;noiseDots+=`<circle cx="${x}" cy="${y}" r="${radius}" fill="rgb(${r},${g},${b})"/>`}let textElements="",charWidth=width/(text.length+2),startX=charWidth;for(let i=0;i<text.length;i++){let x=startX+i*charWidth+(getSecureFloat()-0.5)*15,y=height/2+8+(getSecureFloat()-0.5)*12,rotation=(getSecureFloat()-0.5)*40,fontSize=22+getSecureFloat()*10,r=getSecureFloat()*80,g=getSecureFloat()*80,b=getSecureFloat()*80,skewX=(getSecureFloat()-0.5)*15,scaleY=0.9+getSecureFloat()*0.3;textElements+=`<text x="${x}" y="${y}" font-family="Arial, Helvetica, sans-serif" font-size="${fontSize}" font-weight="bold" fill="rgb(${r},${g},${b})" transform="rotate(${rotation}, ${x}, ${y}) skewX(${skewX}) scale(1, ${scaleY})" style="font-style: ${getSecureFloat()>0.5?"italic":"normal"}">${text[i]}</text>`}let overlayLines="";for(let i=0;i<3;i++){let y=10+getSecureFloat()*(height-20),r=getSecureFloat()*60+60,g=getSecureFloat()*60+60,b=getSecureFloat()*60+60;overlayLines+=`<line x1="0" y1="${y}" x2="${width}" y2="${y+(getSecureFloat()-0.5)*20}" stroke="rgb(${r},${g},${b})" stroke-width="1.5"/>`}return`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
|
|
18
18
|
<defs>
|
|
19
19
|
<filter id="noise" x="0%" y="0%" width="100%" height="100%">
|
|
20
20
|
<feTurbulence type="fractalNoise" baseFrequency="0.04" numOctaves="2" result="noise"/>
|
|
@@ -98,7 +98,7 @@ end
|
|
|
98
98
|
redis.call('ZADD', KEYS[1], now, ARGV[4])
|
|
99
99
|
redis.call('PEXPIRE', KEYS[1], windowMs + 1000)
|
|
100
100
|
return {1, count + 1}
|
|
101
|
-
`,RateLimiterBackendError,DEFAULT_AUTH_LOGIN,DEFAULT_AUTH_REGISTER,DEFAULT_AUTH_PASSWORD_RESET,DEFAULT_AUTH_MAGIC_LINK,DEFAULT_CONFIG4;var init_RateLimiter=__esm(()=>{RateLimiterBackendError=class RateLimiterBackendError extends Error{constructor(message){super(message);this.name="RateLimiterBackendError"}};DEFAULT_AUTH_LOGIN={window:"15m",max:5,blockDuration:"30m"},DEFAULT_AUTH_REGISTER={window:"1h",max:3,blockDuration:"1h"},DEFAULT_AUTH_PASSWORD_RESET={window:"1h",max:3,blockDuration:"1h"},DEFAULT_AUTH_MAGIC_LINK={window:"1h",max:5,blockDuration:"1h"},DEFAULT_CONFIG4={enabled:!0,strategy:"sliding-window",keyPrefix:"rl:",authRoutes:{window:"1m",max:10,login:DEFAULT_AUTH_LOGIN,register:DEFAULT_AUTH_REGISTER,passwordReset:DEFAULT_AUTH_PASSWORD_RESET,magicLink:DEFAULT_AUTH_MAGIC_LINK},publicRoutes:{window:"1m",max:100},privateRoutes:{window:"1m",max:60},byIp:!0,byUserId:!0,byEndpoint:!1,skipSuccessfulRequests:!1,headers:{remaining:"X-RateLimit-Remaining",reset:"X-RateLimit-Reset",limit:"X-RateLimit-Limit"},whitelist:[],blacklist:[]}});var exports_schema={};__export(exports_schema,{ensureSchemaExists:()=>ensureSchemaExists,applySchemaPush:()=>applySchemaPush});import{sql as sql4}from"drizzle-orm";var validateIdentifier=(name)=>{if(!name||name.length>63)throw Error(`Invalid identifier: must be 1-63 characters, got ${name.length}`);if(!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name))throw Error(`Invalid identifier: "${name}" contains unsafe characters`);return name},ensureSchemaExists=async(db,schemaName)=>{let safeName=validateIdentifier(schemaName);await db.execute(sql4.raw(`CREATE SCHEMA IF NOT EXISTS "${safeName}"`))},applySchemaPush=async(push,opts)=>{let{schemaName,allowDataLoss,logger:logger2}=opts;if(push.hasDataLoss&&!allowDataLoss)return logger2.error(`[Schema] Destructive changes detected for schema "${schemaName}" but database.allowDataLoss is not enabled \u2014 skipping schema sync for this schema. Set database.allowDataLoss: true to apply them.`,{warnings:push.warnings,statements:push.statementsToExecute}),!1;if(push.hasDataLoss)logger2.warn(`[Schema] Applying destructive changes to schema "${schemaName}" (database.allowDataLoss=true)`,{warnings:push.warnings});return await push.apply(),!0};var init_schema=()=>{};var rowToTenantRecord=(row)=>({id:String(row.id||""),subdomain:String(row.subdomain||""),schemaName:String(row.schemaName||row.schema_name||""),companyId:String(row.companyId||row.company_id||""),companyName:row.companyName!=null?String(row.companyName):row.company_name!=null?String(row.company_name):null,godAdminEmail:String(row.godAdminEmail||row.god_admin_email||""),status:parseStatus(row.status),plan:row.plan!=null?String(row.plan):null,domain:row.domain!=null?String(row.domain):null,settings:parseJsonbToConfig(row.settings),trustedSources:parseTrustedSources(row.trustedSources||row.trusted_sources),maxUsers:row.maxUsers!=null?Number(row.maxUsers):row.max_users!=null?Number(row.max_users):null,provisionedAt:row.provisionedAt!=null?String(row.provisionedAt):row.provisioned_at!=null?String(row.provisioned_at):null,suspendedAt:row.suspendedAt!=null?String(row.suspendedAt):row.suspended_at!=null?String(row.suspended_at):null,suspendedReason:row.suspendedReason!=null?String(row.suspendedReason):row.suspended_reason!=null?String(row.suspended_reason):null}),rowToFeatureRecord=(row,parseConfig)=>({id:String(row.id||""),tenantId:String(row.tenantId||row.tenant_id||""),featureName:String(row.featureName||row.feature_name||""),enabled:Boolean(row.enabled),featureConfig:parseConfig(row.config)}),parseStatus=(value)=>{let valid=["provisioning","active","suspended","archived"],str3=String(value||"provisioning");return valid.includes(str3)?str3:"provisioning"},parseJsonbToConfig=(value)=>{if(!value||typeof value!=="object")return{};let result={};for(let[k,v]of Object.entries(value))if(typeof v==="string"||typeof v==="number"||typeof v==="boolean")result[k]=v;return result},parseTrustedSources=(value)=>{if(!Array.isArray(value))return[];return value.map((item)=>{let entry=item;return{allowHeaderAuth:entry.allowHeaderAuth===!0||entry.allow_header_auth===!0,allowedIps:Array.isArray(entry.allowedIps||entry.allowed_ips)?entry.allowedIps||entry.allowed_ips:void 0,allowedServices:Array.isArray(entry.allowedServices||entry.allowed_services)?entry.allowedServices||entry.allowed_services:void 0}})},normalizeHost=(host)=>{return((host||"").split(":")[0]||"").toLowerCase().replace(/\.$/,"")},extractSubdomain=(host)=>{let hostWithoutPort=host.split(":")[0]||"";if(hostWithoutPort==="localhost"||/^\d+\.\d+\.\d+\.\d+$/.test(hostWithoutPort))return null;let parts=hostWithoutPort.split(".");if(parts.length<3)return null;let subdomain=parts[0]||"";if(!subdomain||subdomain==="www")return null;return subdomain},isIpInCidr=(ip,cidr)=>{let[cidrIp,prefixStr]=cidr.split("/");if(!cidrIp||!prefixStr)return!1;let prefix=Number.parseInt(prefixStr,10);if(Number.isNaN(prefix))return!1;let ipParts=ip.split(".").map(Number),cidrParts=cidrIp.split(".").map(Number);if(ipParts.length!==4||cidrParts.length!==4)return!1;let ipNum=(ipParts[0]||0)<<24|(ipParts[1]||0)<<16|(ipParts[2]||0)<<8|(ipParts[3]||0),cidrNum=(cidrParts[0]||0)<<24|(cidrParts[1]||0)<<16|(cidrParts[2]||0)<<8|(cidrParts[3]||0),mask=~((1<<32-prefix)-1);return(ipNum&mask)===(cidrNum&mask)},isTrustedSource=(tenant,request,authMode,fallbackSources,vettedClientIp)=>{let ownSources=tenant.trustedSources,trustedSources=Array.isArray(ownSources)&&ownSources.length>0?ownSources:fallbackSources;if(!trustedSources||!Array.isArray(trustedSources)||trustedSources.length===0)return!1;let clientIp=vettedClientIp?.trim()||"",serviceId=request.headers.get("x-service-id")||"";for(let source of trustedSources){if(!source.allowHeaderAuth)continue;if(source.allowedIps&&source.allowedIps.length>0){if(source.allowedIps.some((allowedIp)=>{if(allowedIp.includes("/"))return isIpInCidr(clientIp,allowedIp);return clientIp===allowedIp}))return!0}if(source.allowedServices&&source.allowedServices.length>0){if(source.allowedServices.includes(serviceId))return!0}}return!1};function getDatabaseAuthMode(){return process.env.DATABASE_AUTH_MODE||"password"}function getRedisAuthMode(){return process.env.REDIS_AUTH_MODE||"password"}async function acquireToken(scope,label){let{DefaultAzureCredential,ManagedIdentityCredential,ClientSecretCredential}=await import("@azure/identity"),authMode=scope===PG_TOKEN_SCOPE?getDatabaseAuthMode():getRedisAuthMode(),clientId=process.env.AZURE_CLIENT_ID||"",tenantId=process.env.AZURE_TENANT_ID||"",clientSecret=process.env.AZURE_CLIENT_SECRET||"",credential;if(authMode==="managed_identity")credential=clientId?new ManagedIdentityCredential(clientId):new DefaultAzureCredential;else if(authMode==="service_principal"){if(!tenantId||!clientId||!clientSecret)throw Error("[azure-auth] service_principal auth requires AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET");credential=new ClientSecretCredential(tenantId,clientId,clientSecret)}else throw Error(`[azure-auth] Unsupported auth mode: ${authMode}`);let result=await credential.getToken(scope);if(!result)throw Error(`[azure-auth] Failed to acquire token for ${label}`);return logger.scoped("database.connect").info(`[azure-auth] ${label} token acquired`,{expiresAt:new Date(result.expiresOnTimestamp).toISOString(),authMode}),{token:result.token,expiresAt:result.expiresOnTimestamp}}async function getPostgresToken(){let now=Date.now();if(pgCachedToken&&now<pgTokenExpiresAt-REFRESH_BUFFER_MS)return pgCachedToken;let{token,expiresAt}=await acquireToken(PG_TOKEN_SCOPE,"PostgreSQL");return pgCachedToken=token,pgTokenExpiresAt=expiresAt,pgCachedToken}async function getRedisToken(){let now=Date.now();if(redisCachedToken&&now<redisTokenExpiresAt-REFRESH_BUFFER_MS)return redisCachedToken;let{token,expiresAt}=await acquireToken(REDIS_TOKEN_SCOPE,"Redis");return redisCachedToken=token,redisTokenExpiresAt=expiresAt,redisCachedToken}function getRedisTokenExpiresAt(){return redisTokenExpiresAt}var PG_TOKEN_SCOPE="https://ossrdbms-aad.database.windows.net/.default",REDIS_TOKEN_SCOPE="https://redis.azure.com/.default",REFRESH_BUFFER_MS=300000,pgCachedToken=null,pgTokenExpiresAt=0,redisCachedToken=null,redisTokenExpiresAt=0;var init_AzureTokenProvider=__esm(()=>{init_Logger2()});var exports_Azure={};__export(exports_Azure,{getRedisTokenExpiresAt:()=>getRedisTokenExpiresAt,getRedisToken:()=>getRedisToken,getRedisAuthMode:()=>getRedisAuthMode,getPostgresToken:()=>getPostgresToken,getDatabaseAuthMode:()=>getDatabaseAuthMode});var init_Azure=__esm(()=>{init_AzureTokenProvider()});import{access,mkdir as mkdir2}from"fs/promises";import{dirname,resolve}from"path";var DEFAULT_CONFIG5,FILE_SIZE_UNITS,resolvePath=(path2)=>{if(!path2||typeof path2!=="string")throw createFileManagerError("INVALID_PATH","Path must be a non-empty string",path2,"resolvePath");return resolve(path2)},extractDirectoryPath=(filePath)=>{let resolvedPath=resolvePath(filePath);return dirname(resolvedPath)},ensureDirectoryExists=async(dirPath)=>{let resolvedPath=resolve(dirPath);try{await mkdir2(resolvedPath,{recursive:!0})}catch(error){if(error.code!=="EEXIST")throw createFileManagerError("DIRECTORY_CREATE_FAILED",`Failed to create directory: ${resolvedPath}`,resolvedPath,"ensureDirectory")}},formatFileSize=(bytes)=>{let size=bytes,unitIndex=0;while(size>=1024&&unitIndex<FILE_SIZE_UNITS.length-1)size/=1024,unitIndex++;return`${size.toFixed(2)} ${FILE_SIZE_UNITS[unitIndex]}`},validateFileExtension=(fileName,expectedExtension)=>{return fileName.toLowerCase().endsWith(expectedExtension.toLowerCase())},ensureFileExtension=(fileName,extension)=>{let normalizedExtension=extension.startsWith(".")?extension:`.${extension}`;if(validateFileExtension(fileName,normalizedExtension))return fileName;return`${fileName}${normalizedExtension}`},createFileManagerError=(code,message,path2,operation)=>{return{code,message,path:path2,operation:operation||"unknown"}},safeJsonStringify=(data)=>{try{return JSON.stringify(data,null,2)}catch{return"{}"}},executeBulkOperation=async(items,operation,concurrency=DEFAULT_CONFIG5.maxConcurrency)=>{let results=[];for(let i=0;i<items.length;i+=concurrency){let batch3=items.slice(i,i+concurrency),batchPromises=[];for(let item of batch3)batchPromises.push(operation(item));let batchResults=await Promise.allSettled(batchPromises);results.push(...batchResults)}return results},validateConfig=(config,options={})=>{let errors=[],warnings=[],strict=options.strict??!0;if(config.defaultEncoding!==void 0){if(!["utf-8","utf8","ascii","base64","hex"].includes(config.defaultEncoding))errors.push(`Invalid defaultEncoding: ${config.defaultEncoding}`)}if(config.maxConcurrency!==void 0){if(!Number.isInteger(config.maxConcurrency)||config.maxConcurrency<1)errors.push("maxConcurrency must be a positive integer");if(config.maxConcurrency>50)warnings.push("maxConcurrency > 50 may cause performance issues")}if(config.defaultCreateDir!==void 0&&typeof config.defaultCreateDir!=="boolean")errors.push("defaultCreateDir must be a boolean");if(config.defaultRecursive!==void 0&&typeof config.defaultRecursive!=="boolean")errors.push("defaultRecursive must be a boolean");if(strict&&!options.allowUnknownKeys){let validKeys=["defaultEncoding","defaultCreateDir","defaultRecursive","maxConcurrency"],configKeys=Object.keys(config);for(let key2 of configKeys)if(!validKeys.includes(key2))errors.push(`Unknown configuration key: ${key2}`)}return{isValid:errors.length===0,errors,warnings}},mergeConfig=(partial,base=DEFAULT_CONFIG5)=>{let validation=validateConfig(partial);if(!validation.isValid)throw createFileManagerError("CONFIG_VALIDATION_FAILED",`Configuration validation failed: ${validation.errors.join(", ")}`,void 0,"mergeConfig");return{...base,...partial}},parsePermissions=(mode)=>{let parseOctal=(octal)=>({read:Boolean(octal&4),write:Boolean(octal&2),execute:Boolean(octal&1)}),ownerMode=mode>>6&7,groupMode=mode>>3&7,othersMode=mode&7;return{owner:parseOctal(ownerMode),group:parseOctal(groupMode),others:parseOctal(othersMode)}},validatePermissionMode=(mode)=>{return Number.isInteger(mode)&&mode>=0&&mode<=511};var init_utils4=__esm(()=>{DEFAULT_CONFIG5={defaultEncoding:"utf-8",defaultCreateDir:!0,defaultRecursive:!0,maxConcurrency:5},FILE_SIZE_UNITS=["B","KB","MB","GB","TB"]});import{copyFile,rename,unlink as unlink2}from"fs/promises";import{basename,dirname as dirname2,extname,join as join2}from"path";var DEFAULT_ATOMIC_CONFIG,generateTempPath=(originalPath,suffix=".tmp")=>{let resolvedPath=resolvePath(originalPath),timestamp=Date.now(),random=Math.random().toString(36).substring(2,8);return`${resolvedPath}${suffix}.${timestamp}.${random}`},generateBackupPath=(originalPath,backupDir,useTimestamp=!0)=>{let resolvedPath=resolvePath(originalPath),dir=backupDir?resolvePath(backupDir):dirname2(resolvedPath),name=basename(resolvedPath),ext=extname(name),nameWithoutExt=basename(name,ext),timestamp=useTimestamp?`.${new Date().toISOString().replace(/[:.]/g,"-")}`:"",backupName=`${nameWithoutExt}.backup${timestamp}${ext}`;return join2(dir,backupName)},atomicWrite=async({path:path2,data,tempSuffix=DEFAULT_ATOMIC_CONFIG.tempSuffix,backup=DEFAULT_ATOMIC_CONFIG.backup,sync=DEFAULT_ATOMIC_CONFIG.sync})=>{let resolvedPath=resolvePath(path2),tempPath=generateTempPath(resolvedPath,tempSuffix),backupPath;try{if(await ensureDirectoryExists(extractDirectoryPath(resolvedPath)),backup){if(await Bun.file(resolvedPath).exists())backupPath=generateBackupPath(resolvedPath),await copyFile(resolvedPath,backupPath)}let bytesWritten=await Bun.write(tempPath,data);return await rename(tempPath,resolvedPath),{success:!0,bytesWritten,tempPath,backupPath}}catch(error){try{await unlink2(tempPath)}catch{}throw createFileManagerError("ATOMIC_WRITE_FAILED",`Atomic write failed: ${error}`,resolvedPath,"atomicWrite")}},atomicJsonWrite=async(path2,data,options={})=>{let jsonString=JSON.stringify(data,null,2);return atomicWrite({path:path2,data:jsonString,...options})},createBackup=async({sourcePath,backupDir,keepOriginal=!0,timestamp=DEFAULT_ATOMIC_CONFIG.timestamp})=>{let resolvedSource=resolvePath(sourcePath);if(!await Bun.file(resolvedSource).exists())throw createFileManagerError("SOURCE_NOT_FOUND",`Source file not found: ${sourcePath}`,resolvedSource,"createBackup");let backupPath=generateBackupPath(resolvedSource,backupDir,timestamp);if(await ensureDirectoryExists(dirname2(backupPath)),keepOriginal)await copyFile(resolvedSource,backupPath);else await rename(resolvedSource,backupPath);return backupPath},restoreFromBackup=async(backupPath,targetPath,deleteBackup=!1)=>{let resolvedBackup=resolvePath(backupPath),resolvedTarget=resolvePath(targetPath);if(!await Bun.file(resolvedBackup).exists())throw createFileManagerError("BACKUP_NOT_FOUND",`Backup file not found: ${backupPath}`,resolvedBackup,"restoreFromBackup");try{if(await ensureDirectoryExists(extractDirectoryPath(resolvedTarget)),deleteBackup)await rename(resolvedBackup,resolvedTarget);else await copyFile(resolvedBackup,resolvedTarget);return!0}catch(error){return logger.scoped("storage.fs").error(`Failed to restore from backup ${backupPath}`,error,{backupPath}),!1}},safeUpdate=async(path2,updateFunction,options={})=>{let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath),backupPath;try{if(await file.exists())backupPath=await createBackup({sourcePath:resolvedPath,keepOriginal:!0,timestamp:!0});let currentData=await file.exists()?await file.text():"",newData=await updateFunction(currentData),result=await atomicWrite({path:resolvedPath,data:newData,backup:!1,...options});return{success:result.success,bytesWritten:result.bytesWritten,tempPath:result.tempPath,backupPath}}catch(error){if(backupPath)try{await restoreFromBackup(backupPath,resolvedPath,!1)}catch(rollbackError){logger.scoped("storage.fs").error("Atomic write rollback failed",rollbackError,{backupPath})}throw error}},batchAtomicWrite=async(operations)=>{let successful=[],failed=[];for(let operation of operations)try{let result=await atomicWrite(operation);successful.push(result)}catch(error){failed.push({operation,error})}return{successful,failed}};var init_atomic=__esm(()=>{init_Logger2();init_utils4();DEFAULT_ATOMIC_CONFIG={tempSuffix:".tmp",backup:!1,sync:!0,timestamp:!0}});import{chmod,stat as stat2}from"fs/promises";var PERMISSION_MODES,setFilePermissions=async(path2,mode)=>{let resolvedPath=resolvePath(path2);if(!validatePermissionMode(mode))throw createFileManagerError("INVALID_PERMISSION_MODE",`Invalid permission mode: ${mode.toString(8)}`,resolvedPath,"setFilePermissions");try{return await chmod(resolvedPath,mode),!0}catch(error){return logger.scoped("storage.fs").error(`Failed to set permissions for ${path2}`,error,{path:path2,mode}),!1}},getFilePermissions=async(path2)=>{let resolvedPath=resolvePath(path2);try{let mode=(await stat2(resolvedPath)).mode&511,permissions=parsePermissions(mode);return{path:resolvedPath,mode,owner:permissions.owner,group:permissions.group,others:permissions.others}}catch(error){throw createFileManagerError("PERMISSION_READ_FAILED",`Failed to read permissions: ${error}`,resolvedPath,"getFilePermissions")}},hasPermissions=async(path2,requiredMode)=>{try{return((await getFilePermissions(path2)).mode&requiredMode)===requiredMode}catch{return!1}},makeReadable=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode|256;return setFilePermissions(path2,newMode)},makeWritable=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode|128;return setFilePermissions(path2,newMode)},makeExecutable=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode|64;return setFilePermissions(path2,newMode)},makeReadOnly=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode&-147;return setFilePermissions(path2,newMode)},setCommonPermissions=async(path2,pattern)=>{let mode=PERMISSION_MODES[pattern];return setFilePermissions(path2,mode)};var init_permissions=__esm(()=>{init_Logger2();init_utils4();PERMISSION_MODES={OWNER_READ_WRITE:384,OWNER_ALL:448,GROUP_READ:416,GROUP_READ_WRITE:432,ALL_READ:420,ALL_READ_WRITE:438,ALL_READ_EXECUTE:493,ALL_FULL:511,READ_ONLY:292,EXECUTABLE:493}});var DEFAULT_STREAM_CONFIG,createFileWriter=async(path2,options={})=>{let resolvedPath=resolvePath(path2),config={...DEFAULT_STREAM_CONFIG,...options};await ensureDirectoryExists(extractDirectoryPath(resolvedPath));let writer=Bun.file(resolvedPath).writer({highWaterMark:config.highWaterMark}),isClosed=!1;return{write:(chunk)=>{if(isClosed)throw createFileManagerError("WRITER_CLOSED","Cannot write to closed writer",resolvedPath,"streamWrite");try{let result=writer.write(chunk);if(config.autoFlush)writer.flush();return result}catch(error){throw createFileManagerError("WRITE_FAILED",`Failed to write chunk: ${error}`,resolvedPath,"streamWrite")}},flush:()=>{if(isClosed)return 0;try{return writer.flush()}catch(error){throw createFileManagerError("FLUSH_FAILED",`Failed to flush writer: ${error}`,resolvedPath,"streamFlush")}},end:async(error)=>{if(isClosed)return 0;try{let result=await writer.end(error);return isClosed=!0,result}catch(err){throw isClosed=!0,createFileManagerError("END_FAILED",`Failed to end writer: ${err}`,resolvedPath,"streamEnd")}},ref:()=>{if(!isClosed)writer.ref()},unref:()=>{if(!isClosed)writer.unref()}}},writeStream=async(path2,chunks,options={})=>{let writer=await createFileWriter(path2,options),totalBytes=0;try{for(let chunk of chunks){let bytesWritten=writer.write(chunk);totalBytes+=bytesWritten}return await writer.flush(),await writer.end(),totalBytes}catch(error){try{await writer.end(error)}catch{}throw error}},appendStream=async(path2,chunks,options={})=>{let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath),existingContent=await file.exists()?await file.arrayBuffer():new ArrayBuffer(0),allChunks=[];if(existingContent.byteLength>0)allChunks.push(existingContent);return allChunks.push(...chunks),writeStream(resolvedPath,allChunks,options)},copyFileStream=async(sourcePath,destinationPath,options={})=>{let resolvedSource=resolvePath(sourcePath),sourceFile=Bun.file(resolvedSource);if(!await sourceFile.exists())throw createFileManagerError("SOURCE_NOT_FOUND",`Source file not found: ${sourcePath}`,resolvedSource,"copyFileStream");let sourceStream=sourceFile.stream(),writer=await createFileWriter(destinationPath,options),totalBytes=0;try{let reader=sourceStream.getReader();while(!0){let{done,value}=await reader.read();if(done)break;let bytesWritten=writer.write(value);totalBytes+=bytesWritten}return await writer.flush(),await writer.end(),totalBytes}catch(error){try{await writer.end(error)}catch{}throw error}},readFileStream=async(path2,chunkProcessor)=>{let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath);if(!await file.exists())throw createFileManagerError("FILE_NOT_FOUND",`File not found: ${path2}`,resolvedPath,"readFileStream");let reader=file.stream().getReader();try{while(!0){let{done,value}=await reader.read();if(done)break;await chunkProcessor(value)}}finally{reader.releaseLock()}};var init_streaming=__esm(()=>{init_utils4();DEFAULT_STREAM_CONFIG={highWaterMark:1048576,autoFlush:!0,closeOnEnd:!0}});import{readdir,rm,rmdir,stat as stat3}from"fs/promises";import{extname as extname2,join as join3}from"path";class BunFileManager{static instance;config;constructor(){this.config={...DEFAULT_CONFIG5}}static getInstance(){if(!BunFileManager.instance)BunFileManager.instance=new BunFileManager;return BunFileManager.instance}async createFile({dir,name,data,options={}}){let filePath=resolvePath(join3(dir,name));if(options.createDir!==!1)await ensureDirectoryExists(extractDirectoryPath(filePath));let fileData=options.type?new Blob([data],{type:options.type}):data;return await Bun.write(filePath,fileData)}async createJsonFile(dir,name,data){let fileName=ensureFileExtension(name,".json"),jsonString=safeJsonStringify(data);return this.createFile({dir,name:fileName,data:jsonString,options:{type:"application/json"}})}async createDirectory({path:path2}){await ensureDirectoryExists(path2)}async readFile({path:path2,format="text"}){let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath);if(!await file.exists())throw createFileManagerError("FILE_NOT_FOUND",`File not found: ${path2}`,resolvedPath,"readFile");switch(format){case"text":return await file.text();case"json":return await file.json();case"buffer":return await file.arrayBuffer();case"bytes":return await file.bytes();case"stream":return file.stream();default:return await file.text()}}async readJsonFile(path2){return this.readFile({path:path2,format:"json"})}async getFileInfo(path2){let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath),fileName=path2.split("/").pop()||path2,stats=null;try{stats=await stat3(resolvedPath)}catch{}return{name:fileName,path:resolvedPath,size:file.size,type:file.type,exists:await file.exists(),extension:extname2(fileName),createdAt:stats?.birthtime,modifiedAt:stats?.mtime}}async readDirectory({path:path2,recursive=!1}){let resolvedPath=resolvePath(path2);return await readdir(resolvedPath,{recursive,encoding:"utf8"})}async getFilesByExtension(dir,extension){let files=await this.readDirectory({path:dir}),normalizedExt=extension.startsWith(".")?extension:`.${extension}`;return files.filter((file)=>file.endsWith(normalizedExt))}async updateFile({path:path2,data,mode="overwrite"}){let resolvedPath=resolvePath(path2);if(mode==="append"){let combinedData=await this.readFile({path:path2,format:"text"})+data;return await Bun.write(resolvedPath,combinedData)}return await Bun.write(resolvedPath,data)}async updateJsonFile(path2,data,merge=!1){let finalData=data;if(merge)try{let existingData=await this.readJsonFile(path2);if(typeof existingData==="object"&&existingData!==null&&!Array.isArray(existingData)&&typeof data==="object"&&data!==null&&!Array.isArray(data))finalData={...existingData,...data}}catch{}return this.updateFile({path:path2,data:safeJsonStringify(finalData),mode:"overwrite"})}async appendToFile(path2,data){return this.updateFile({path:path2,data,mode:"append"})}async deleteFile(path2){try{let resolvedPath=resolvePath(path2);return await Bun.file(resolvedPath).delete(),!0}catch(error){return logger.scoped("storage.fs").error(`Failed to delete file ${path2}`,error,{path:path2}),!1}}async deleteDirectory({path:path2,recursive=!1}){try{let resolvedPath=resolvePath(path2);if(recursive)await rm(resolvedPath,{recursive:!0,force:!0});else await rmdir(resolvedPath);return!0}catch(error){return logger.scoped("storage.fs").error(`Failed to delete directory ${path2}`,error,{path:path2}),!1}}async deleteFiles(paths){let results=await executeBulkOperation(paths,async(path2)=>{if(!await this.deleteFile(path2))throw Error(`Failed to delete: ${path2}`);return path2}),success=[],failed=[];for(let i=0;i<results.length;i++){let result=results[i],originalPath=paths[i];if(result?.status==="fulfilled")success.push(originalPath||"");else failed.push(originalPath||"")}return{success,failed}}async exists(path2){let resolvedPath=resolvePath(path2);return await Bun.file(resolvedPath).exists()}async copyFile(sourcePath,destinationPath){let resolvedSource=resolvePath(sourcePath),resolvedDestination=resolvePath(destinationPath),sourceFile=Bun.file(resolvedSource);if(!await sourceFile.exists())throw createFileManagerError("SOURCE_NOT_FOUND",`Source file not found: ${sourcePath}`,resolvedSource,"copyFile");return await ensureDirectoryExists(extractDirectoryPath(resolvedDestination)),await Bun.write(resolvedDestination,sourceFile)}async moveFile(sourcePath,destinationPath){try{return await this.copyFile(sourcePath,destinationPath),await this.deleteFile(sourcePath),!0}catch(error){return logger.scoped("storage.fs").error("Failed to move file",error,{sourcePath,destinationPath}),!1}}getFormattedFileSize(bytes){return formatFileSize(bytes)}getConfig(){return{...this.config}}updateConfig(newConfig){let validation=validateConfig(newConfig);if(validation.isValid){let mergedConfig=mergeConfig(newConfig,this.config);Object.assign(this.config,mergedConfig)}return validation}validateConfiguration(config){return validateConfig(config)}async createStreamWriter(path2,options={}){return createFileWriter(path2,options)}async writeStream(path2,chunks,options={}){return writeStream(path2,chunks,options)}async appendStream(path2,chunks,options={}){return appendStream(path2,chunks,options)}async copyFileStream(sourcePath,destinationPath,options={}){return copyFileStream(sourcePath,destinationPath,options)}async readFileStream(path2,chunkProcessor){return readFileStream(path2,chunkProcessor)}async setPermissions(path2,mode){return setFilePermissions(path2,mode)}async setPermissionsAdvanced(options){return setFilePermissions(options.path,options.mode)}async getPermissions(path2){return getFilePermissions(path2)}async checkPermissions(path2,requiredMode){return hasPermissions(path2,requiredMode)}async makeFileReadable(path2){return makeReadable(path2)}async makeFileWritable(path2){return makeWritable(path2)}async makeFileExecutable(path2){return makeExecutable(path2)}async makeFileReadOnly(path2){return makeReadOnly(path2)}async setCommonPermission(path2,pattern){return setCommonPermissions(path2,pattern)}async atomicWrite(options){return atomicWrite(options)}async atomicJsonWrite(path2,data,options={}){return atomicJsonWrite(path2,data,options)}async createFileBackup(options){return createBackup(options)}async restoreFileFromBackup(backupPath,targetPath,deleteBackup=!1){return restoreFromBackup(backupPath,targetPath,deleteBackup)}async safeFileUpdate(path2,updateFunction,options={}){return safeUpdate(path2,updateFunction,options)}async batchAtomicOperations(operations){return batchAtomicWrite(operations)}}var init_core=__esm(()=>{init_Logger2();init_atomic();init_permissions();init_streaming();init_utils4()});var fileManager;var init_File=__esm(()=>{init_core();init_utils4();init_core();fileManager=BunFileManager.getInstance()});import{Pool}from"pg";var init_Postgre=__esm(()=>{init_Logger2()});var init_Managers=__esm(()=>{init_Azure();init_Dapr();init_File();init_Postgre();init_Redis()});var exports_utils={};__export(exports_utils,{warnIfAccessTokenTooLargeForCookie:()=>warnIfAccessTokenTooLargeForCookie,validatePayload:()=>validatePayload,validateEnvVariables:()=>validateEnvVariables,toAudit:()=>toAudit,signNewAccessToken:()=>signNewAccessToken,sanitizePayload:()=>sanitizePayload,resolveDbPoolConfig:()=>resolveDbPoolConfig,refreshAccessTokenWithLock:()=>refreshAccessTokenWithLock,redactSensitiveOutput:()=>redactSensitiveOutput,parseTokenValuesFromHeaders:()=>parseTokenValuesFromHeaders,parseTimeToSeconds:()=>parseTimeToSeconds2,parseQueryParams:()=>parseQueryParams,isSensitiveOutputKey:()=>isSensitiveOutputKey,initiateRedisManager:()=>initiateRedisManager,getRedisManager:()=>getRedisManager,ensureDatabaseExists:()=>ensureDatabaseExists,decodeUnverifiedSubject:()=>decodeUnverifiedSubject,createAuditLog:()=>createAuditLog,buildPaginationMeta:()=>buildPaginationMeta,COOKIE_SAFE_TOKEN_BYTES:()=>COOKIE_SAFE_TOKEN_BYTES});function parseTokenValuesFromHeaders(headers,tokenNames){let cookies=(headers.get("cookie")?.split(";")||[]).reduce((acc,cookie)=>{let trimmed=cookie.trim(),eqIndex=trimmed.indexOf("=");if(eqIndex>0)acc[trimmed.slice(0,eqIndex)]=trimmed.slice(eqIndex+1);return acc},{});return{access_token:cookies[tokenNames.access_token]||headers.get("authorization")?.split(" ")[1],refresh_token:cookies[tokenNames.refresh_token],session_token:cookies[tokenNames.session_token]}}async function initiateRedisManager(config){if(!config.redis){logger.info("[Redis] Not configured, skipping");return}let rawWithDapr=config.redis.withDapr;if(typeof rawWithDapr==="string"?process.env[rawWithDapr]?.toLowerCase()!=="false":rawWithDapr??!1){redisManagerInstance=new RedisManager({withDapr:!0,stateStoreName:config.redis.stateStoreName});return}let resolvedUrl=config.redis.url?process.env[config.redis.url]:void 0,resolvedHost=config.redis.host?process.env[config.redis.host]:void 0,resolvedPort=config.redis.port?parseInt(process.env[config.redis.port]||"",10):void 0;if((process.env.REDIS_AUTH_MODE||"password")!=="password"){let{getRedisToken:getRedisToken2,getRedisTokenExpiresAt:getRedisTokenExpiresAt2}=await Promise.resolve().then(() => (init_Azure(),exports_Azure)),clientId=process.env.AZURE_CLIENT_ID||"",initialToken=await getRedisToken2();redisManagerInstance=new RedisManager({host:resolvedHost,port:Number.isNaN(resolvedPort)?void 0:resolvedPort,password:initialToken,username:clientId,tls:!0});let unref=(t)=>{t.unref?.()},scheduleRedisTokenRefresh=()=>{let expiresAt=getRedisTokenExpiresAt2(),refreshIn=Math.max(expiresAt-Date.now()-300000,30000);unref(setTimeout(async()=>{try{let newToken=await getRedisToken2();if(redisManagerInstance)await redisManagerInstance.reauthenticate(clientId,newToken),logger.info("[Redis] Entra ID token refreshed successfully");scheduleRedisTokenRefresh()}catch(err){logger.error("[Redis] Token refresh failed \u2014 retrying in 30s",err),unref(setTimeout(scheduleRedisTokenRefresh,30000))}},refreshIn))};scheduleRedisTokenRefresh()}else{let resolvedPassword=process.env.REDIS_PASSWORD||void 0;redisManagerInstance=new RedisManager({url:resolvedUrl,host:resolvedHost,port:Number.isNaN(resolvedPort)?void 0:resolvedPort,...resolvedPassword?{password:resolvedPassword}:{}})}}function getRedisManager(){return redisManagerInstance}function parseTimeToSeconds2(timeString){if(typeof timeString==="number")return timeString;if(!timeString||timeString.trim()==="")throw Error("Time string cannot be empty");let match=timeString.trim().match(/^(\d+(?:\.\d+)?)\s*([smhdwMy])$/);if(!match||!match[1]||!match[2])throw Error(`Invalid time format: "${timeString}". Expected format: "75s", "10m", "2h", "1d", "1w", "2M", "1y"`);let value=parseFloat(match[1]),unit=match[2],multiplier={s:1,m:60,h:3600,d:86400,w:604800,M:2592000,y:31536000}[unit];if(multiplier===void 0)throw Error(`Unknown time unit: "${unit}"`);let seconds=Math.floor(value*multiplier);if(seconds<=0)throw Error(`Time value must be positive: "${timeString}"`);return seconds}function warnIfAccessTokenTooLargeForCookie(token,jwtClaimsMode){let bytes=Buffer.byteLength(token,"utf-8");if(bytes<=COOKIE_SAFE_TOKEN_BYTES)return;let now=Date.now();if(now-lastOversizeWarnAt<60000)return;lastOversizeWarnAt=now,logger.warn(`[Auth] access_token is ${bytes} bytes \u2014 at/over the ~4KB per-cookie browser limit, so the cookie may be `+"silently dropped (symptom: appears logged-in but requests are unauthenticated). Shrink it: set authorization.jwtClaimsMode:'resolve' (token carries only roles; claims resolved from the Redis claims cache), or deliver the token off-cookie via authentication.accessToken.setHeadersEnabled:false. "+(jwtClaimsMode?`Current jwtClaimsMode='${jwtClaimsMode}'.`:""))}function signNewAccessToken({sessionData,options,refreshTokenId,roles,claims,tenant,claimScopes,resolveMode}){let secretEnvName=options.authentication?.accessToken?.secret;if(!secretEnvName)throw Error("Access token secret env name is not configured");let secret=process.env[secretEnvName];if(!secret)throw Error(`Access token secret env "${secretEnvName}" is not set`);let token=signJWT({subject:sessionData.userId,issuer:options.authentication?.accessToken?.issuer,audience:options.authentication?.accessToken?.audience,algorithm:options.authentication?.accessToken?.algorithm,expiresInSeconds:parseTimeToSeconds2(options.authentication?.accessToken?.expiresIn??"15m"),sessionId:sessionData.id,customClaims:{refreshTokenId,...roles&&roles.length>0?{roles}:{},...!resolveMode&&claims&&claims.length>0?{claims}:{},...!resolveMode&&claimScopes&&Object.keys(claimScopes).length>0?{claimScopes}:{},...tenant?{tenant}:{}}},secret);return warnIfAccessTokenTooLargeForCookie(token,resolveMode?"resolve":options.authorization?.jwtClaimsMode),token}function resolveDbPoolConfig(pool){return{max:pool?.max!=null&&pool.max>0?pool.max:10,idleTimeoutMillis:pool?.idleTimeoutMillis??30000,connectionTimeoutMillis:pool?.connectionTimeoutMillis??1e4,...pool?.maxUses!=null&&pool.maxUses>0?{maxUses:pool.maxUses}:{}}}function toAudit(payload,summary,opts){return payload?{entityName:payload.entity_name,entityId:payload.entity_id===" - "?null:payload.entity_id,operation:payload.operation_type,userId:opts&&"userId"in opts?opts.userId??null:payload.user_id==="unknown"?null:payload.user_id,summary,severity:opts?.severity,category:opts?.category,ipAddress:payload.ip_address,userAgent:payload.user_agent,path:payload.path,query:payload.query}:void 0}function decodeUnverifiedSubject(token){if(!token)return null;try{let parts=token.split(".");if(parts.length<2)return null;let payloadPart=parts[1];if(!payloadPart)return null;let json=Buffer.from(payloadPart,"base64url").toString("utf-8"),decoded=JSON.parse(json);return typeof decoded.sub==="string"&&decoded.sub?decoded.sub:null}catch{return null}}function reconstructBracketParams(query){let result={},arrayGroups={};for(let[key2,value]of Object.entries(query)){let match=key2.match(/^(\w+)\[\d*\]\[(\w+)\]$/),arrayName=match?.[1],prop=match?.[2];if(arrayName&&prop){if(!arrayGroups[arrayName])arrayGroups[arrayName]={};let group=arrayGroups[arrayName];if(!group[prop])group[prop]=[];let arr=group[prop];if(Array.isArray(value))for(let v of value)arr.push(v);else arr.push(value)}else result[key2]=value}for(let[arrayName,props]of Object.entries(arrayGroups)){let propNames=Object.keys(props);if(propNames.length===0)continue;let maxLen=Math.max(...propNames.map((p)=>(props[p]||[]).length)),items=[];for(let i=0;i<maxLen;i++){let item={};for(let p of propNames)item[p]=(props[p]||[])[i];items.push(item)}result[arrayName]=items}return result}function parseQueryParams(query){let q=reconstructBracketParams(query),parseJSONOrPassthrough=(value)=>{if(value===void 0||value===null)return;if(typeof value==="object")return value;if(typeof value==="string")try{return JSON.parse(value)}catch{return}return},DEFAULT_PAGE_SIZE=20,MAX_PAGE_SIZE=200,rawPage=q.page?parseInt(q.page,10):1,page=Number.isFinite(rawPage)&&rawPage>0?rawPage:1,rawLimit=q.limit?parseInt(q.limit,10):20,limit=Number.isFinite(rawLimit)&&rawLimit>0?Math.min(rawLimit,200):20,rawOffset=q.offset?parseInt(q.offset,10):(page-1)*limit,offset=Number.isFinite(rawOffset)&&rawOffset>=0?rawOffset:0;return{page,limit,offset,search:q.search,searchFields:q.searchFields?q.searchFields.split(","):void 0,filters:parseJSONOrPassthrough(q.filters),sort:parseJSONOrPassthrough(q.sort),select:q.select?q.select.split(","):void 0,with:parseJSONOrPassthrough(q.with),distinct:q.distinct==="true",distinctOn:q.distinctOn?q.distinctOn.split(","):void 0}}function buildPaginationMeta(page,limit,offset,totalItems){let totalPages=Math.ceil(totalItems/limit),hasNextPage=page<totalPages,hasPrevPage=page>1;return{page,limit,offset,totalItems,totalPages,hasNextPage,hasPrevPage,nextPage:hasNextPage?page+1:null,prevPage:hasPrevPage?page-1:null}}function getBaseTypeValidator(type){let stringTypes=["varchar","char","text","uuid","citext","bit","varbit"],numberTypes=["integer","smallint","bigint","serial","smallserial","bigserial","real","doublePrecision","numeric","decimal"],booleanTypes=["boolean"];if(stringTypes.includes(type))return(v)=>({valid:typeof v==="string",expectedType:"string"});if(numberTypes.includes(type))return(v)=>({valid:typeof v==="number",expectedType:"number"});if(booleanTypes.includes(type))return(v)=>({valid:typeof v==="boolean",expectedType:"boolean"});if(type==="json"||type==="jsonb")return(v)=>({valid:typeof v==="object",expectedType:"object"});return()=>({valid:!0,expectedType:"any"})}function validatePayload(payload,columns,isPartial=!1){let errors=[];for(let col6 of columns){let value=payload[col6.name]??payload[col6.name.replace(/_([a-z])/g,(_,l)=>l.toUpperCase())],hasDbDefault=col6.default!==void 0||!!col6.defaultRaw||!!col6.generatedByDefaultAsIdentity||!!col6.generatedAlwaysAsIdentity||!!col6.generatedAlwaysAs,isRequired=col6.notNull&&!col6.nullable&&!hasDbDefault;if(value===void 0||value===null){if(isRequired&&!isPartial)errors.push({field:col6.name,message:col6.validation?.customMessage||`${col6.name} is required`});continue}if(col6.array){let baseValidator=getBaseTypeValidator(col6.type),expectedType=baseValidator(void 0).expectedType;if(!Array.isArray(value)){errors.push({field:col6.name,message:col6.validation?.customMessage||`${col6.name} must be an array of ${expectedType}`});continue}if(value.some((el)=>el!==null&&!baseValidator(el).valid))errors.push({field:col6.name,message:col6.validation?.customMessage||`${col6.name} must be an array of ${expectedType}`});continue}let typeCheck=getBaseTypeValidator(col6.type)(value);if(!typeCheck.valid){errors.push({field:col6.name,message:col6.validation?.customMessage||`${col6.name} must be of type ${typeCheck.expectedType}`});continue}if(typeof value==="string"){let len=value.length;if(col6.length&&len>col6.length)errors.push({field:col6.name,message:col6.validation?.customMessage||`${col6.name} exceeds max length of ${col6.length}`});if(col6.validation?.minLength&&len<col6.validation.minLength)errors.push({field:col6.name,message:col6.validation.customMessage||`${col6.name} must be at least ${col6.validation.minLength} characters`});if(col6.validation?.maxLength&&len>col6.validation.maxLength)errors.push({field:col6.name,message:col6.validation.customMessage||`${col6.name} must be at most ${col6.validation.maxLength} characters`});if(col6.validation?.pattern){if(!new RegExp(col6.validation.pattern).test(value))errors.push({field:col6.name,message:col6.validation.customMessage||`${col6.name} does not match required pattern`})}if(col6.validation?.format){let formatRegex=FORMAT_PATTERNS[col6.validation.format];if(formatRegex&&!formatRegex.test(value))errors.push({field:col6.name,message:col6.validation.customMessage||`${col6.name} must be a valid ${col6.validation.format}`})}}if(typeof value==="number"){if(col6.validation?.min!==void 0&&value<col6.validation.min)errors.push({field:col6.name,message:col6.validation.customMessage||`${col6.name} must be at least ${col6.validation.min}`});if(col6.validation?.max!==void 0&&value>col6.validation.max)errors.push({field:col6.name,message:col6.validation.customMessage||`${col6.name} must be at most ${col6.validation.max}`})}if(col6.enumValues&&col6.enumValues.length>0){if(!col6.enumValues.includes(value))errors.push({field:col6.name,message:col6.validation?.customMessage||`${col6.name} must be one of: ${col6.enumValues.join(", ")}`})}}return{valid:errors.length===0,errors}}function escapeHtml(str3){return str3.replace(/[&<>"'`=/]/g,(char)=>HTML_ENTITIES[char]||char)}function stripTags(str3){return str3.replace(/<[^>]*>/g,"")}function normalizeEmail(email){let parts=email.split("@"),localPart=parts[0],domain=parts[1];if(!localPart||!domain)return email;let beforePlus=localPart.split("+")[0];if(!beforePlus)return email;return`${beforePlus.replace(/\./g,"")}@${domain.toLowerCase()}`}function slugify(str3){return str3.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}function applySanitizer(value,sanitizer){if(value===null||value===void 0)return value;switch(sanitizer){case"trim":return typeof value==="string"?value.trim():value;case"lowercase":return typeof value==="string"?value.toLowerCase():value;case"uppercase":return typeof value==="string"?value.toUpperCase():value;case"escapeHtml":return typeof value==="string"?escapeHtml(value):value;case"stripTags":return typeof value==="string"?stripTags(value):value;case"normalizeEmail":return typeof value==="string"?normalizeEmail(value):value;case"toNumber":if(typeof value==="number")return value;if(typeof value==="string"){let num2=Number(value);return Number.isNaN(num2)?value:num2}return value;case"toBoolean":if(typeof value==="boolean")return value;if(typeof value==="string"){let lower=value.toLowerCase();if(lower==="true"||lower==="1"||lower==="yes")return!0;if(lower==="false"||lower==="0"||lower==="no")return!1}if(typeof value==="number")return value!==0;return value;case"slugify":return typeof value==="string"?slugify(value):value;default:return value}}function isSensitiveOutputKey(key2){return SENSITIVE_OUTPUT_KEYS.has(key2)}function redactSensitiveOutput(row){return scrubSensitive(row)}function scrubSensitive(value){if(value===null||typeof value!=="object")return value;if(Array.isArray(value))return value.map(scrubSensitive);let proto=Object.getPrototypeOf(value);if(proto!==Object.prototype&&proto!==null)return value;let out={};for(let[k,v]of Object.entries(value)){if(SENSITIVE_OUTPUT_KEYS.has(k))continue;out[k]=scrubSensitive(v)}return out}function sanitizePayload(payload,columns,opts){let sanitized={},toCamel2=(s)=>s.replace(/_([a-z])/g,(_,l)=>l.toUpperCase()),SERVER_MANAGED=new Set(["id","created_at","updated_at","created_by","updated_by","createdAt","updatedAt","createdBy","updatedBy"]),PROTECTED_SENSITIVE=new Set(["is_god","password","password_hash","email_verified","verified_at","email_verified_at","is_locked","locked_until","failed_login_attempts","login_count","last_login_at","email_verification_token","email_verification_sent_at","email_verification_expires_at","password_reset_token","password_reset_expires_at","password_reset_sent_at","magic_link_token","two_factor_secret"]),STORAGE_MANAGED=opts?.isFormData?new Set(["path","name","original_name","originalName","extension","size","mime_type","mimeType","uploaded_by","uploadedBy"]):null;for(let key2 of Object.keys(payload)){if(SERVER_MANAGED.has(key2))continue;if(STORAGE_MANAGED?.has(key2))continue;let value=payload[key2],snakeKey=key2.replace(/[A-Z]/g,(l)=>`_${l.toLowerCase()}`);if(PROTECTED_SENSITIVE.has(snakeKey))continue;let col6=columns.find((c)=>c.name===key2||c.name===snakeKey);if(col6?.readOnly)continue;if(col6?.sanitize&&col6.sanitize.length>0)for(let sanitizer of col6.sanitize)value=applySanitizer(value,sanitizer);if(col6&&(col6.type==="timestamp"||col6.type==="timestamptz"||col6.type==="date")&&typeof value==="string"){let parsed=new Date(value);if(!Number.isNaN(parsed.getTime()))value=parsed}let normalizedKey=key2.includes("_")?toCamel2(key2):key2;sanitized[normalizedKey]=value}return sanitized}function createAuditLog(db,auditTable,entry){if(!db||!auditTable)return;let logEntry={user_id:entry.user_id,entity_name:entry.entity_name,entity_id:entry.entity_id,operation:entry.operation,old_data:entry.old_data??null,new_data:entry.new_data??null,timestamp:new Date().toISOString()};db.insert(auditTable).values(logEntry).execute().catch((err)=>{logger.error("[Audit] Database audit write failed",err,{entity:logEntry.entity_name,operation:logEntry.operation})})}async function refreshAccessTokenWithLock(userId,sessionId,generateToken){let redis=new RedisManager,lockKey=`${REFRESH_LOCK_PREFIX}${userId}`,cacheKey=`${ACCESS_TOKEN_CACHE_PREFIX}${userId}:${sessionId}`,cachedResult=await redis.read(cacheKey);if(cachedResult.success&&cachedResult.data)return{success:!0,accessToken:cachedResult.data,fromCache:!0};let lockResult=await redis.acquireLock(lockKey,LOCK_TTL_SECONDS);if(!lockResult.success)return{success:!1,error:lockResult.error};if(lockResult.data)try{let newToken=generateToken();return await redis.create(cacheKey,newToken,ACCESS_TOKEN_CACHE_TTL_SECONDS),{success:!0,accessToken:newToken,fromCache:!1}}finally{await redis.releaseLock(lockKey)}let waitResult=await redis.waitForLock(lockKey,LOCK_WAIT_TIMEOUT_MS,50);if(!waitResult.success)return{success:!1,error:waitResult.error};if(!waitResult.data)return{success:!1,error:"Lock wait timeout"};let newCachedResult=await redis.read(cacheKey);if(newCachedResult.success&&newCachedResult.data)return{success:!0,accessToken:newCachedResult.data,fromCache:!0};let fallbackToken=generateToken();return await redis.create(cacheKey,fallbackToken,ACCESS_TOKEN_CACHE_TTL_SECONDS),{success:!0,accessToken:fallbackToken,fromCache:!1}}function validateEnvVariables(config){let errors=[],resolved={},databaseAuthMode=process.env.DATABASE_AUTH_MODE||"password",redisAuthMode=process.env.REDIS_AUTH_MODE||"password";resolved.databaseAuthMode=databaseAuthMode,resolved.redisAuthMode=redisAuthMode;let entraIdModes=["managed_identity","service_principal"];if(entraIdModes.includes(databaseAuthMode)||entraIdModes.includes(redisAuthMode)){if(!process.env.AZURE_CLIENT_ID)logger.warn("[Config] AZURE_CLIENT_ID is not set. Required for user-assigned managed identity.");if([databaseAuthMode,redisAuthMode].filter((m)=>m==="service_principal").length>0){if(!process.env.AZURE_TENANT_ID)errors.push({field:"azure.tenantId",envName:"AZURE_TENANT_ID",message:"AZURE_TENANT_ID is required for service_principal auth mode."});if(!process.env.AZURE_CLIENT_SECRET)errors.push({field:"azure.clientSecret",envName:"AZURE_CLIENT_SECRET",message:"AZURE_CLIENT_SECRET is required for service_principal auth mode."})}}if(config.database?.url){let envValue=process.env[config.database.url];if(!envValue)errors.push({field:"database.url",envName:config.database.url,message:`Environment variable "${config.database.url}" is not set. Please set it in your .env file.`});else resolved.databaseUrl=envValue}let validationWithDapr=typeof config.redis?.withDapr==="string"?process.env[config.redis.withDapr]?.toLowerCase()!=="false":config.redis?.withDapr??!1;if(config.redis&&!validationWithDapr)if(config.redis.url){let envValue=process.env[config.redis.url];if(!envValue)errors.push({field:"redis.url",envName:config.redis.url,message:`Environment variable "${config.redis.url}" is not set. Please set it in your .env file.`});else resolved.redisUrl=envValue}else{if(config.redis.host){if(!process.env[config.redis.host])errors.push({field:"redis.host",envName:config.redis.host,message:`Environment variable "${config.redis.host}" is not set. Please set it in your .env file.`})}if(config.redis.port){if(!process.env[config.redis.port])errors.push({field:"redis.port",envName:config.redis.port,message:`Environment variable "${config.redis.port}" is not set. Please set it in your .env file.`})}}if(config.authentication?.enabled){if(!config.authentication.mode)errors.push({field:"authentication.mode",envName:"",message:'authentication.mode is required when authentication is enabled. Use "full" for IDP/standalone services, "consumer" for resource servers.'});if(config.authentication.accessToken?.secret){let envValue=process.env[config.authentication.accessToken.secret];if(!envValue)errors.push({field:"authentication.accessToken.secret",envName:config.authentication.accessToken.secret,message:`Environment variable "${config.authentication.accessToken.secret}" is not set. Please set it in your .env file.`});else resolved.accessTokenSecret=envValue}else errors.push({field:"authentication.accessToken.secret",envName:"",message:"authentication.accessToken.secret is required when authentication is enabled."});let isConsumerMode=config.authentication.mode==="consumer";if(config.authentication.refreshToken?.secret){let envValue=process.env[config.authentication.refreshToken.secret];if(!envValue)errors.push({field:"authentication.refreshToken.secret",envName:config.authentication.refreshToken.secret,message:`Environment variable "${config.authentication.refreshToken.secret}" is not set. Please set it in your .env file.`});else resolved.refreshTokenSecret=envValue}else if(!isConsumerMode)errors.push({field:"authentication.refreshToken.secret",envName:"",message:"authentication.refreshToken.secret is required when authentication is enabled."});if(config.authentication.sessionToken?.secret){let envValue=process.env[config.authentication.sessionToken.secret];if(!envValue)errors.push({field:"authentication.sessionToken.secret",envName:config.authentication.sessionToken.secret,message:`Environment variable "${config.authentication.sessionToken.secret}" is not set. Please set it in your .env file.`});else resolved.sessionTokenSecret=envValue}else if(!isConsumerMode)errors.push({field:"authentication.sessionToken.secret",envName:"",message:"authentication.sessionToken.secret is required when authentication is enabled."})}if(config.authentication?.oauth?.enabled&&config.authentication.oauth.providers){let resolvedProviders={};for(let[providerName,providerConfig]of Object.entries(config.authentication.oauth.providers)){if(!providerConfig)continue;let{clientId:clientIdEnvName,clientSecret:clientSecretEnvName,redirectUri:redirectUriEnvName,tenantId:tenantIdEnvName}=providerConfig,clientId=process.env[clientIdEnvName],clientSecret=process.env[clientSecretEnvName],redirectUri=process.env[redirectUriEnvName]??redirectUriEnvName,tenantId=tenantIdEnvName?process.env[tenantIdEnvName]??tenantIdEnvName:void 0;if(!clientId)errors.push({field:`authentication.oauth.providers.${providerName}.clientId`,envName:clientIdEnvName,message:`Environment variable "${clientIdEnvName}" is not set (OAuth ${providerName} clientId).`});if(!clientSecret)errors.push({field:`authentication.oauth.providers.${providerName}.clientSecret`,envName:clientSecretEnvName,message:`Environment variable "${clientSecretEnvName}" is not set (OAuth ${providerName} clientSecret).`});if(clientId&&clientSecret)resolvedProviders[providerName]={clientId,clientSecret,redirectUri,tenantId,scopes:providerConfig.scopes,authorizationUrl:providerConfig.authorizationUrl,tokenUrl:providerConfig.tokenUrl,userInfoUrl:providerConfig.userInfoUrl,extraAuthParams:providerConfig.extraAuthParams}}if(Object.keys(resolvedProviders).length>0)resolved.oauthProviders=resolvedProviders}return{valid:errors.length===0,errors,resolved}}async function ensureDatabaseExists(databaseUrl,logger2,authMode){let{Pool:Pool2}=await import("pg"),targetDb=new URL(databaseUrl).pathname.replace("/","");if(!targetDb)return;let adminUrl=new URL(databaseUrl);adminUrl.pathname="/postgres";let pool;if(authMode&&authMode!=="password"){let{getPostgresToken:getPostgresToken2}=await Promise.resolve().then(() => (init_Azure(),exports_Azure));pool=new Pool2({connectionString:adminUrl.toString(),password:getPostgresToken2,ssl:{rejectUnauthorized:!0}})}else pool=new Pool2({connectionString:adminUrl.toString()});try{if((await pool.query("SELECT 1 FROM pg_database WHERE datname = $1",[targetDb])).rowCount===0)logger2.info(`[Database] Creating database "${targetDb}"...`),await pool.query(`CREATE DATABASE "${targetDb}" TEMPLATE template0`),logger2.info(`[Database] Database "${targetDb}" created successfully`);else logger2.info(`[Database] Database "${targetDb}" exists`)}catch(err){let message=err instanceof Error?err.message:String(err);logger2.warn(`[Database] Could not auto-create database: ${message}`)}finally{await pool.end()}}var redisManagerInstance=null,COOKIE_SAFE_TOKEN_BYTES=3500,lastOversizeWarnAt=0,FORMAT_PATTERNS,HTML_ENTITIES,SENSITIVE_OUTPUT_KEYS,ACCESS_TOKEN_CACHE_PREFIX="access_token:",REFRESH_LOCK_PREFIX="refresh_lock:",LOCK_TTL_SECONDS=5,LOCK_WAIT_TIMEOUT_MS=3000,ACCESS_TOKEN_CACHE_TTL_SECONDS=60;var init_utils5=__esm(()=>{init_Managers();init_Services();init_Logger2();FORMAT_PATTERNS={email:/^[^\s@]+@[^\s@]+\.[^\s@]+$/,url:/^https?:\/\/.+/,uuid:/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,date:/^\d{4}-\d{2}-\d{2}$/,datetime:/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/,time:/^\d{2}:\d{2}:\d{2}$/,uri:/^[a-z][a-z0-9+.-]*:/i,ipv4:/^(\d{1,3}\.){3}\d{1,3}$/,ipv6:/^([0-9a-f]{1,4}:){7}[0-9a-f]{1,4}$/i};HTML_ENTITIES={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};SENSITIVE_OUTPUT_KEYS=new Set(["password","passwordHash","password_hash","emailVerificationToken","email_verification_token","emailVerificationTokenExpiresAt","email_verification_token_expires_at","passwordResetToken","password_reset_token","refreshTokenHash","refresh_token_hash"])});import{eq as eq12}from"drizzle-orm";import{pgSchema}from"drizzle-orm/pg-core";class TenantRegistry{db;logger;mainSchemaName;mainSchemaTables;mainSchemaRelations;createAllTablesForSchema;createAllRelationsForSchema;appId;authMode;tenantResolution;tenantHeader;redisCacheTtlSeconds;defaultTrustedSources;idpUrl;allowDataLoss;onTenantProvisioned;tenantsBySubdomain=new Map;tenantsBySchemaName=new Map;tenantsById=new Map;schemaContexts=new Map;tenantFeatures=new Map;tenantsByDomainHostname=new Map;constructor(config){this.db=config.db,this.logger=config.logger,this.mainSchemaName=config.mainSchemaName,this.mainSchemaTables=config.mainSchemaTables,this.mainSchemaRelations=config.mainSchemaRelations,this.createAllTablesForSchema=config.createAllTablesForSchema,this.createAllRelationsForSchema=config.createAllRelationsForSchema,this.appId=config.appId,this.authMode=config.authMode,this.tenantResolution=config.tenantResolution,this.tenantHeader=config.tenantHeader,this.redisCacheTtlSeconds=config.redisCacheTtlSeconds,this.defaultTrustedSources=config.defaultTrustedSources,this.idpUrl=config.idpUrl,this.allowDataLoss=config.allowDataLoss===!0,this.onTenantProvisioned=config.onTenantProvisioned}async initialize(){this.logger.info("[TenantRegistry] Initializing..."),this.schemaContexts.set(this.mainSchemaName,{schemaName:this.mainSchemaName,schemaTables:this.mainSchemaTables,schemaRelations:this.mainSchemaRelations,tenant:null});let tenants=await this.loadTenantsFromDb();this.logger.info(`[TenantRegistry] Loaded ${tenants.length} tenants from database`);let features=await this.loadTenantFeaturesFromDb();this.logger.info(`[TenantRegistry] Loaded ${features.length} tenant feature mappings`);for(let tenant of tenants)this.indexTenant(tenant);for(let feature of features){let existing=this.tenantFeatures.get(feature.tenantId)||[];existing.push(feature),this.tenantFeatures.set(feature.tenantId,existing)}let activeTenants=tenants.filter((t)=>t.status==="active");for(let tenant of activeTenants)await this.buildSchemaContext(tenant);await this.loadDomainHostnames(),this.logger.info(`[TenantRegistry] Initialized with ${activeTenants.length} active tenant schemas + main schema`)}resolveFromRequest(request,vettedClientIp){let url=new URL(request.url),host=request.headers.get("host")||url.host||"",normalizedHost=normalizeHost(host);if(normalizedHost){let byHostname=this.tenantsByDomainHostname.get(normalizedHost);if(byHostname)return this.validateAndReturnTenant(byHostname)}if(this.tenantResolution==="subdomain"||this.tenantResolution==="both"){let subdomain=extractSubdomain(host);if(subdomain){let tenant=this.tenantsBySubdomain.get(subdomain);if(tenant)return this.validateAndReturnTenant(tenant);return{resolved:!1,error:`Tenant not found for subdomain: ${subdomain}`,statusCode:404}}}if(this.tenantResolution==="header"||this.tenantResolution==="both"){let tenantIdOrSubdomain=request.headers.get(this.tenantHeader);if(tenantIdOrSubdomain){let result=this.resolveFromHeader(tenantIdOrSubdomain,request,vettedClientIp);if(result)return result}}let mainContext=this.schemaContexts.get(this.mainSchemaName);if(mainContext)return{resolved:!0,context:mainContext};return{resolved:!1,error:"No tenant could be resolved and main schema is unavailable",statusCode:500}}getSchemaContext(schemaName){return this.schemaContexts.get(schemaName)}getMainContext(){let ctx=this.schemaContexts.get(this.mainSchemaName);if(!ctx)throw Error("[TenantRegistry] Main schema context not initialized");return ctx}getActiveTenants(){return Array.from(this.tenantsById.values()).filter((t)=>t.status==="active")}getTenantById(id){return this.tenantsById.get(id)}getTenantBySchemaName(schemaName){return this.tenantsBySchemaName.get(schemaName)}getTenantFeatures(tenantId){return this.tenantFeatures.get(tenantId)||[]}isTenantFeatureEnabled(tenantId,featureName){return(this.tenantFeatures.get(tenantId)||[]).find((f)=>f.featureName===featureName)?.enabled??!1}getTenantIdsWithFeature(featureName){let result=[];for(let[tenantId,features]of this.tenantFeatures)if(features.find((f)=>f.featureName===featureName&&f.enabled))result.push(tenantId);return result}getSchemaNamesWithFeature(featureName){let tenantIds=this.getTenantIdsWithFeature(featureName),schemaNames=[];for(let tenantId of tenantIds){let tenant=this.tenantsById.get(tenantId);if(tenant&&tenant.status==="active")schemaNames.push(tenant.schemaName)}return schemaNames}getAllSchemaNames(){return Array.from(this.schemaContexts.keys())}async provisionTenant(tenant){this.logger.info(`[TenantRegistry] Provisioning tenant: ${tenant.subdomain} \u2192 ${tenant.schemaName}`),await ensureSchemaExists(this.db,tenant.schemaName);let context=await this.buildSchemaContext(tenant);if(this.indexTenant(tenant),await this.syncSchemaToDb(context),this.onTenantProvisioned)try{await this.onTenantProvisioned(context)}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[TenantRegistry] onTenantProvisioned hook failed for ${tenant.schemaName}: ${msg}`)}return this.logger.info(`[TenantRegistry] Tenant provisioned: ${tenant.subdomain}`),context}async syncSchemaToDb(context){let{pushSchema}=await import("drizzle-kit/api"),{applySchemaPush:applySchemaPush2}=await Promise.resolve().then(() => (init_schema(),exports_schema)),targetSchema=pgSchema(context.schemaName);try{let push=await pushSchema({schema:targetSchema,...context.schemaTables},this.db,[context.schemaName]);if(await applySchemaPush2(push,{schemaName:context.schemaName,allowDataLoss:this.allowDataLoss,logger:this.logger}))this.logger.info(`[TenantRegistry] Schema sync completed for: ${context.schemaName}`)}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[TenantRegistry] Schema sync warning for ${context.schemaName}: ${msg}`)}}async syncAllSchemas(){for(let[schemaName,context]of this.schemaContexts)this.logger.info(`[TenantRegistry] Syncing schema: ${schemaName}`),await ensureSchemaExists(this.db,schemaName),await this.syncSchemaToDb(context)}async invalidateCache(subdomain){try{let{getRedisManager:getRedisManager2}=await Promise.resolve().then(() => (init_utils5(),exports_utils)),redis=getRedisManager2();if(redis)await redis.remove(`tenant:${subdomain}`),this.logger.info(`[TenantRegistry] Cache invalidated for: ${subdomain}`)}catch{}}async refreshTenant(tenantId){let tenantsTable=this.mainSchemaTables.tenants;if(!tenantsTable)return;let row=(await this.db.select().from(tenantsTable).where(eq12(tenantsTable.id,tenantId)).limit(1))[0];if(!row)return;let tenant=rowToTenantRecord(row),oldTenant=this.tenantsById.get(tenantId);if(oldTenant)this.tenantsBySubdomain.delete(oldTenant.subdomain),this.tenantsBySchemaName.delete(oldTenant.schemaName);if(this.indexTenant(tenant),tenant.status==="active")await this.buildSchemaContext(tenant);else this.schemaContexts.delete(tenant.schemaName);if(oldTenant)await this.invalidateCache(oldTenant.subdomain);await this.invalidateCache(tenant.subdomain)}async initializeFromIdp(){if(!this.idpUrl){this.logger.error("[TenantRegistry] Consumer multi-tenant requires idpUrl (IDP_URL)");return}this.logger.info(`[TenantRegistry] Initializing from IDP: ${this.idpUrl}`),this.schemaContexts.set(this.mainSchemaName,{schemaName:this.mainSchemaName,schemaTables:this.mainSchemaTables,schemaRelations:this.mainSchemaRelations,tenant:null});let tenants=await this.loadTenantsFromIdp();this.logger.info(`[TenantRegistry] Fetched ${tenants.length} tenants from IDP`);for(let tenant of tenants)this.indexTenant(tenant);let activeTenants=tenants.filter((t)=>t.status==="active");for(let tenant of activeTenants)await this.buildSchemaContext(tenant);await this.loadDomainHostnames(),this.logger.info(`[TenantRegistry] Consumer initialized with ${activeTenants.length} active tenant schemas + main schema`)}isConsumerMode(){return this.authMode==="consumer"&&!!this.idpUrl}async syncFromIdp(){if(!this.isConsumerMode())return{added:[],removed:[],total:this.tenantsById.size};let tenants=await this.loadTenantsFromIdp(),added=[],removed=[],seenSchemaNames=new Set;for(let tenant of tenants){seenSchemaNames.add(tenant.schemaName);let known=this.tenantsById.get(tenant.id);if(known)this.tenantsBySubdomain.delete(known.subdomain),this.tenantsBySchemaName.delete(known.schemaName);if(this.indexTenant(tenant),tenant.status==="active"){if(!this.schemaContexts.has(tenant.schemaName)){await ensureSchemaExists(this.db,tenant.schemaName);let ctx=await this.buildSchemaContext(tenant);await this.syncSchemaToDb(ctx),added.push(tenant.schemaName),await this.invalidateCache(tenant.subdomain),this.logger.info(`[TenantRegistry] Synced new tenant from IDP: ${tenant.subdomain}`)}}else if(this.schemaContexts.has(tenant.schemaName))this.schemaContexts.delete(tenant.schemaName),removed.push(tenant.schemaName),await this.invalidateCache(tenant.subdomain),this.logger.info(`[TenantRegistry] Deactivated tenant context: ${tenant.subdomain}`)}for(let[schemaName,ctx]of this.schemaContexts){if(schemaName===this.mainSchemaName)continue;if(!seenSchemaNames.has(schemaName)){if(this.schemaContexts.delete(schemaName),removed.push(schemaName),ctx.tenant)this.tenantsBySubdomain.delete(ctx.tenant.subdomain),this.tenantsById.delete(ctx.tenant.id),this.tenantsBySchemaName.delete(schemaName),await this.invalidateCache(ctx.tenant.subdomain)}}return{added,removed,total:tenants.length}}registerDomainHostname(hostname,tenantId){let tenant=this.tenantsById.get(tenantId);if(!tenant)return;this.tenantsByDomainHostname.set(normalizeHost(hostname),tenant)}unregisterDomainHostname(hostname){this.tenantsByDomainHostname.delete(normalizeHost(hostname))}async loadDomainHostnames(){let table=this.mainSchemaTables.domainHostnames;if(!table)return 0;try{let rows=await this.db.select().from(table),count=0;this.tenantsByDomainHostname.clear();for(let row of rows){let status=String(row.status??""),tenantId=String(row.tenantId??row.tenant_id??""),hostname=String(row.normalizedHostname??row.normalized_hostname??"");if(status!=="active"||!tenantId||!hostname)continue;let tenant=this.tenantsById.get(tenantId);if(!tenant)continue;this.tenantsByDomainHostname.set(normalizeHost(hostname),tenant),count++}if(count>0)this.logger.info(`[TenantRegistry] Indexed ${count} active custom hostnames`);return count}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.warn(`[TenantRegistry] Failed to load custom hostnames: ${msg}`),0}}async loadTenantsFromIdp(){if(!this.idpUrl)return[];try{let response=await fetch(`${this.idpUrl}/tenants`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!response.ok)return this.logger.warn(`[TenantRegistry] IDP tenant fetch failed: ${response.status} ${response.statusText}`),[];return((await response.json())?.data?.items||[]).map((item)=>rowToTenantRecord(item))}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.warn(`[TenantRegistry] Failed to fetch tenants from IDP: ${msg}`),[]}}async loadTenantsFromDb(){let tenantsTable=this.mainSchemaTables.tenants;if(!tenantsTable)return this.logger.warn("[TenantRegistry] No tenants table found in main schema"),[];try{return(await this.db.select().from(tenantsTable)).map((row)=>rowToTenantRecord(row))}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.warn(`[TenantRegistry] Failed to load tenants: ${msg}`),[]}}async loadTenantFeaturesFromDb(){let featuresTable=this.mainSchemaTables.tenantFeatures;if(!featuresTable)return this.logger.warn("[TenantRegistry] No tenant_features table found in main schema"),[];try{return(await this.db.select().from(featuresTable)).map((row)=>rowToFeatureRecord(row,parseJsonbToConfig))}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.warn(`[TenantRegistry] Failed to load tenant features: ${msg}`),[]}}indexTenant(tenant){if(this.tenantsById.set(tenant.id,tenant),this.tenantsBySubdomain.set(tenant.subdomain,tenant),this.tenantsBySchemaName.set(tenant.schemaName,tenant),tenant.domain)this.tenantsBySubdomain.set(tenant.domain,tenant)}async buildSchemaContext(tenant){let schema=pgSchema(tenant.schemaName),schemaTables=this.createAllTablesForSchema(schema),schemaRelations=this.createAllRelationsForSchema?this.createAllRelationsForSchema(schema):{},context={schemaName:tenant.schemaName,schemaTables,schemaRelations,tenant};return this.schemaContexts.set(tenant.schemaName,context),context}resolveFromHeader(tenantIdOrSubdomain,request,vettedClientIp){let tenant=this.tenantsBySubdomain.get(tenantIdOrSubdomain);if(!tenant)tenant=this.tenantsById.get(tenantIdOrSubdomain);if(!tenant)tenant=this.tenantsBySchemaName.get(tenantIdOrSubdomain);if(!tenant)return{resolved:!1,error:`Tenant not found for header value: ${tenantIdOrSubdomain}`,statusCode:404};if(!isTrustedSource(tenant,request,this.authMode,this.defaultTrustedSources,vettedClientIp))return{resolved:!1,error:`Untrusted source for tenant: ${tenant.subdomain}`,statusCode:403};return this.validateAndReturnTenant(tenant)}validateAndReturnTenant(tenant){if(tenant.status==="suspended")return{resolved:!1,error:`Tenant ${tenant.subdomain} is suspended: ${tenant.suspendedReason||"No reason provided"}`,statusCode:403};if(tenant.status==="provisioning")return{resolved:!1,error:`Tenant ${tenant.subdomain} is still being provisioned`,statusCode:503};if(tenant.status==="archived")return{resolved:!1,error:`Tenant ${tenant.subdomain} has been archived`,statusCode:410};let context=this.schemaContexts.get(tenant.schemaName);if(!context)return{resolved:!1,error:`Schema context not found for tenant: ${tenant.subdomain}`,statusCode:500};return{resolved:!0,context}}}var init_TenantRegistry=__esm(()=>{init_schema()});var init_Tenant=__esm(()=>{init_schema();init_TenantRegistry()});var init_types5=()=>{};import{and as and7,desc as desc2,eq as eq13,inArray as inArray2}from"drizzle-orm";function toCamel2(obj){let result={};for(let[key2,value]of Object.entries(obj)){let camelKey=key2.replace(/_([a-z])/g,(_,c)=>c.toUpperCase());result[camelKey]=value}return result}function fromCamel2(obj){let result={};for(let[key2,value]of Object.entries(obj)){let snakeKey=key2.replace(/[A-Z]/g,(c)=>`_${c.toLowerCase()}`);result[snakeKey]=value}return result}class VerificationService{db;schemaTables;config;logger;onNotificationTrigger;constructor(serviceConfig){this.db=serviceConfig.db,this.schemaTables=serviceConfig.schemaTables,this.config=serviceConfig.config,this.logger=serviceConfig.logger}setNotificationHandler(handler){this.onNotificationTrigger=handler}getConnectedNotificationNodeIds(stepNodeId,steps,edges){let result=new Set,getNeighbors=(nid)=>{let neighbors=[];for(let edge of edges){let{sourceNodeId:src,targetNodeId:tgt}=edge;if(src===nid)neighbors.push(tgt);else if(tgt===nid)neighbors.push(src)}return neighbors},directNeighbors=getNeighbors(stepNodeId);for(let neighborId of directNeighbors)if(steps.find((s)=>s.nodeId===neighborId)?.nodeType==="notification")result.add(neighborId);for(let neighborId of directNeighbors)if(steps.find((s)=>s.nodeId===neighborId)?.nodeType==="verifier"){let verifierNeighbors=getNeighbors(neighborId);for(let vNeighborId of verifierNeighbors){if(vNeighborId===stepNodeId)continue;if(steps.find((s)=>s.nodeId===vNeighborId)?.nodeType==="notification")result.add(vNeighborId)}}let ids=[...result];return this.logger.info(`[Verification] Connected notification nodes for step ${stepNodeId}: [${ids.join(", ")}]`),ids}getTable(name){return resolveSchemaTable(this.schemaTables,name,this.logger)}getCol(table,col6){return table[col6]}async listFlows(entityName){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return[];return(await(entityName?this.db.select().from(flowsTable).where(eq13(this.getCol(flowsTable,"entityName"),entityName)):this.db.select().from(flowsTable))).map((r)=>fromCamel2(r))}async getFlow(flowId){let flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),notifRulesTable=this.getTable("verificationNotificationRules"),notifRecipientsTable=this.getTable("verificationNotificationRecipients"),notifChannelsTable=this.getTable("verificationNotificationChannels");if(!flowsTable)return null;let flowRow=(await this.db.select().from(flowsTable).where(eq13(this.getCol(flowsTable,"id"),flowId)).limit(1))[0];if(!flowRow)return null;let flow=fromCamel2(flowRow),steps=(stepsTable?await this.db.select().from(stepsTable).where(eq13(this.getCol(stepsTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),edges=(edgesTable?await this.db.select().from(edgesTable).where(eq13(this.getCol(edgesTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),verifierConfigs=(verifierConfigsTable?await this.db.select().from(verifierConfigsTable).where(eq13(this.getCol(verifierConfigsTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),notifRules=(notifRulesTable?await this.db.select().from(notifRulesTable).where(eq13(this.getCol(notifRulesTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),ruleIds=notifRules.map((r)=>r.id),notifRecipients=(notifRecipientsTable&&ruleIds.length>0?await this.db.select().from(notifRecipientsTable).where(inArray2(this.getCol(notifRecipientsTable,"ruleId"),ruleIds)):[]).map((r)=>fromCamel2(r)),notifChannels=(notifChannelsTable&&ruleIds.length>0?await this.db.select().from(notifChannelsTable).where(inArray2(this.getCol(notifChannelsTable,"ruleId"),ruleIds)):[]).map((r)=>fromCamel2(r));return{flow,graph:{steps,edges,verifier_configs:verifierConfigs,notification_rules:notifRules,notification_recipients:notifRecipients,notification_channels:notifChannels}}}async saveFlow(params){let flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),notifRulesTable=this.getTable("verificationNotificationRules"),notifRecipientsTable=this.getTable("verificationNotificationRecipients"),notifChannelsTable=this.getTable("verificationNotificationChannels");if(!flowsTable||!stepsTable||!edgesTable)throw Error("Verification tables not configured");let existingFlows=await this.db.select().from(flowsTable).where(eq13(this.getCol(flowsTable,"id"),params.flow_id)).limit(1),flowId=params.flow_id;if(existingFlows.length>0)await this.db.update(flowsTable).set(toCamel2({entity_name:params.entity_name,name:params.name,description:params.description||null,trigger_on:params.trigger_on,trigger_fields:params.trigger_fields||null,is_draft:params.is_draft,viewport:params.viewport||null})).where(eq13(this.getCol(flowsTable,"id"),flowId));else{let[newFlow]=await this.db.insert(flowsTable).values(toCamel2({id:flowId,entity_name:params.entity_name,name:params.name,description:params.description||null,trigger_on:params.trigger_on,trigger_fields:params.trigger_fields||null,is_draft:params.is_draft,viewport:params.viewport||null})).returning();flowId=newFlow.id}if(await this.db.delete(stepsTable).where(eq13(this.getCol(stepsTable,"flowId"),flowId)),edgesTable)await this.db.delete(edgesTable).where(eq13(this.getCol(edgesTable,"flowId"),flowId));if(verifierConfigsTable)await this.db.delete(verifierConfigsTable).where(eq13(this.getCol(verifierConfigsTable,"flowId"),flowId));if(notifRulesTable){let oldRuleIds=(await this.db.select().from(notifRulesTable).where(eq13(this.getCol(notifRulesTable,"flowId"),flowId))).map((r)=>r.id);if(oldRuleIds.length>0){if(notifRecipientsTable)for(let rid of oldRuleIds)await this.db.delete(notifRecipientsTable).where(eq13(this.getCol(notifRecipientsTable,"ruleId"),rid));if(notifChannelsTable)for(let rid of oldRuleIds)await this.db.delete(notifChannelsTable).where(eq13(this.getCol(notifChannelsTable,"ruleId"),rid))}await this.db.delete(notifRulesTable).where(eq13(this.getCol(notifRulesTable,"flowId"),flowId))}let{graph}=params;if(graph.steps.length>0)await this.db.insert(stepsTable).values(graph.steps.map((s)=>toCamel2({flow_id:flowId,entity_name:params.entity_name,node_id:s.node_id,node_type:s.node_type,step_order:s.step_order,name:s.name||null,description:s.description||null,position_x:s.position_x,position_y:s.position_y,width:s.width||null,height:s.height||null,style:s.style||null,data:s.data||null})));if(graph.edges.length>0&&edgesTable)await this.db.insert(edgesTable).values(graph.edges.map((e)=>toCamel2({flow_id:flowId,edge_id:e.edge_id,source_node_id:e.source_node_id,target_node_id:e.target_node_id,source_handle:e.source_handle||null,target_handle:e.target_handle||null,edge_type:e.edge_type,label:e.label||null,condition:e.condition||null,style:e.style||null,animated:e.animated})));if(graph.verifier_configs.length>0&&verifierConfigsTable)await this.db.insert(verifierConfigsTable).values(graph.verifier_configs.map((vc)=>toCamel2({flow_id:flowId,node_id:vc.node_id,verifier_type:vc.verifier_type,verifier_user_id:vc.verifier_user_id||null,verifier_role:vc.verifier_role||null,require_signature:vc.require_signature,all_must_approve:vc.all_must_approve})));if(this.logger.info(`[Verification] Save: ${graph.notification_rules.length} rules, ${graph.notification_recipients.length} recipients, ${graph.notification_channels.length} channels`),graph.notification_rules.length>0&¬ifRulesTable)for(let rule of graph.notification_rules){this.logger.info(`[Verification] Saving notification rule: node_id=${rule.node_id}, trigger=${rule.trigger}, title_template=${JSON.stringify(rule.title_template)}, body_template=${JSON.stringify(rule.body_template)}`);let[insertedRule]=await this.db.insert(notifRulesTable).values(toCamel2({flow_id:flowId,node_id:rule.node_id,trigger:rule.trigger,title_template:rule.title_template||null,body_template:rule.body_template||null,starts_at:rule.starts_at||null,expires_at:rule.expires_at||null})).returning(),ruleId=insertedRule.id,ruleRecipients=graph.notification_recipients.filter((r)=>r.rule_id===rule.node_id);if(ruleRecipients.length>0&¬ifRecipientsTable)await this.db.insert(notifRecipientsTable).values(ruleRecipients.map((r)=>toCamel2({rule_id:ruleId,recipient_type:r.recipient_type,recipient_user_id:r.recipient_user_id||null,recipient_role:r.recipient_role||null})));let ruleChannels=graph.notification_channels.filter((c)=>c.rule_id===rule.node_id);if(ruleChannels.length>0&¬ifChannelsTable)await this.db.insert(notifChannelsTable).values(ruleChannels.map((c)=>toCamel2({rule_id:ruleId,channel:c.channel})))}return this.logger.info(`[Verification] Flow saved: ${flowId} for ${params.entity_name}`),{success:!0,flow_id:flowId}}async publishFlow(flowId){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return{success:!1,message:"Flow table not configured"};return await this.db.update(flowsTable).set(toCamel2({is_draft:!1,published_at:new Date})).where(eq13(this.getCol(flowsTable,"id"),flowId)),this.logger.info(`[Verification] Flow published: ${flowId}`),{success:!0,message:"Flow published"}}async deleteFlow(flowId){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return{success:!1,message:"Flow table not configured"};return await this.db.delete(flowsTable).where(eq13(this.getCol(flowsTable,"id"),flowId)),this.logger.info(`[Verification] Flow deleted: ${flowId}`),{success:!0,message:"Flow deleted"}}async startFlow(params){let flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),instancesTable=this.getTable("verificationInstances"),requirementsTable=this.getTable("verificationRequirements"),userRolesTable=this.getTable("userRoles");if(!flowsTable||!stepsTable||!edgesTable||!instancesTable||!requirementsTable)return{success:!1,message:"Verification tables not configured"};let flow=(await this.db.select().from(flowsTable).where(and7(eq13(this.getCol(flowsTable,"id"),params.flow_id),eq13(this.getCol(flowsTable,"isDraft"),!1))).limit(1))[0];if(!flow)return{success:!1,message:"Published flow not found"};if((await this.db.select().from(instancesTable).where(and7(eq13(this.getCol(instancesTable,"entityName"),params.entity_name),eq13(this.getCol(instancesTable,"entityId"),params.entity_id),eq13(this.getCol(instancesTable,"status"),"active"))).limit(1)).length>0)return{success:!1,message:"An active verification instance already exists for this entity"};let steps=await this.db.select().from(stepsTable).where(eq13(this.getCol(stepsTable,"flowId"),params.flow_id)),edges=await this.db.select().from(edgesTable).where(eq13(this.getCol(edgesTable,"flowId"),params.flow_id)),stepNodes=steps.filter((s)=>s.nodeType==="step");if(stepNodes.sort((a,b)=>a.stepOrder-b.stepOrder),stepNodes.length===0)return{success:!1,message:"Flow has no step nodes"};let[instance]=await this.db.insert(instancesTable).values(toCamel2({flow_id:params.flow_id,entity_name:params.entity_name,entity_id:params.entity_id,started_by:params.started_by||null,status:"active",current_step_order:1,started_at:new Date})).returning(),instanceId=instance.id;if(await this.materializeRequirementsForStep(instanceId,params.flow_id,params.entity_name,params.entity_id,1,steps,edges,verifierConfigsTable,requirementsTable,userRolesTable),this.onNotificationTrigger){let firstStep=stepNodes[0],firstStepNodeId=firstStep?.nodeId,connectedNotifIds=firstStepNodeId?this.getConnectedNotificationNodeIds(firstStepNodeId,steps,edges):[],ctx={flow_name:flow.name,step_name:firstStep?.name||"Step 1",step_order:1,total_steps:stepNodes.length};if(connectedNotifIds.length>0)for(let notifNodeId of connectedNotifIds)await this.onNotificationTrigger({trigger:"on_flow_started",flow_id:params.flow_id,entity_name:params.entity_name,entity_id:params.entity_id,node_id:notifNodeId,context:ctx});else await this.onNotificationTrigger({trigger:"on_flow_started",flow_id:params.flow_id,entity_name:params.entity_name,entity_id:params.entity_id,context:ctx})}return this.logger.info(`[Verification] Flow started: instance ${instanceId} for ${params.entity_name}:${params.entity_id}`),{success:!0,instance_id:instanceId,message:"Flow started"}}async materializeRequirementsForStep(instanceId,flowId,entityName,entityId,stepOrder,steps,edges,verifierConfigsTable,requirementsTable,userRolesTable){if(!requirementsTable)return;let stepNode=steps.find((s)=>s.nodeType==="step"&&s.stepOrder===stepOrder);if(!stepNode)return;let stepNodeId=stepNode.nodeId,verifierNodeIds=edges.filter((e)=>e.targetNodeId===stepNodeId).map((e)=>e.sourceNodeId),verifierNodes=steps.filter((s)=>s.nodeType==="verifier"&&verifierNodeIds.includes(s.nodeId));if(verifierNodes.length===0)return;let verifierConfigs=[];if(verifierConfigsTable)verifierConfigs=await this.db.select().from(verifierConfigsTable).where(eq13(this.getCol(verifierConfigsTable,"flowId"),flowId));for(let verifierNode of verifierNodes){let nodeId=verifierNode.nodeId,config=verifierConfigs.find((vc)=>vc.nodeId===nodeId);if(!config)continue;let{verifierType,allMustApprove}=config;if(verifierType==="role"&&allMustApprove&&userRolesTable){let rolesTable=this.getTable("roles");if(rolesTable){let rolesCols=rolesTable,userRolesCols=userRolesTable,role=(await this.db.select().from(rolesTable).where(eq13(rolesCols.name,config.verifierRole)).limit(1))[0];if(role){let usersWithRole=await this.db.select({user_id:userRolesCols.userId}).from(userRolesTable).where(eq13(userRolesCols.roleId,role.id));for(let userRole of usersWithRole)await this.db.insert(requirementsTable).values(toCamel2({instance_id:instanceId,step_node_id:stepNodeId,verifier_node_id:nodeId,entity_name:entityName,entity_id:entityId,verifier_type:"user",verifier_user_id:userRole.user_id,verifier_role:config.verifierRole||null,require_signature:config.requireSignature,all_must_approve:!0,step_order:stepOrder,status:"pending"}))}}}else await this.db.insert(requirementsTable).values(toCamel2({instance_id:instanceId,step_node_id:stepNodeId,verifier_node_id:nodeId,entity_name:entityName,entity_id:entityId,verifier_type:verifierType,verifier_user_id:config.verifierUserId||null,verifier_role:config.verifierRole||null,require_signature:config.requireSignature,all_must_approve:allMustApprove,step_order:stepOrder,status:"pending"}))}if(this.onNotificationTrigger){let connectedNotifIds=this.getConnectedNotificationNodeIds(stepNodeId,steps,edges);if(this.logger.info(`[Verification] on_step_reached: stepNodeId=${stepNodeId}, connectedNotifIds=[${connectedNotifIds.join(", ")}]`),connectedNotifIds.length>0)for(let notifNodeId of connectedNotifIds)this.logger.info(`[Verification] Triggering on_step_reached for notifNodeId=${notifNodeId}`),await this.onNotificationTrigger({trigger:"on_step_reached",flow_id:flowId,entity_name:entityName,entity_id:entityId,node_id:notifNodeId,context:{step_name:stepNode.name||`Step ${stepOrder}`,step_order:stepOrder}});else await this.onNotificationTrigger({trigger:"on_step_reached",flow_id:flowId,entity_name:entityName,entity_id:entityId,context:{step_name:stepNode.name||`Step ${stepOrder}`,step_order:stepOrder}})}}async getStatus(entityName,entityId){let instancesTable=this.getTable("verificationInstances"),flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),verificationsTable=this.getTable("verifications"),requirementsTable=this.getTable("verificationRequirements"),emptyStatus={entity_name:entityName,entity_id:entityId,instance:null,flow:null,current_step:0,total_steps:0,is_completed:!1,is_rejected:!1,verifications:[],pending_requirements:[]};if(!instancesTable||!flowsTable||!verificationsTable||!requirementsTable)return this.logger.error("[Verification] Required tables not found"),emptyStatus;let instanceRow=(await this.db.select().from(instancesTable).where(and7(eq13(this.getCol(instancesTable,"entityName"),entityName),eq13(this.getCol(instancesTable,"entityId"),entityId))).orderBy(desc2(this.getCol(instancesTable,"createdAt"))).limit(1))[0];if(!instanceRow)return emptyStatus;let instance=fromCamel2(instanceRow),flows=await this.db.select().from(flowsTable).where(eq13(this.getCol(flowsTable,"id"),instance.flow_id)).limit(1),flow=flows[0]?fromCamel2(flows[0]):void 0,totalSteps=(stepsTable?await this.db.select().from(stepsTable).where(and7(eq13(this.getCol(stepsTable,"flowId"),instance.flow_id),eq13(this.getCol(stepsTable,"nodeType"),"step"))):[]).length,verifications=(await this.db.select().from(verificationsTable).where(eq13(this.getCol(verificationsTable,"instanceId"),instance.id)).orderBy(desc2(this.getCol(verificationsTable,"createdAt")))).map((r)=>fromCamel2(r)),pendingRequirements=(await this.db.select().from(requirementsTable).where(and7(eq13(this.getCol(requirementsTable,"instanceId"),instance.id),eq13(this.getCol(requirementsTable,"status"),"pending")))).map((r)=>fromCamel2(r));return{entity_name:entityName,entity_id:entityId,instance,flow:flow||null,current_step:instance.current_step_order,total_steps:totalSteps,is_completed:instance.status==="completed",is_rejected:instance.status==="rejected",verifications,pending_requirements:pendingRequirements}}async decide(params){let{entity_name,entity_id,user_id,decision,reason,signature_id,diff}=params,verificationsTable=this.getTable("verifications"),requirementsTable=this.getTable("verificationRequirements"),instancesTable=this.getTable("verificationInstances"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),userRolesTable=this.getTable("userRoles"),rolesTable=this.getTable("roles");if(!verificationsTable||!requirementsTable||!instancesTable)return{success:!1,message:"Verification tables not configured"};let status=await this.getStatus(entity_name,entity_id);if(!status.instance||status.instance.status!=="active")return{success:!1,message:"No active verification instance"};let currentPending=status.pending_requirements.filter((r)=>r.step_order===status.current_step);if(currentPending.length===0)return{success:!1,message:"No pending requirements for current step"};let matchedReq=null;for(let req of currentPending){if(req.verifier_type==="user"&&req.verifier_user_id===user_id){matchedReq=req;break}if(req.verifier_type==="role"&&req.verifier_role&&userRolesTable&&rolesTable){let userRolesCols=userRolesTable,rolesCols=rolesTable;if((await this.db.select({role_name:rolesCols.name}).from(userRolesTable).innerJoin(rolesTable,eq13(userRolesCols.roleId,rolesCols.id)).where(eq13(userRolesCols.userId,user_id))).some((ur)=>ur.role_name===req.verifier_role)){matchedReq=req;break}}}if(!matchedReq)return{success:!1,message:"User is not authorized to verify at this step"};if(matchedReq.require_signature){if(!signature_id)return{success:!1,message:"Signature is required for this verification step"};let filesTable=resolveSchemaTable(this.schemaTables,"files",this.logger);if(filesTable){if((await this.db.select().from(filesTable).where(and7(eq13(this.getCol(filesTable,"id"),signature_id),eq13(this.getCol(filesTable,"uploadedBy"),user_id))).limit(1)).length===0)return{success:!1,message:"Signature file not found or not owned by the verifier"}}}if((await this.db.update(requirementsTable).set({status:decision}).where(and7(eq13(this.getCol(requirementsTable,"id"),matchedReq.id),eq13(this.getCol(requirementsTable,"status"),"pending"))).returning()).length===0)return{success:!1,message:"This requirement has already been decided"};let[newVerification]=await this.db.insert(verificationsTable).values(toCamel2({instance_id:status.instance.id,requirement_id:matchedReq.id,verifier_id:user_id,signature_id:signature_id||null,entity_name,entity_id,step_order:status.current_step,decision,reason:reason||null,diff:diff||null})).returning();if(this.onNotificationTrigger&&status.instance){let stepName=`Step ${status.current_step}`,allSteps=[],allEdges=[];if(stepsTable){allSteps=await this.db.select().from(stepsTable).where(eq13(this.getCol(stepsTable,"flowId"),status.instance.flow_id));let stepRow=allSteps.find((s)=>s.nodeId===matchedReq.step_node_id);if(stepRow?.name)stepName=stepRow.name}if(edgesTable)allEdges=await this.db.select().from(edgesTable).where(eq13(this.getCol(edgesTable,"flowId"),status.instance.flow_id));let triggerName=decision==="approved"?"on_approved":"on_rejected",ctx={flow_name:status.flow?.name||"",step_name:stepName,step_order:status.current_step,total_steps:status.total_steps,decision},connectedNotifIds=this.getConnectedNotificationNodeIds(matchedReq.step_node_id,allSteps,allEdges);if(connectedNotifIds.length>0)for(let notifNodeId of connectedNotifIds)await this.onNotificationTrigger({trigger:triggerName,flow_id:status.instance.flow_id,entity_name,entity_id,node_id:notifNodeId,verifier_id:user_id,decision,context:ctx});else await this.onNotificationTrigger({trigger:triggerName,flow_id:status.instance.flow_id,entity_name,entity_id,verifier_id:user_id,decision,context:ctx})}if(decision==="rejected"){await this.db.update(instancesTable).set(toCamel2({status:"rejected",completed_at:new Date})).where(eq13(this.getCol(instancesTable,"id"),status.instance.id));let newInstanceId;if(this.config.autoResetOnRejection){this.logger.info(`[Verification] Flow rejected for ${entity_name}:${entity_id}, auto-restarting from step 1`);let restartResult=await this.startFlow({flow_id:status.instance.flow_id,entity_name,entity_id,started_by:status.instance.started_by});if(restartResult.success)newInstanceId=restartResult.instance_id}return{success:!0,message:this.config.autoResetOnRejection?"Verification rejected \u2014 flow restarted from step 1":"Verification rejected",verification:newVerification,flow_completed:!1,new_instance_id:newInstanceId}}let matchedReqId=matchedReq.id,remainingPending=currentPending.filter((r)=>r.id!==matchedReqId);if(remainingPending.length>0)return{success:!0,message:`Step ${status.current_step} partially approved, ${remainingPending.length} verifier(s) remaining`,verification:newVerification,flow_completed:!1};let nextStep=status.current_step+1;if(nextStep>status.total_steps){if(await this.db.update(instancesTable).set(toCamel2({status:"completed",completed_at:new Date})).where(eq13(this.getCol(instancesTable,"id"),status.instance.id)),this.onNotificationTrigger){let completedSteps=[],completedEdges=[];if(stepsTable)completedSteps=await this.db.select().from(stepsTable).where(eq13(this.getCol(stepsTable,"flowId"),status.instance.flow_id));if(edgesTable)completedEdges=await this.db.select().from(edgesTable).where(eq13(this.getCol(edgesTable,"flowId"),status.instance.flow_id));let lastStepNodeId=matchedReq.step_node_id,completedNotifIds=this.getConnectedNotificationNodeIds(lastStepNodeId,completedSteps,completedEdges),completedCtx={flow_name:status.flow?.name||"",step_order:status.current_step,total_steps:status.total_steps};if(completedNotifIds.length>0)for(let notifNodeId of completedNotifIds)await this.onNotificationTrigger({trigger:"on_flow_completed",flow_id:status.instance.flow_id,entity_name,entity_id,node_id:notifNodeId,context:completedCtx});else await this.onNotificationTrigger({trigger:"on_flow_completed",flow_id:status.instance.flow_id,entity_name,entity_id,context:completedCtx})}return{success:!0,message:"Verification flow completed",verification:newVerification,flow_completed:!0}}if(await this.db.update(instancesTable).set(toCamel2({current_step_order:nextStep})).where(eq13(this.getCol(instancesTable,"id"),status.instance.id)),stepsTable&&edgesTable){let steps=await this.db.select().from(stepsTable).where(eq13(this.getCol(stepsTable,"flowId"),status.instance.flow_id)),edges=await this.db.select().from(edgesTable).where(eq13(this.getCol(edgesTable,"flowId"),status.instance.flow_id));await this.materializeRequirementsForStep(status.instance.id,status.instance.flow_id,entity_name,entity_id,nextStep,steps,edges,verifierConfigsTable,requirementsTable,userRolesTable)}return{success:!0,message:`Step ${status.current_step} approved, moving to step ${nextStep}`,verification:newVerification,flow_completed:!1,next_step:nextStep}}async startFlowForEntity(params){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return{success:!1,message:"Flow table not configured"};let flow=(await this.db.select().from(flowsTable).where(and7(eq13(this.getCol(flowsTable,"entityName"),params.entity_name),eq13(this.getCol(flowsTable,"isDraft"),!1))).limit(1))[0];if(!flow)return{success:!1,message:`No published flow found for entity '${params.entity_name}'`};return this.startFlow({flow_id:flow.id,entity_name:params.entity_name,entity_id:params.entity_id,started_by:params.started_by})}async listEntityStatuses(params){let instancesTable=this.getTable("verificationInstances"),flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),emptyResult={items:[],total:0,page:1,limit:20};if(!instancesTable||!flowsTable)return emptyResult;let page=params.page||1,limit=params.limit||20,offset=(page-1)*limit,conditions=[eq13(this.getCol(instancesTable,"entityName"),params.entity_name)];if(params.status)conditions.push(eq13(this.getCol(instancesTable,"status"),params.status));let whereClause=conditions.length===1?conditions[0]:and7(...conditions),allInstances=(await this.db.select().from(instancesTable).where(whereClause).orderBy(desc2(this.getCol(instancesTable,"createdAt")))).map((r)=>fromCamel2(r)),total=allInstances.length,paged=allInstances.slice(offset,offset+limit),items=[];for(let inst of paged){let flowId=inst.flow_id,flows=await this.db.select().from(flowsTable).where(eq13(this.getCol(flowsTable,"id"),flowId)).limit(1),flow=flows[0]?fromCamel2(flows[0]):void 0,totalSteps=0;if(stepsTable)totalSteps=(await this.db.select().from(stepsTable).where(and7(eq13(this.getCol(stepsTable,"flowId"),flowId),eq13(this.getCol(stepsTable,"nodeType"),"step")))).length;items.push({instance_id:inst.id,entity_name:inst.entity_name,entity_id:inst.entity_id,flow_id:flowId,flow_name:flow?.name||"Unknown",status:inst.status,current_step_order:inst.current_step_order,total_steps:totalSteps,started_by:inst.started_by,started_at:inst.started_at,completed_at:inst.completed_at})}return{items,total,page,limit}}async getPending(userId){let requirementsTable=this.getTable("verificationRequirements"),instancesTable=this.getTable("verificationInstances"),flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),userRolesTable=this.getTable("userRoles"),rolesTable=this.getTable("roles");if(this.logger.info(`[Verification.getPending] userId=${userId}, tables: req=${!!requirementsTable} inst=${!!instancesTable} flow=${!!flowsTable} steps=${!!stepsTable} roles=${!!rolesTable} userRoles=${!!userRolesTable}`),!requirementsTable||!instancesTable||!flowsTable)return this.logger.warn("[Verification.getPending] Missing required tables, returning empty"),[];let userRolesCols=userRolesTable,rolesCols=rolesTable,userRoleNames=(userRolesTable&&rolesTable?await this.db.select({role_name:rolesCols.name}).from(userRolesTable).innerJoin(rolesTable,eq13(userRolesCols.roleId,rolesCols.id)).where(eq13(userRolesCols.userId,userId)):[]).map((ur)=>ur.role_name),pendingReqs=(await this.db.select().from(requirementsTable).where(eq13(this.getCol(requirementsTable,"status"),"pending"))).map((r)=>fromCamel2(r));this.logger.info(`[Verification.getPending] Found ${pendingReqs.length} pending requirements, userRoles=${JSON.stringify(userRoleNames)}`);for(let req of pendingReqs)this.logger.info(`[Verification.getPending] Req: verifier_type=${req.verifier_type} verifier_user_id=${req.verifier_user_id} verifier_role=${req.verifier_role} step_order=${req.step_order} entity=${req.entity_name}/${req.entity_id}`);let pendingItems=[];for(let req of pendingReqs){if(!(req.verifier_type==="user"&&req.verifier_user_id===userId||req.verifier_type==="role"&&userRoleNames.includes(req.verifier_role))){this.logger.info(`[Verification.getPending] Skipping req: canVerify=false (type=${req.verifier_type}, reqUserId=${req.verifier_user_id}, loggedInUserId=${userId})`);continue}let instances=await this.db.select().from(instancesTable).where(and7(eq13(this.getCol(instancesTable,"id"),req.instance_id),eq13(this.getCol(instancesTable,"status"),"active"))).limit(1),instance=instances[0]?fromCamel2(instances[0]):void 0;if(!instance)continue;if(instance.current_step_order!==req.step_order)continue;let flows=await this.db.select().from(flowsTable).where(eq13(this.getCol(flowsTable,"id"),instance.flow_id)).limit(1),flow=flows[0]?fromCamel2(flows[0]):void 0;if(!flow)continue;let stepName;if(stepsTable&&req.step_node_id){let stepRow=(await this.db.select().from(stepsTable).where(and7(eq13(this.getCol(stepsTable,"flowId"),instance.flow_id),eq13(this.getCol(stepsTable,"nodeId"),req.step_node_id))).limit(1))[0];if(stepRow?.name)stepName=stepRow.name}pendingItems.push({instance_id:instance.id,entity_name:req.entity_name,entity_id:req.entity_id,flow_name:flow.name,step_order:req.step_order,step_name:stepName,require_signature:req.require_signature,created_at:req.created_at})}return pendingItems}}var init_Verification=__esm(()=>{init_types5()});var genLookup=(target)=>{let lookupTemp=typeof Uint8Array>"u"?[]:new Uint8Array(256),len=64;for(let i=0;i<64;i++)lookupTemp[target.charCodeAt(i)]=i;return lookupTemp},lookup,lookupUrl,base64UrlPattern,base64Pattern,base64,base64_default;var init_base64=__esm(()=>{lookup=genLookup("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),lookupUrl=genLookup("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),base64UrlPattern=/^[-A-Za-z0-9\-_]*$/,base64Pattern=/^[-A-Za-z0-9+/]*={0,3}$/,base64={};base64.toArrayBuffer=(data,urlMode)=>{let len=data.length,bufferLength=data.length*0.75,i,p=0,encoded1,encoded2,encoded3,encoded4;if(data[data.length-1]==="="){if(bufferLength--,data[data.length-2]==="=")bufferLength--}let arraybuffer=new ArrayBuffer(bufferLength),bytes=new Uint8Array(arraybuffer),target=urlMode?lookupUrl:lookup;for(i=0;i<len;i+=4)encoded1=target[data.charCodeAt(i)],encoded2=target[data.charCodeAt(i+1)],encoded3=target[data.charCodeAt(i+2)],encoded4=target[data.charCodeAt(i+3)],bytes[p++]=encoded1<<2|encoded2>>4,bytes[p++]=(encoded2&15)<<4|encoded3>>2,bytes[p++]=(encoded3&3)<<6|encoded4&63;return arraybuffer};base64.fromArrayBuffer=(arrBuf,urlMode)=>{let bytes=new Uint8Array(arrBuf),i,result="",len=bytes.length,target=urlMode?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(i=0;i<len;i+=3)result+=target[bytes[i]>>2],result+=target[(bytes[i]&3)<<4|bytes[i+1]>>4],result+=target[(bytes[i+1]&15)<<2|bytes[i+2]>>6],result+=target[bytes[i+2]&63];let remainder=len%3;if(remainder===2)result=result.substring(0,result.length-1)+(urlMode?"":"=");else if(remainder===1)result=result.substring(0,result.length-2)+(urlMode?"":"==");return result};base64.toString=(str3,urlMode)=>{return new TextDecoder().decode(base64.toArrayBuffer(str3,urlMode))};base64.fromString=(str3,urlMode)=>{return base64.fromArrayBuffer(new TextEncoder().encode(str3),urlMode)};base64.validate=(encoded,urlMode)=>{if(!(typeof encoded==="string"||encoded instanceof String))return!1;try{return urlMode?base64UrlPattern.test(encoded):base64Pattern.test(encoded)}catch(_e){return!1}};base64.base64=base64;base64_default=base64});var exports_isoBase64URL={};__export(exports_isoBase64URL,{trimPadding:()=>trimPadding,toUTF8String:()=>toUTF8String,toBuffer:()=>toBuffer,toBase64:()=>toBase64,isBase64URL:()=>isBase64URL,isBase64:()=>isBase64,fromUTF8String:()=>fromUTF8String,fromBuffer:()=>fromBuffer});function toBuffer(base64urlString,from="base64url"){let _buffer=base64_default.toArrayBuffer(base64urlString,from==="base64url");return new Uint8Array(_buffer)}function fromBuffer(buffer,to="base64url"){let _normalized=new Uint8Array(buffer);return base64_default.fromArrayBuffer(_normalized.buffer,to==="base64url")}function toBase64(base64urlString){let fromBase64Url=base64_default.toArrayBuffer(base64urlString,!0);return base64_default.fromArrayBuffer(fromBase64Url)}function fromUTF8String(utf8String){return base64_default.fromString(utf8String,!0)}function toUTF8String(base64urlString){return base64_default.toString(base64urlString,!0)}function isBase64(input){return base64_default.validate(input,!1)}function isBase64URL(input){return input=trimPadding(input),base64_default.validate(input,!0)}function trimPadding(input){return input.replace(/=/g,"")}var init_isoBase64URL=__esm(()=>{init_base64()});function decodeLength(data,argument,index){if(argument<24)return[argument,1];let remainingDataLength=data.byteLength-index-1,view=new DataView(data.buffer,index+1),output,bytes=0;switch(argument){case 24:{if(remainingDataLength>0)output=view.getUint8(0),bytes=2;break}case 25:{if(remainingDataLength>1)output=view.getUint16(0,!1),bytes=3;break}case 26:{if(remainingDataLength>3)output=view.getUint32(0,!1),bytes=5;break}case 27:{if(remainingDataLength>7){let bigOutput=view.getBigUint64(0,!1);if(bigOutput>=24n&&bigOutput<=Number.MAX_SAFE_INTEGER)return[Number(bigOutput),9]}break}}if(output&&output>=24)return[output,bytes];throw Error("Length not supported or not well formed")}function encodeLength(major,argument){let majorEncoded=major<<5;if(argument<0)throw Error("CBOR Data Item argument must not be negative");let bigintArgument;if(typeof argument=="number"){if(!Number.isInteger(argument))throw Error("CBOR Data Item argument must be an integer");bigintArgument=BigInt(argument)}else bigintArgument=argument;if(major==MAJOR_TYPE_NEGATIVE_INTEGER){if(bigintArgument==0n)throw Error("CBOR Data Item argument cannot be zero when negative");bigintArgument=bigintArgument-1n}if(bigintArgument>18446744073709551615n)throw Error("CBOR number out of range");let buffer=new Uint8Array(8);if(new DataView(buffer.buffer).setBigUint64(0,bigintArgument,!1),bigintArgument<=23)return[majorEncoded|buffer[7]];else if(bigintArgument<=255)return[majorEncoded|24,buffer[7]];else if(bigintArgument<=65535)return[majorEncoded|25,...buffer.slice(6)];else if(bigintArgument<=4294967295)return[majorEncoded|26,...buffer.slice(4)];else return[majorEncoded|27,...buffer]}var MAJOR_TYPE_UNSIGNED_INTEGER=0,MAJOR_TYPE_NEGATIVE_INTEGER=1,MAJOR_TYPE_BYTE_STRING=2,MAJOR_TYPE_TEXT_STRING=3,MAJOR_TYPE_ARRAY=4,MAJOR_TYPE_MAP=5,MAJOR_TYPE_TAG=6,MAJOR_TYPE_SIMPLE_OR_FLOAT=7;class CBORTag{constructor(tag,value){Object.defineProperty(this,"tagId",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"tagValue",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.tagId=tag,this.tagValue=value}get tag(){return this.tagId}get value(){return this.tagValue}}function decodeUnsignedInteger(data,argument,index){return decodeLength(data,argument,index)}function decodeNegativeInteger(data,argument,index){let[value,length]=decodeUnsignedInteger(data,argument,index);return[-value-1,length]}function decodeByteString(data,argument,index){let[lengthValue,lengthConsumed]=decodeLength(data,argument,index),dataStartIndex=index+lengthConsumed;return[new Uint8Array(data.buffer.slice(dataStartIndex,dataStartIndex+lengthValue)),lengthConsumed+lengthValue]}function decodeString(data,argument,index){let[value,length]=decodeByteString(data,argument,index);return[TEXT_DECODER.decode(value),length]}function decodeArray(data,argument,index){if(argument===0)return[[],1];let[length,lengthConsumed]=decodeLength(data,argument,index),consumedLength=lengthConsumed,value=[];for(let i=0;i<length;i++){if(data.byteLength-index-consumedLength<=0)throw Error("array is not supported or well formed");let[decodedValue,consumed]=decodeNext(data,index+consumedLength);value.push(decodedValue),consumedLength+=consumed}return[value,consumedLength]}function decodeMap(data,argument,index){if(argument===0)return[new Map,1];let[length,lengthConsumed]=decodeLength(data,argument,index),consumedLength=lengthConsumed,result=new Map;for(let i=0;i<length;i++){let remainingDataLength=data.byteLength-index-consumedLength;if(remainingDataLength<=0)throw Error(MAP_ERROR);let[key2,keyConsumed]=decodeNext(data,index+consumedLength);if(consumedLength+=keyConsumed,remainingDataLength-=keyConsumed,remainingDataLength<=0)throw Error(MAP_ERROR);if(typeof key2!=="string"&&typeof key2!=="number")throw Error(MAP_ERROR);if(result.has(key2))throw Error(MAP_ERROR);let[value,valueConsumed]=decodeNext(data,index+consumedLength);consumedLength+=valueConsumed,result.set(key2,value)}return[result,consumedLength]}function decodeFloat16(data,index){if(index+3>data.byteLength)throw Error("CBOR stream ended before end of Float 16");let result=data.getUint16(index+1,!1);if(result==31744)return[1/0,3];else if(result==32256)return[NaN,3];else if(result==64512)return[-1/0,3];throw Error("Float16 data is unsupported")}function decodeFloat32(data,index){if(index+5>data.byteLength)throw Error("CBOR stream ended before end of Float 32");return[data.getFloat32(index+1,!1),5]}function decodeFloat64(data,index){if(index+9>data.byteLength)throw Error("CBOR stream ended before end of Float 64");return[data.getFloat64(index+1,!1),9]}function decodeTag(data,argument,index){let[tag,tagBytes]=decodeLength(data,argument,index),[value,valueBytes]=decodeNext(data,index+tagBytes);return[new CBORTag(tag,value),tagBytes+valueBytes]}function decodeNext(data,index){if(index>=data.byteLength)throw Error("CBOR stream ended before tag value");let byte=data.getUint8(index),majorType=byte>>5,argument=byte&31;switch(majorType){case MAJOR_TYPE_UNSIGNED_INTEGER:return decodeUnsignedInteger(data,argument,index);case MAJOR_TYPE_NEGATIVE_INTEGER:return decodeNegativeInteger(data,argument,index);case MAJOR_TYPE_BYTE_STRING:return decodeByteString(data,argument,index);case MAJOR_TYPE_TEXT_STRING:return decodeString(data,argument,index);case MAJOR_TYPE_ARRAY:return decodeArray(data,argument,index);case MAJOR_TYPE_MAP:return decodeMap(data,argument,index);case MAJOR_TYPE_TAG:return decodeTag(data,argument,index);case MAJOR_TYPE_SIMPLE_OR_FLOAT:switch(argument){case 20:return[!1,1];case 21:return[!0,1];case 22:return[null,1];case 23:return[void 0,1];case 25:return decodeFloat16(data,index);case 26:return decodeFloat32(data,index);case 27:return decodeFloat64(data,index)}}throw Error(`Unsupported or not well formed at ${index}`)}function encodeSimple(data){if(data===!0)return 245;else if(data===!1)return 244;else if(data===null)return 246;return 247}function encodeFloat(data){if(Math.fround(data)==data||!Number.isFinite(data)||Number.isNaN(data)){let output=new Uint8Array(5);return output[0]=250,new DataView(output.buffer).setFloat32(1,data,!1),output}else{let output=new Uint8Array(9);return output[0]=251,new DataView(output.buffer).setFloat64(1,data,!1),output}}function encodeNumber(data){if(typeof data=="number"){if(Number.isSafeInteger(data))if(data<0)return encodeLength(MAJOR_TYPE_NEGATIVE_INTEGER,Math.abs(data));else return encodeLength(MAJOR_TYPE_UNSIGNED_INTEGER,data);return[encodeFloat(data)]}else if(data<0n)return encodeLength(MAJOR_TYPE_NEGATIVE_INTEGER,data*-1n);else return encodeLength(MAJOR_TYPE_UNSIGNED_INTEGER,data)}function encodeString(data,output){output.push(...encodeLength(MAJOR_TYPE_TEXT_STRING,data.length)),output.push(ENCODER.encode(data))}function encodeBytes(data,output){output.push(...encodeLength(MAJOR_TYPE_BYTE_STRING,data.length)),output.push(data)}function encodeArray(data,output){output.push(...encodeLength(MAJOR_TYPE_ARRAY,data.length));for(let element of data)encodePartialCBOR(element,output)}function encodeMap(data,output){output.push(new Uint8Array(encodeLength(MAJOR_TYPE_MAP,data.size)));for(let[key2,value]of data.entries())encodePartialCBOR(key2,output),encodePartialCBOR(value,output)}function encodeTag(tag,output){output.push(...encodeLength(MAJOR_TYPE_TAG,tag.tag)),encodePartialCBOR(tag.value,output)}function encodePartialCBOR(data,output){if(typeof data=="boolean"||data===null||data==null){output.push(encodeSimple(data));return}if(typeof data=="number"||typeof data=="bigint"){output.push(...encodeNumber(data));return}if(typeof data=="string"){encodeString(data,output);return}if(data instanceof Uint8Array){encodeBytes(data,output);return}if(Array.isArray(data)){encodeArray(data,output);return}if(data instanceof Map){encodeMap(data,output);return}if(data instanceof CBORTag){encodeTag(data,output);return}throw Error("Not implemented")}function decodePartialCBOR(data,index){if(data.byteLength===0||data.byteLength<=index||index<0)throw Error("No data");if(data instanceof Uint8Array)return decodeNext(new DataView(data.buffer),index);else if(data instanceof ArrayBuffer)return decodeNext(new DataView(data),index);return decodeNext(data,index)}function encodeCBOR(data){let results=[];encodePartialCBOR(data,results);let length=0;for(let result of results)if(typeof result=="number")length+=1;else length+=result.length;let output=new Uint8Array(length),index=0;for(let result of results)if(typeof result=="number")output[index]=result,index+=1;else output.set(result,index),index+=result.length;return output}var TEXT_DECODER,MAP_ERROR="Map is not supported or well formed",ENCODER;var init_cbor=__esm(()=>{TEXT_DECODER=new TextDecoder;ENCODER=new TextEncoder});var init_esm=__esm(()=>{init_cbor()});var exports_isoCBOR={};__export(exports_isoCBOR,{encode:()=>encode,decodeFirst:()=>decodeFirst});function decodeFirst(input){let _input=new Uint8Array(input),decoded=decodePartialCBOR(_input,0),[first]=decoded;return first}function encode(input){return encodeCBOR(input)}var init_isoCBOR=__esm(()=>{init_esm()});function isCOSEPublicKeyOKP(cosePublicKey){let kty=cosePublicKey.get(COSEKEYS.kty);return isCOSEKty(kty)&&kty===COSEKTY.OKP}function isCOSEPublicKeyEC2(cosePublicKey){let kty=cosePublicKey.get(COSEKEYS.kty);return isCOSEKty(kty)&&kty===COSEKTY.EC2}function isCOSEPublicKeyRSA(cosePublicKey){let kty=cosePublicKey.get(COSEKEYS.kty);return isCOSEKty(kty)&&kty===COSEKTY.RSA}function isCOSEKty(kty){return Object.values(COSEKTY).indexOf(kty)>=0}function isCOSECrv(crv){return Object.values(COSECRV).indexOf(crv)>=0}function isCOSEAlg(alg){return Object.values(COSEALG).indexOf(alg)>=0}var COSEKEYS,COSEKTY,COSECRV,COSEALG;var init_cose=__esm(()=>{(function(COSEKEYS2){COSEKEYS2[COSEKEYS2.kty=1]="kty",COSEKEYS2[COSEKEYS2.alg=3]="alg",COSEKEYS2[COSEKEYS2.crv=-1]="crv",COSEKEYS2[COSEKEYS2.x=-2]="x",COSEKEYS2[COSEKEYS2.y=-3]="y",COSEKEYS2[COSEKEYS2.n=-1]="n",COSEKEYS2[COSEKEYS2.e=-2]="e"})(COSEKEYS||(COSEKEYS={}));(function(COSEKTY2){COSEKTY2[COSEKTY2.OKP=1]="OKP",COSEKTY2[COSEKTY2.EC2=2]="EC2",COSEKTY2[COSEKTY2.RSA=3]="RSA"})(COSEKTY||(COSEKTY={}));(function(COSECRV2){COSECRV2[COSECRV2.P256=1]="P256",COSECRV2[COSECRV2.P384=2]="P384",COSECRV2[COSECRV2.P521=3]="P521",COSECRV2[COSECRV2.ED25519=6]="ED25519",COSECRV2[COSECRV2.SECP256K1=8]="SECP256K1"})(COSECRV||(COSECRV={}));(function(COSEALG2){COSEALG2[COSEALG2.ES256=-7]="ES256",COSEALG2[COSEALG2.EdDSA=-8]="EdDSA",COSEALG2[COSEALG2.ES384=-35]="ES384",COSEALG2[COSEALG2.ES512=-36]="ES512",COSEALG2[COSEALG2.PS256=-37]="PS256",COSEALG2[COSEALG2.PS384=-38]="PS384",COSEALG2[COSEALG2.PS512=-39]="PS512",COSEALG2[COSEALG2.ES256K=-47]="ES256K",COSEALG2[COSEALG2.RS256=-257]="RS256",COSEALG2[COSEALG2.RS384=-258]="RS384",COSEALG2[COSEALG2.RS512=-259]="RS512",COSEALG2[COSEALG2.RS1=-65535]="RS1"})(COSEALG||(COSEALG={}))});function mapCoseAlgToWebCryptoAlg(alg){if([COSEALG.RS1].indexOf(alg)>=0)return"SHA-1";else if([COSEALG.ES256,COSEALG.PS256,COSEALG.RS256].indexOf(alg)>=0)return"SHA-256";else if([COSEALG.ES384,COSEALG.PS384,COSEALG.RS384].indexOf(alg)>=0)return"SHA-384";else if([COSEALG.ES512,COSEALG.PS512,COSEALG.RS512,COSEALG.EdDSA].indexOf(alg)>=0)return"SHA-512";throw Error(`Could not map COSE alg value of ${alg} to a WebCrypto alg`)}var init_mapCoseAlgToWebCryptoAlg=__esm(()=>{init_cose()});function getWebCrypto(){return new Promise((resolve2,reject)=>{if(webCrypto)return resolve2(webCrypto);let _globalThisCrypto=_getWebCryptoInternals.stubThisGlobalThisCrypto();if(_globalThisCrypto)return webCrypto=_globalThisCrypto,resolve2(webCrypto);return reject(new MissingWebCrypto)})}var webCrypto=void 0,MissingWebCrypto,_getWebCryptoInternals;var init_getWebCrypto=__esm(()=>{MissingWebCrypto=class MissingWebCrypto extends Error{constructor(){super("An instance of the Crypto API could not be located");this.name="MissingWebCrypto"}};_getWebCryptoInternals={stubThisGlobalThisCrypto:()=>globalThis.crypto,setCachedCrypto:(newCrypto)=>{webCrypto=newCrypto}}});async function digest(data,algorithm){let WebCrypto=await getWebCrypto(),subtleAlgorithm=mapCoseAlgToWebCryptoAlg(algorithm),hashed=await WebCrypto.subtle.digest(subtleAlgorithm,data);return new Uint8Array(hashed)}var init_digest=__esm(()=>{init_mapCoseAlgToWebCryptoAlg();init_getWebCrypto()});async function getRandomValues(array){return(await getWebCrypto()).getRandomValues(array),array}var init_getRandomValues=__esm(()=>{init_getWebCrypto()});async function importKey(opts){let WebCrypto=await getWebCrypto(),{keyData,algorithm}=opts;return WebCrypto.subtle.importKey("jwk",keyData,algorithm,!1,["verify"])}var init_importKey=__esm(()=>{init_getWebCrypto()});async function verifyEC2(opts){let{cosePublicKey,signature,data,shaHashOverride}=opts,WebCrypto=await getWebCrypto(),alg=cosePublicKey.get(COSEKEYS.alg),crv=cosePublicKey.get(COSEKEYS.crv),x=cosePublicKey.get(COSEKEYS.x),y=cosePublicKey.get(COSEKEYS.y);if(!alg)throw Error("Public key was missing alg (EC2)");if(!crv)throw Error("Public key was missing crv (EC2)");if(!x)throw Error("Public key was missing x (EC2)");if(!y)throw Error("Public key was missing y (EC2)");let _crv;if(crv===COSECRV.P256)_crv="P-256";else if(crv===COSECRV.P384)_crv="P-384";else if(crv===COSECRV.P521)_crv="P-521";else throw Error(`Unexpected COSE crv value of ${crv} (EC2)`);let keyData={kty:"EC",crv:_crv,x:exports_isoBase64URL.fromBuffer(x),y:exports_isoBase64URL.fromBuffer(y),ext:!1},key2=await importKey({keyData,algorithm:{name:"ECDSA",namedCurve:_crv}}),subtleAlg=mapCoseAlgToWebCryptoAlg(alg);if(shaHashOverride)subtleAlg=mapCoseAlgToWebCryptoAlg(shaHashOverride);let verifyAlgorithm={name:"ECDSA",hash:{name:subtleAlg}};return WebCrypto.subtle.verify(verifyAlgorithm,key2,signature,data)}var init_verifyEC2=__esm(()=>{init_cose();init_mapCoseAlgToWebCryptoAlg();init_importKey();init_iso();init_getWebCrypto()});function mapCoseAlgToWebCryptoKeyAlgName(alg){if([COSEALG.EdDSA].indexOf(alg)>=0)return"Ed25519";else if([COSEALG.ES256,COSEALG.ES384,COSEALG.ES512,COSEALG.ES256K].indexOf(alg)>=0)return"ECDSA";else if([COSEALG.RS256,COSEALG.RS384,COSEALG.RS512,COSEALG.RS1].indexOf(alg)>=0)return"RSASSA-PKCS1-v1_5";else if([COSEALG.PS256,COSEALG.PS384,COSEALG.PS512].indexOf(alg)>=0)return"RSA-PSS";throw Error(`Could not map COSE alg value of ${alg} to a WebCrypto key alg name`)}var init_mapCoseAlgToWebCryptoKeyAlgName=__esm(()=>{init_cose()});async function verifyRSA(opts){let{cosePublicKey,signature,data,shaHashOverride}=opts,WebCrypto=await getWebCrypto(),alg=cosePublicKey.get(COSEKEYS.alg),n=cosePublicKey.get(COSEKEYS.n),e=cosePublicKey.get(COSEKEYS.e);if(!alg)throw Error("Public key was missing alg (RSA)");if(!isCOSEAlg(alg))throw Error(`Public key had invalid alg ${alg} (RSA)`);if(!n)throw Error("Public key was missing n (RSA)");if(!e)throw Error("Public key was missing e (RSA)");let keyData={kty:"RSA",alg:"",n:exports_isoBase64URL.fromBuffer(n),e:exports_isoBase64URL.fromBuffer(e),ext:!1},keyAlgorithm={name:mapCoseAlgToWebCryptoKeyAlgName(alg),hash:{name:mapCoseAlgToWebCryptoAlg(alg)}},verifyAlgorithm={name:mapCoseAlgToWebCryptoKeyAlgName(alg)};if(shaHashOverride)keyAlgorithm.hash.name=mapCoseAlgToWebCryptoAlg(shaHashOverride);if(keyAlgorithm.name==="RSASSA-PKCS1-v1_5"){if(keyAlgorithm.hash.name==="SHA-256")keyData.alg="RS256";else if(keyAlgorithm.hash.name==="SHA-384")keyData.alg="RS384";else if(keyAlgorithm.hash.name==="SHA-512")keyData.alg="RS512";else if(keyAlgorithm.hash.name==="SHA-1")keyData.alg="RS1"}else if(keyAlgorithm.name==="RSA-PSS"){let saltLength=0;if(keyAlgorithm.hash.name==="SHA-256")keyData.alg="PS256",saltLength=32;else if(keyAlgorithm.hash.name==="SHA-384")keyData.alg="PS384",saltLength=48;else if(keyAlgorithm.hash.name==="SHA-512")keyData.alg="PS512",saltLength=64;verifyAlgorithm.saltLength=saltLength}else throw Error(`Unexpected RSA key algorithm ${alg} (${keyAlgorithm.name})`);let key2=await importKey({keyData,algorithm:keyAlgorithm});return WebCrypto.subtle.verify(verifyAlgorithm,key2,signature,data)}var init_verifyRSA=__esm(()=>{init_cose();init_mapCoseAlgToWebCryptoAlg();init_importKey();init_iso();init_mapCoseAlgToWebCryptoKeyAlgName();init_getWebCrypto()});function convertAAGUIDToString(aaguid){let hex=exports_isoUint8Array.toHex(aaguid);return[hex.slice(0,8),hex.slice(8,12),hex.slice(12,16),hex.slice(16,20),hex.slice(20,32)].join("-")}var init_convertAAGUIDToString=__esm(()=>{init_iso()});function convertCertBufferToPEM(certBuffer){let b64cert;if(typeof certBuffer==="string")if(exports_isoBase64URL.isBase64URL(certBuffer))b64cert=exports_isoBase64URL.toBase64(certBuffer);else if(exports_isoBase64URL.isBase64(certBuffer))b64cert=certBuffer;else throw Error("Certificate is not a valid base64 or base64url string");else b64cert=exports_isoBase64URL.fromBuffer(certBuffer,"base64");let PEMKey="";for(let i=0;i<Math.ceil(b64cert.length/64);i+=1){let start=64*i;PEMKey+=`${b64cert.substr(start,64)}
|
|
101
|
+
`,RateLimiterBackendError,DEFAULT_AUTH_LOGIN,DEFAULT_AUTH_REGISTER,DEFAULT_AUTH_PASSWORD_RESET,DEFAULT_AUTH_MAGIC_LINK,DEFAULT_CONFIG4;var init_RateLimiter=__esm(()=>{RateLimiterBackendError=class RateLimiterBackendError extends Error{constructor(message){super(message);this.name="RateLimiterBackendError"}};DEFAULT_AUTH_LOGIN={window:"15m",max:5,blockDuration:"30m"},DEFAULT_AUTH_REGISTER={window:"1h",max:3,blockDuration:"1h"},DEFAULT_AUTH_PASSWORD_RESET={window:"1h",max:3,blockDuration:"1h"},DEFAULT_AUTH_MAGIC_LINK={window:"1h",max:5,blockDuration:"1h"},DEFAULT_CONFIG4={enabled:!0,strategy:"sliding-window",keyPrefix:"rl:",authRoutes:{window:"1m",max:10,login:DEFAULT_AUTH_LOGIN,register:DEFAULT_AUTH_REGISTER,passwordReset:DEFAULT_AUTH_PASSWORD_RESET,magicLink:DEFAULT_AUTH_MAGIC_LINK},publicRoutes:{window:"1m",max:100},privateRoutes:{window:"1m",max:60},byIp:!0,byUserId:!0,byEndpoint:!1,skipSuccessfulRequests:!1,headers:{remaining:"X-RateLimit-Remaining",reset:"X-RateLimit-Reset",limit:"X-RateLimit-Limit"},whitelist:[],blacklist:[]}});var exports_schema={};__export(exports_schema,{ensureSchemaExists:()=>ensureSchemaExists,applySchemaPush:()=>applySchemaPush});import{sql as sql4}from"drizzle-orm";var validateIdentifier=(name)=>{if(!name||name.length>63)throw Error(`Invalid identifier: must be 1-63 characters, got ${name.length}`);if(!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name))throw Error(`Invalid identifier: "${name}" contains unsafe characters`);return name},ensureSchemaExists=async(db,schemaName)=>{let safeName=validateIdentifier(schemaName);await db.execute(sql4.raw(`CREATE SCHEMA IF NOT EXISTS "${safeName}"`))},applySchemaPush=async(push,opts)=>{let{schemaName,allowDataLoss,logger:logger2}=opts;if(push.hasDataLoss&&!allowDataLoss)return logger2.error(`[Schema] Destructive changes detected for schema "${schemaName}" but database.allowDataLoss is not enabled \u2014 skipping schema sync for this schema. Set database.allowDataLoss: true to apply them.`,{warnings:push.warnings,statements:push.statementsToExecute}),!1;if(push.hasDataLoss)logger2.warn(`[Schema] Applying destructive changes to schema "${schemaName}" (database.allowDataLoss=true)`,{warnings:push.warnings});return await push.apply(),!0};var init_schema=()=>{};var rowToTenantRecord=(row)=>({id:String(row.id||""),subdomain:String(row.subdomain||""),schemaName:String(row.schemaName||row.schema_name||""),companyId:String(row.companyId||row.company_id||""),companyName:row.companyName!=null?String(row.companyName):row.company_name!=null?String(row.company_name):null,godAdminEmail:String(row.godAdminEmail||row.god_admin_email||""),status:parseStatus(row.status),plan:row.plan!=null?String(row.plan):null,domain:row.domain!=null?String(row.domain):null,settings:parseJsonbToConfig(row.settings),trustedSources:parseTrustedSources(row.trustedSources||row.trusted_sources),maxUsers:row.maxUsers!=null?Number(row.maxUsers):row.max_users!=null?Number(row.max_users):null,provisionedAt:row.provisionedAt!=null?String(row.provisionedAt):row.provisioned_at!=null?String(row.provisioned_at):null,suspendedAt:row.suspendedAt!=null?String(row.suspendedAt):row.suspended_at!=null?String(row.suspended_at):null,suspendedReason:row.suspendedReason!=null?String(row.suspendedReason):row.suspended_reason!=null?String(row.suspended_reason):null}),rowToFeatureRecord=(row,parseConfig)=>({id:String(row.id||""),tenantId:String(row.tenantId||row.tenant_id||""),featureName:String(row.featureName||row.feature_name||""),enabled:Boolean(row.enabled),featureConfig:parseConfig(row.config)}),parseStatus=(value)=>{let valid=["provisioning","active","suspended","archived"],str3=String(value||"provisioning");return valid.includes(str3)?str3:"provisioning"},parseJsonbToConfig=(value)=>{if(!value||typeof value!=="object")return{};let result={};for(let[k,v]of Object.entries(value))if(typeof v==="string"||typeof v==="number"||typeof v==="boolean")result[k]=v;return result},parseTrustedSources=(value)=>{if(!Array.isArray(value))return[];return value.map((item)=>{let entry=item;return{allowHeaderAuth:entry.allowHeaderAuth===!0||entry.allow_header_auth===!0,allowedIps:Array.isArray(entry.allowedIps||entry.allowed_ips)?entry.allowedIps||entry.allowed_ips:void 0,allowedServices:Array.isArray(entry.allowedServices||entry.allowed_services)?entry.allowedServices||entry.allowed_services:void 0}})},normalizeHost=(host)=>{return((host||"").split(":")[0]||"").toLowerCase().replace(/\.$/,"")},extractSubdomain=(host)=>{let hostWithoutPort=host.split(":")[0]||"";if(hostWithoutPort==="localhost"||/^\d+\.\d+\.\d+\.\d+$/.test(hostWithoutPort))return null;let parts=hostWithoutPort.split(".");if(parts.length<3)return null;let subdomain=parts[0]||"";if(!subdomain||subdomain==="www")return null;return subdomain},isIpInCidr=(ip,cidr)=>{let[cidrIp,prefixStr]=cidr.split("/");if(!cidrIp||!prefixStr)return!1;let prefix=Number.parseInt(prefixStr,10);if(Number.isNaN(prefix))return!1;let ipParts=ip.split(".").map(Number),cidrParts=cidrIp.split(".").map(Number);if(ipParts.length!==4||cidrParts.length!==4)return!1;let ipNum=(ipParts[0]||0)<<24|(ipParts[1]||0)<<16|(ipParts[2]||0)<<8|(ipParts[3]||0),cidrNum=(cidrParts[0]||0)<<24|(cidrParts[1]||0)<<16|(cidrParts[2]||0)<<8|(cidrParts[3]||0),mask=~((1<<32-prefix)-1);return(ipNum&mask)===(cidrNum&mask)},isTrustedSource=(tenant,request,authMode,fallbackSources,vettedClientIp)=>{let ownSources=tenant.trustedSources,trustedSources=Array.isArray(ownSources)&&ownSources.length>0?ownSources:fallbackSources;if(!trustedSources||!Array.isArray(trustedSources)||trustedSources.length===0)return!1;let clientIp=vettedClientIp?.trim()||"",serviceId=request.headers.get("x-service-id")||"";for(let source of trustedSources){if(!source.allowHeaderAuth)continue;if(source.allowedIps&&source.allowedIps.length>0){if(source.allowedIps.some((allowedIp)=>{if(allowedIp.includes("/"))return isIpInCidr(clientIp,allowedIp);return clientIp===allowedIp}))return!0}if(source.allowedServices&&source.allowedServices.length>0){if(source.allowedServices.includes(serviceId))return!0}}return!1};function getDatabaseAuthMode(){return process.env.DATABASE_AUTH_MODE||"password"}function getRedisAuthMode(){return process.env.REDIS_AUTH_MODE||"password"}async function acquireToken(scope,label){let{DefaultAzureCredential,ManagedIdentityCredential,ClientSecretCredential}=await import("@azure/identity"),authMode=scope===PG_TOKEN_SCOPE?getDatabaseAuthMode():getRedisAuthMode(),clientId=process.env.AZURE_CLIENT_ID||"",tenantId=process.env.AZURE_TENANT_ID||"",clientSecret=process.env.AZURE_CLIENT_SECRET||"",credential;if(authMode==="managed_identity")credential=clientId?new ManagedIdentityCredential(clientId):new DefaultAzureCredential;else if(authMode==="service_principal"){if(!tenantId||!clientId||!clientSecret)throw Error("[azure-auth] service_principal auth requires AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET");credential=new ClientSecretCredential(tenantId,clientId,clientSecret)}else throw Error(`[azure-auth] Unsupported auth mode: ${authMode}`);let result=await credential.getToken(scope);if(!result)throw Error(`[azure-auth] Failed to acquire token for ${label}`);return logger.scoped("database.connect").info(`[azure-auth] ${label} token acquired`,{expiresAt:new Date(result.expiresOnTimestamp).toISOString(),authMode}),{token:result.token,expiresAt:result.expiresOnTimestamp}}async function getPostgresToken(){let now=Date.now();if(pgCachedToken&&now<pgTokenExpiresAt-REFRESH_BUFFER_MS)return pgCachedToken;let{token,expiresAt}=await acquireToken(PG_TOKEN_SCOPE,"PostgreSQL");return pgCachedToken=token,pgTokenExpiresAt=expiresAt,pgCachedToken}async function getRedisToken(){let now=Date.now();if(redisCachedToken&&now<redisTokenExpiresAt-REFRESH_BUFFER_MS)return redisCachedToken;let{token,expiresAt}=await acquireToken(REDIS_TOKEN_SCOPE,"Redis");return redisCachedToken=token,redisTokenExpiresAt=expiresAt,redisCachedToken}function getRedisTokenExpiresAt(){return redisTokenExpiresAt}var PG_TOKEN_SCOPE="https://ossrdbms-aad.database.windows.net/.default",REDIS_TOKEN_SCOPE="https://redis.azure.com/.default",REFRESH_BUFFER_MS=300000,pgCachedToken=null,pgTokenExpiresAt=0,redisCachedToken=null,redisTokenExpiresAt=0;var init_AzureTokenProvider=__esm(()=>{init_Logger2()});var exports_Azure={};__export(exports_Azure,{getRedisTokenExpiresAt:()=>getRedisTokenExpiresAt,getRedisToken:()=>getRedisToken,getRedisAuthMode:()=>getRedisAuthMode,getPostgresToken:()=>getPostgresToken,getDatabaseAuthMode:()=>getDatabaseAuthMode});var init_Azure=__esm(()=>{init_AzureTokenProvider()});import{access,mkdir as mkdir2}from"fs/promises";import{dirname,resolve}from"path";var DEFAULT_CONFIG5,FILE_SIZE_UNITS,resolvePath=(path2)=>{if(!path2||typeof path2!=="string")throw createFileManagerError("INVALID_PATH","Path must be a non-empty string",path2,"resolvePath");return resolve(path2)},extractDirectoryPath=(filePath)=>{let resolvedPath=resolvePath(filePath);return dirname(resolvedPath)},ensureDirectoryExists=async(dirPath)=>{let resolvedPath=resolve(dirPath);try{await mkdir2(resolvedPath,{recursive:!0})}catch(error){if(error.code!=="EEXIST")throw createFileManagerError("DIRECTORY_CREATE_FAILED",`Failed to create directory: ${resolvedPath}`,resolvedPath,"ensureDirectory")}},formatFileSize=(bytes)=>{let size=bytes,unitIndex=0;while(size>=1024&&unitIndex<FILE_SIZE_UNITS.length-1)size/=1024,unitIndex++;return`${size.toFixed(2)} ${FILE_SIZE_UNITS[unitIndex]}`},validateFileExtension=(fileName,expectedExtension)=>{return fileName.toLowerCase().endsWith(expectedExtension.toLowerCase())},ensureFileExtension=(fileName,extension)=>{let normalizedExtension=extension.startsWith(".")?extension:`.${extension}`;if(validateFileExtension(fileName,normalizedExtension))return fileName;return`${fileName}${normalizedExtension}`},createFileManagerError=(code,message,path2,operation)=>{return{code,message,path:path2,operation:operation||"unknown"}},safeJsonStringify=(data)=>{try{return JSON.stringify(data,null,2)}catch{return"{}"}},executeBulkOperation=async(items,operation,concurrency=DEFAULT_CONFIG5.maxConcurrency)=>{let results=[];for(let i=0;i<items.length;i+=concurrency){let batch3=items.slice(i,i+concurrency),batchPromises=[];for(let item of batch3)batchPromises.push(operation(item));let batchResults=await Promise.allSettled(batchPromises);results.push(...batchResults)}return results},validateConfig=(config,options={})=>{let errors=[],warnings=[],strict=options.strict??!0;if(config.defaultEncoding!==void 0){if(!["utf-8","utf8","ascii","base64","hex"].includes(config.defaultEncoding))errors.push(`Invalid defaultEncoding: ${config.defaultEncoding}`)}if(config.maxConcurrency!==void 0){if(!Number.isInteger(config.maxConcurrency)||config.maxConcurrency<1)errors.push("maxConcurrency must be a positive integer");if(config.maxConcurrency>50)warnings.push("maxConcurrency > 50 may cause performance issues")}if(config.defaultCreateDir!==void 0&&typeof config.defaultCreateDir!=="boolean")errors.push("defaultCreateDir must be a boolean");if(config.defaultRecursive!==void 0&&typeof config.defaultRecursive!=="boolean")errors.push("defaultRecursive must be a boolean");if(strict&&!options.allowUnknownKeys){let validKeys=["defaultEncoding","defaultCreateDir","defaultRecursive","maxConcurrency"],configKeys=Object.keys(config);for(let key2 of configKeys)if(!validKeys.includes(key2))errors.push(`Unknown configuration key: ${key2}`)}return{isValid:errors.length===0,errors,warnings}},mergeConfig=(partial,base=DEFAULT_CONFIG5)=>{let validation=validateConfig(partial);if(!validation.isValid)throw createFileManagerError("CONFIG_VALIDATION_FAILED",`Configuration validation failed: ${validation.errors.join(", ")}`,void 0,"mergeConfig");return{...base,...partial}},parsePermissions=(mode)=>{let parseOctal=(octal)=>({read:Boolean(octal&4),write:Boolean(octal&2),execute:Boolean(octal&1)}),ownerMode=mode>>6&7,groupMode=mode>>3&7,othersMode=mode&7;return{owner:parseOctal(ownerMode),group:parseOctal(groupMode),others:parseOctal(othersMode)}},validatePermissionMode=(mode)=>{return Number.isInteger(mode)&&mode>=0&&mode<=511};var init_utils4=__esm(()=>{DEFAULT_CONFIG5={defaultEncoding:"utf-8",defaultCreateDir:!0,defaultRecursive:!0,maxConcurrency:5},FILE_SIZE_UNITS=["B","KB","MB","GB","TB"]});import{copyFile,rename,unlink as unlink2}from"fs/promises";import{basename,dirname as dirname2,extname,join as join2}from"path";var DEFAULT_ATOMIC_CONFIG,generateTempPath=(originalPath,suffix=".tmp")=>{let resolvedPath=resolvePath(originalPath),timestamp=Date.now(),random=Math.random().toString(36).substring(2,8);return`${resolvedPath}${suffix}.${timestamp}.${random}`},generateBackupPath=(originalPath,backupDir,useTimestamp=!0)=>{let resolvedPath=resolvePath(originalPath),dir=backupDir?resolvePath(backupDir):dirname2(resolvedPath),name=basename(resolvedPath),ext=extname(name),nameWithoutExt=basename(name,ext),timestamp=useTimestamp?`.${new Date().toISOString().replace(/[:.]/g,"-")}`:"",backupName=`${nameWithoutExt}.backup${timestamp}${ext}`;return join2(dir,backupName)},atomicWrite=async({path:path2,data,tempSuffix=DEFAULT_ATOMIC_CONFIG.tempSuffix,backup=DEFAULT_ATOMIC_CONFIG.backup,sync=DEFAULT_ATOMIC_CONFIG.sync})=>{let resolvedPath=resolvePath(path2),tempPath=generateTempPath(resolvedPath,tempSuffix),backupPath;try{if(await ensureDirectoryExists(extractDirectoryPath(resolvedPath)),backup){if(await Bun.file(resolvedPath).exists())backupPath=generateBackupPath(resolvedPath),await copyFile(resolvedPath,backupPath)}let bytesWritten=await Bun.write(tempPath,data);return await rename(tempPath,resolvedPath),{success:!0,bytesWritten,tempPath,backupPath}}catch(error){try{await unlink2(tempPath)}catch{}throw createFileManagerError("ATOMIC_WRITE_FAILED",`Atomic write failed: ${error}`,resolvedPath,"atomicWrite")}},atomicJsonWrite=async(path2,data,options={})=>{let jsonString=JSON.stringify(data,null,2);return atomicWrite({path:path2,data:jsonString,...options})},createBackup=async({sourcePath,backupDir,keepOriginal=!0,timestamp=DEFAULT_ATOMIC_CONFIG.timestamp})=>{let resolvedSource=resolvePath(sourcePath);if(!await Bun.file(resolvedSource).exists())throw createFileManagerError("SOURCE_NOT_FOUND",`Source file not found: ${sourcePath}`,resolvedSource,"createBackup");let backupPath=generateBackupPath(resolvedSource,backupDir,timestamp);if(await ensureDirectoryExists(dirname2(backupPath)),keepOriginal)await copyFile(resolvedSource,backupPath);else await rename(resolvedSource,backupPath);return backupPath},restoreFromBackup=async(backupPath,targetPath,deleteBackup=!1)=>{let resolvedBackup=resolvePath(backupPath),resolvedTarget=resolvePath(targetPath);if(!await Bun.file(resolvedBackup).exists())throw createFileManagerError("BACKUP_NOT_FOUND",`Backup file not found: ${backupPath}`,resolvedBackup,"restoreFromBackup");try{if(await ensureDirectoryExists(extractDirectoryPath(resolvedTarget)),deleteBackup)await rename(resolvedBackup,resolvedTarget);else await copyFile(resolvedBackup,resolvedTarget);return!0}catch(error){return logger.scoped("storage.fs").error(`Failed to restore from backup ${backupPath}`,error,{backupPath}),!1}},safeUpdate=async(path2,updateFunction,options={})=>{let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath),backupPath;try{if(await file.exists())backupPath=await createBackup({sourcePath:resolvedPath,keepOriginal:!0,timestamp:!0});let currentData=await file.exists()?await file.text():"",newData=await updateFunction(currentData),result=await atomicWrite({path:resolvedPath,data:newData,backup:!1,...options});return{success:result.success,bytesWritten:result.bytesWritten,tempPath:result.tempPath,backupPath}}catch(error){if(backupPath)try{await restoreFromBackup(backupPath,resolvedPath,!1)}catch(rollbackError){logger.scoped("storage.fs").error("Atomic write rollback failed",rollbackError,{backupPath})}throw error}},batchAtomicWrite=async(operations)=>{let successful=[],failed=[];for(let operation of operations)try{let result=await atomicWrite(operation);successful.push(result)}catch(error){failed.push({operation,error})}return{successful,failed}};var init_atomic=__esm(()=>{init_Logger2();init_utils4();DEFAULT_ATOMIC_CONFIG={tempSuffix:".tmp",backup:!1,sync:!0,timestamp:!0}});import{chmod,stat as stat2}from"fs/promises";var PERMISSION_MODES,setFilePermissions=async(path2,mode)=>{let resolvedPath=resolvePath(path2);if(!validatePermissionMode(mode))throw createFileManagerError("INVALID_PERMISSION_MODE",`Invalid permission mode: ${mode.toString(8)}`,resolvedPath,"setFilePermissions");try{return await chmod(resolvedPath,mode),!0}catch(error){return logger.scoped("storage.fs").error(`Failed to set permissions for ${path2}`,error,{path:path2,mode}),!1}},getFilePermissions=async(path2)=>{let resolvedPath=resolvePath(path2);try{let mode=(await stat2(resolvedPath)).mode&511,permissions=parsePermissions(mode);return{path:resolvedPath,mode,owner:permissions.owner,group:permissions.group,others:permissions.others}}catch(error){throw createFileManagerError("PERMISSION_READ_FAILED",`Failed to read permissions: ${error}`,resolvedPath,"getFilePermissions")}},hasPermissions=async(path2,requiredMode)=>{try{return((await getFilePermissions(path2)).mode&requiredMode)===requiredMode}catch{return!1}},makeReadable=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode|256;return setFilePermissions(path2,newMode)},makeWritable=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode|128;return setFilePermissions(path2,newMode)},makeExecutable=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode|64;return setFilePermissions(path2,newMode)},makeReadOnly=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode&-147;return setFilePermissions(path2,newMode)},setCommonPermissions=async(path2,pattern)=>{let mode=PERMISSION_MODES[pattern];return setFilePermissions(path2,mode)};var init_permissions=__esm(()=>{init_Logger2();init_utils4();PERMISSION_MODES={OWNER_READ_WRITE:384,OWNER_ALL:448,GROUP_READ:416,GROUP_READ_WRITE:432,ALL_READ:420,ALL_READ_WRITE:438,ALL_READ_EXECUTE:493,ALL_FULL:511,READ_ONLY:292,EXECUTABLE:493}});var DEFAULT_STREAM_CONFIG,createFileWriter=async(path2,options={})=>{let resolvedPath=resolvePath(path2),config={...DEFAULT_STREAM_CONFIG,...options};await ensureDirectoryExists(extractDirectoryPath(resolvedPath));let writer=Bun.file(resolvedPath).writer({highWaterMark:config.highWaterMark}),isClosed=!1;return{write:(chunk)=>{if(isClosed)throw createFileManagerError("WRITER_CLOSED","Cannot write to closed writer",resolvedPath,"streamWrite");try{let result=writer.write(chunk);if(config.autoFlush)writer.flush();return result}catch(error){throw createFileManagerError("WRITE_FAILED",`Failed to write chunk: ${error}`,resolvedPath,"streamWrite")}},flush:()=>{if(isClosed)return 0;try{return writer.flush()}catch(error){throw createFileManagerError("FLUSH_FAILED",`Failed to flush writer: ${error}`,resolvedPath,"streamFlush")}},end:async(error)=>{if(isClosed)return 0;try{let result=await writer.end(error);return isClosed=!0,result}catch(err){throw isClosed=!0,createFileManagerError("END_FAILED",`Failed to end writer: ${err}`,resolvedPath,"streamEnd")}},ref:()=>{if(!isClosed)writer.ref()},unref:()=>{if(!isClosed)writer.unref()}}},writeStream=async(path2,chunks,options={})=>{let writer=await createFileWriter(path2,options),totalBytes=0;try{for(let chunk of chunks){let bytesWritten=writer.write(chunk);totalBytes+=bytesWritten}return await writer.flush(),await writer.end(),totalBytes}catch(error){try{await writer.end(error)}catch{}throw error}},appendStream=async(path2,chunks,options={})=>{let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath),existingContent=await file.exists()?await file.arrayBuffer():new ArrayBuffer(0),allChunks=[];if(existingContent.byteLength>0)allChunks.push(existingContent);return allChunks.push(...chunks),writeStream(resolvedPath,allChunks,options)},copyFileStream=async(sourcePath,destinationPath,options={})=>{let resolvedSource=resolvePath(sourcePath),sourceFile=Bun.file(resolvedSource);if(!await sourceFile.exists())throw createFileManagerError("SOURCE_NOT_FOUND",`Source file not found: ${sourcePath}`,resolvedSource,"copyFileStream");let sourceStream=sourceFile.stream(),writer=await createFileWriter(destinationPath,options),totalBytes=0;try{let reader=sourceStream.getReader();while(!0){let{done,value}=await reader.read();if(done)break;let bytesWritten=writer.write(value);totalBytes+=bytesWritten}return await writer.flush(),await writer.end(),totalBytes}catch(error){try{await writer.end(error)}catch{}throw error}},readFileStream=async(path2,chunkProcessor)=>{let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath);if(!await file.exists())throw createFileManagerError("FILE_NOT_FOUND",`File not found: ${path2}`,resolvedPath,"readFileStream");let reader=file.stream().getReader();try{while(!0){let{done,value}=await reader.read();if(done)break;await chunkProcessor(value)}}finally{reader.releaseLock()}};var init_streaming=__esm(()=>{init_utils4();DEFAULT_STREAM_CONFIG={highWaterMark:1048576,autoFlush:!0,closeOnEnd:!0}});import{readdir,rm,rmdir,stat as stat3}from"fs/promises";import{extname as extname2,join as join3}from"path";class BunFileManager{static instance;config;constructor(){this.config={...DEFAULT_CONFIG5}}static getInstance(){if(!BunFileManager.instance)BunFileManager.instance=new BunFileManager;return BunFileManager.instance}async createFile({dir,name,data,options={}}){let filePath=resolvePath(join3(dir,name));if(options.createDir!==!1)await ensureDirectoryExists(extractDirectoryPath(filePath));let fileData=options.type?new Blob([data],{type:options.type}):data;return await Bun.write(filePath,fileData)}async createJsonFile(dir,name,data){let fileName=ensureFileExtension(name,".json"),jsonString=safeJsonStringify(data);return this.createFile({dir,name:fileName,data:jsonString,options:{type:"application/json"}})}async createDirectory({path:path2}){await ensureDirectoryExists(path2)}async readFile({path:path2,format="text"}){let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath);if(!await file.exists())throw createFileManagerError("FILE_NOT_FOUND",`File not found: ${path2}`,resolvedPath,"readFile");switch(format){case"text":return await file.text();case"json":return await file.json();case"buffer":return await file.arrayBuffer();case"bytes":return await file.bytes();case"stream":return file.stream();default:return await file.text()}}async readJsonFile(path2){return this.readFile({path:path2,format:"json"})}async getFileInfo(path2){let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath),fileName=path2.split("/").pop()||path2,stats=null;try{stats=await stat3(resolvedPath)}catch{}return{name:fileName,path:resolvedPath,size:file.size,type:file.type,exists:await file.exists(),extension:extname2(fileName),createdAt:stats?.birthtime,modifiedAt:stats?.mtime}}async readDirectory({path:path2,recursive=!1}){let resolvedPath=resolvePath(path2);return await readdir(resolvedPath,{recursive,encoding:"utf8"})}async getFilesByExtension(dir,extension){let files=await this.readDirectory({path:dir}),normalizedExt=extension.startsWith(".")?extension:`.${extension}`;return files.filter((file)=>file.endsWith(normalizedExt))}async updateFile({path:path2,data,mode="overwrite"}){let resolvedPath=resolvePath(path2);if(mode==="append"){let combinedData=await this.readFile({path:path2,format:"text"})+data;return await Bun.write(resolvedPath,combinedData)}return await Bun.write(resolvedPath,data)}async updateJsonFile(path2,data,merge=!1){let finalData=data;if(merge)try{let existingData=await this.readJsonFile(path2);if(typeof existingData==="object"&&existingData!==null&&!Array.isArray(existingData)&&typeof data==="object"&&data!==null&&!Array.isArray(data))finalData={...existingData,...data}}catch{}return this.updateFile({path:path2,data:safeJsonStringify(finalData),mode:"overwrite"})}async appendToFile(path2,data){return this.updateFile({path:path2,data,mode:"append"})}async deleteFile(path2){try{let resolvedPath=resolvePath(path2);return await Bun.file(resolvedPath).delete(),!0}catch(error){return logger.scoped("storage.fs").error(`Failed to delete file ${path2}`,error,{path:path2}),!1}}async deleteDirectory({path:path2,recursive=!1}){try{let resolvedPath=resolvePath(path2);if(recursive)await rm(resolvedPath,{recursive:!0,force:!0});else await rmdir(resolvedPath);return!0}catch(error){return logger.scoped("storage.fs").error(`Failed to delete directory ${path2}`,error,{path:path2}),!1}}async deleteFiles(paths){let results=await executeBulkOperation(paths,async(path2)=>{if(!await this.deleteFile(path2))throw Error(`Failed to delete: ${path2}`);return path2}),success=[],failed=[];for(let i=0;i<results.length;i++){let result=results[i],originalPath=paths[i];if(result?.status==="fulfilled")success.push(originalPath||"");else failed.push(originalPath||"")}return{success,failed}}async exists(path2){let resolvedPath=resolvePath(path2);return await Bun.file(resolvedPath).exists()}async copyFile(sourcePath,destinationPath){let resolvedSource=resolvePath(sourcePath),resolvedDestination=resolvePath(destinationPath),sourceFile=Bun.file(resolvedSource);if(!await sourceFile.exists())throw createFileManagerError("SOURCE_NOT_FOUND",`Source file not found: ${sourcePath}`,resolvedSource,"copyFile");return await ensureDirectoryExists(extractDirectoryPath(resolvedDestination)),await Bun.write(resolvedDestination,sourceFile)}async moveFile(sourcePath,destinationPath){try{return await this.copyFile(sourcePath,destinationPath),await this.deleteFile(sourcePath),!0}catch(error){return logger.scoped("storage.fs").error("Failed to move file",error,{sourcePath,destinationPath}),!1}}getFormattedFileSize(bytes){return formatFileSize(bytes)}getConfig(){return{...this.config}}updateConfig(newConfig){let validation=validateConfig(newConfig);if(validation.isValid){let mergedConfig=mergeConfig(newConfig,this.config);Object.assign(this.config,mergedConfig)}return validation}validateConfiguration(config){return validateConfig(config)}async createStreamWriter(path2,options={}){return createFileWriter(path2,options)}async writeStream(path2,chunks,options={}){return writeStream(path2,chunks,options)}async appendStream(path2,chunks,options={}){return appendStream(path2,chunks,options)}async copyFileStream(sourcePath,destinationPath,options={}){return copyFileStream(sourcePath,destinationPath,options)}async readFileStream(path2,chunkProcessor){return readFileStream(path2,chunkProcessor)}async setPermissions(path2,mode){return setFilePermissions(path2,mode)}async setPermissionsAdvanced(options){return setFilePermissions(options.path,options.mode)}async getPermissions(path2){return getFilePermissions(path2)}async checkPermissions(path2,requiredMode){return hasPermissions(path2,requiredMode)}async makeFileReadable(path2){return makeReadable(path2)}async makeFileWritable(path2){return makeWritable(path2)}async makeFileExecutable(path2){return makeExecutable(path2)}async makeFileReadOnly(path2){return makeReadOnly(path2)}async setCommonPermission(path2,pattern){return setCommonPermissions(path2,pattern)}async atomicWrite(options){return atomicWrite(options)}async atomicJsonWrite(path2,data,options={}){return atomicJsonWrite(path2,data,options)}async createFileBackup(options){return createBackup(options)}async restoreFileFromBackup(backupPath,targetPath,deleteBackup=!1){return restoreFromBackup(backupPath,targetPath,deleteBackup)}async safeFileUpdate(path2,updateFunction,options={}){return safeUpdate(path2,updateFunction,options)}async batchAtomicOperations(operations){return batchAtomicWrite(operations)}}var init_core=__esm(()=>{init_Logger2();init_atomic();init_permissions();init_streaming();init_utils4()});var fileManager;var init_File=__esm(()=>{init_core();init_utils4();init_core();fileManager=BunFileManager.getInstance()});import{Pool}from"pg";var init_Postgre=__esm(()=>{init_Logger2()});var init_Managers=__esm(()=>{init_Azure();init_Dapr();init_File();init_Postgre();init_Redis()});var exports_utils={};__export(exports_utils,{warnIfAccessTokenTooLargeForCookie:()=>warnIfAccessTokenTooLargeForCookie,validatePayload:()=>validatePayload,validateEnvVariables:()=>validateEnvVariables,toAudit:()=>toAudit,signNewAccessToken:()=>signNewAccessToken,sanitizePayload:()=>sanitizePayload,resolveDbPoolConfig:()=>resolveDbPoolConfig,refreshAccessTokenWithLock:()=>refreshAccessTokenWithLock,redactSensitiveOutput:()=>redactSensitiveOutput,parseTokenValuesFromHeaders:()=>parseTokenValuesFromHeaders,parseTimeToSeconds:()=>parseTimeToSeconds2,parseQueryParams:()=>parseQueryParams,isSensitiveOutputKey:()=>isSensitiveOutputKey,initiateRedisManager:()=>initiateRedisManager,getRedisManager:()=>getRedisManager,ensureDatabaseExists:()=>ensureDatabaseExists,decodeUnverifiedSubject:()=>decodeUnverifiedSubject,createAuditLog:()=>createAuditLog,buildPaginationMeta:()=>buildPaginationMeta,COOKIE_SAFE_TOKEN_BYTES:()=>COOKIE_SAFE_TOKEN_BYTES});function parseTokenValuesFromHeaders(headers,tokenNames){let cookies=(headers.get("cookie")?.split(";")||[]).reduce((acc,cookie)=>{let trimmed=cookie.trim(),eqIndex=trimmed.indexOf("=");if(eqIndex>0)acc[trimmed.slice(0,eqIndex)]=trimmed.slice(eqIndex+1);return acc},{});return{access_token:cookies[tokenNames.access_token]||headers.get("authorization")?.split(" ")[1],refresh_token:cookies[tokenNames.refresh_token],session_token:cookies[tokenNames.session_token]}}async function initiateRedisManager(config){if(!config.redis){logger.info("[Redis] Not configured, skipping");return}let rawWithDapr=config.redis.withDapr,resolvedWithDapr=typeof rawWithDapr==="string"?process.env[rawWithDapr]?.toLowerCase()!=="false":rawWithDapr??!1,resolvedKeyPrefix=config.redis.keyPrefix?process.env[config.redis.keyPrefix]??config.redis.keyPrefix:void 0;if(resolvedWithDapr){redisManagerInstance=new RedisManager({withDapr:!0,stateStoreName:config.redis.stateStoreName,...resolvedKeyPrefix?{keyPrefix:resolvedKeyPrefix}:{}});return}let resolvedUrl=config.redis.url?process.env[config.redis.url]:void 0,resolvedHost=config.redis.host?process.env[config.redis.host]:void 0,resolvedPort=config.redis.port?parseInt(process.env[config.redis.port]||"",10):void 0;if((process.env.REDIS_AUTH_MODE||"password")!=="password"){let{getRedisToken:getRedisToken2,getRedisTokenExpiresAt:getRedisTokenExpiresAt2}=await Promise.resolve().then(() => (init_Azure(),exports_Azure)),clientId=process.env.AZURE_CLIENT_ID||"",initialToken=await getRedisToken2();redisManagerInstance=new RedisManager({host:resolvedHost,port:Number.isNaN(resolvedPort)?void 0:resolvedPort,password:initialToken,username:clientId,tls:!0,...resolvedKeyPrefix?{keyPrefix:resolvedKeyPrefix}:{}});let unref=(t)=>{t.unref?.()},scheduleRedisTokenRefresh=()=>{let expiresAt=getRedisTokenExpiresAt2(),refreshIn=Math.max(expiresAt-Date.now()-300000,30000);unref(setTimeout(async()=>{try{let newToken=await getRedisToken2();if(redisManagerInstance)await redisManagerInstance.reauthenticate(clientId,newToken),logger.info("[Redis] Entra ID token refreshed successfully");scheduleRedisTokenRefresh()}catch(err){logger.error("[Redis] Token refresh failed \u2014 retrying in 30s",err),unref(setTimeout(scheduleRedisTokenRefresh,30000))}},refreshIn))};scheduleRedisTokenRefresh()}else{let resolvedPassword=process.env.REDIS_PASSWORD||void 0;redisManagerInstance=new RedisManager({url:resolvedUrl,host:resolvedHost,port:Number.isNaN(resolvedPort)?void 0:resolvedPort,...resolvedPassword?{password:resolvedPassword}:{},...resolvedKeyPrefix?{keyPrefix:resolvedKeyPrefix}:{}})}}function getRedisManager(){return redisManagerInstance}function parseTimeToSeconds2(timeString){if(typeof timeString==="number")return timeString;if(!timeString||timeString.trim()==="")throw Error("Time string cannot be empty");let match=timeString.trim().match(/^(\d+(?:\.\d+)?)\s*([smhdwMy])$/);if(!match||!match[1]||!match[2])throw Error(`Invalid time format: "${timeString}". Expected format: "75s", "10m", "2h", "1d", "1w", "2M", "1y"`);let value=parseFloat(match[1]),unit=match[2],multiplier={s:1,m:60,h:3600,d:86400,w:604800,M:2592000,y:31536000}[unit];if(multiplier===void 0)throw Error(`Unknown time unit: "${unit}"`);let seconds=Math.floor(value*multiplier);if(seconds<=0)throw Error(`Time value must be positive: "${timeString}"`);return seconds}function warnIfAccessTokenTooLargeForCookie(token,jwtClaimsMode){let bytes=Buffer.byteLength(token,"utf-8");if(bytes<=COOKIE_SAFE_TOKEN_BYTES)return;let now=Date.now();if(now-lastOversizeWarnAt<60000)return;lastOversizeWarnAt=now,logger.warn(`[Auth] access_token is ${bytes} bytes \u2014 at/over the ~4KB per-cookie browser limit, so the cookie may be `+"silently dropped (symptom: appears logged-in but requests are unauthenticated). Shrink it: set authorization.jwtClaimsMode:'resolve' (token carries only roles; claims resolved from the Redis claims cache), or deliver the token off-cookie via authentication.accessToken.setHeadersEnabled:false. "+(jwtClaimsMode?`Current jwtClaimsMode='${jwtClaimsMode}'.`:""))}function signNewAccessToken({sessionData,options,refreshTokenId,roles,claims,tenant,claimScopes,resolveMode}){let secretEnvName=options.authentication?.accessToken?.secret;if(!secretEnvName)throw Error("Access token secret env name is not configured");let secret=process.env[secretEnvName];if(!secret)throw Error(`Access token secret env "${secretEnvName}" is not set`);let token=signJWT({subject:sessionData.userId,issuer:options.authentication?.accessToken?.issuer,audience:options.authentication?.accessToken?.audience,algorithm:options.authentication?.accessToken?.algorithm,expiresInSeconds:parseTimeToSeconds2(options.authentication?.accessToken?.expiresIn??"15m"),sessionId:sessionData.id,customClaims:{refreshTokenId,...roles&&roles.length>0?{roles}:{},...!resolveMode&&claims&&claims.length>0?{claims}:{},...!resolveMode&&claimScopes&&Object.keys(claimScopes).length>0?{claimScopes}:{},...tenant?{tenant}:{}}},secret);return warnIfAccessTokenTooLargeForCookie(token,resolveMode?"resolve":options.authorization?.jwtClaimsMode),token}function resolveDbPoolConfig(pool){return{max:pool?.max!=null&&pool.max>0?pool.max:10,idleTimeoutMillis:pool?.idleTimeoutMillis??30000,connectionTimeoutMillis:pool?.connectionTimeoutMillis??1e4,...pool?.maxUses!=null&&pool.maxUses>0?{maxUses:pool.maxUses}:{}}}function toAudit(payload,summary,opts){return payload?{entityName:payload.entity_name,entityId:payload.entity_id===" - "?null:payload.entity_id,operation:payload.operation_type,userId:opts&&"userId"in opts?opts.userId??null:payload.user_id==="unknown"?null:payload.user_id,summary,severity:opts?.severity,category:opts?.category,ipAddress:payload.ip_address,userAgent:payload.user_agent,path:payload.path,query:payload.query}:void 0}function decodeUnverifiedSubject(token){if(!token)return null;try{let parts=token.split(".");if(parts.length<2)return null;let payloadPart=parts[1];if(!payloadPart)return null;let json=Buffer.from(payloadPart,"base64url").toString("utf-8"),decoded=JSON.parse(json);return typeof decoded.sub==="string"&&decoded.sub?decoded.sub:null}catch{return null}}function reconstructBracketParams(query){let result={},arrayGroups={};for(let[key2,value]of Object.entries(query)){let match=key2.match(/^(\w+)\[\d*\]\[(\w+)\]$/),arrayName=match?.[1],prop=match?.[2];if(arrayName&&prop){if(!arrayGroups[arrayName])arrayGroups[arrayName]={};let group=arrayGroups[arrayName];if(!group[prop])group[prop]=[];let arr=group[prop];if(Array.isArray(value))for(let v of value)arr.push(v);else arr.push(value)}else result[key2]=value}for(let[arrayName,props]of Object.entries(arrayGroups)){let propNames=Object.keys(props);if(propNames.length===0)continue;let maxLen=Math.max(...propNames.map((p)=>(props[p]||[]).length)),items=[];for(let i=0;i<maxLen;i++){let item={};for(let p of propNames)item[p]=(props[p]||[])[i];items.push(item)}result[arrayName]=items}return result}function parseQueryParams(query){let q=reconstructBracketParams(query),parseJSONOrPassthrough=(value)=>{if(value===void 0||value===null)return;if(typeof value==="object")return value;if(typeof value==="string")try{return JSON.parse(value)}catch{return}return},DEFAULT_PAGE_SIZE=20,MAX_PAGE_SIZE=200,rawPage=q.page?parseInt(q.page,10):1,page=Number.isFinite(rawPage)&&rawPage>0?rawPage:1,rawLimit=q.limit?parseInt(q.limit,10):20,limit=Number.isFinite(rawLimit)&&rawLimit>0?Math.min(rawLimit,200):20,rawOffset=q.offset?parseInt(q.offset,10):(page-1)*limit,offset=Number.isFinite(rawOffset)&&rawOffset>=0?rawOffset:0;return{page,limit,offset,search:q.search,searchFields:q.searchFields?q.searchFields.split(","):void 0,filters:parseJSONOrPassthrough(q.filters),sort:parseJSONOrPassthrough(q.sort),select:q.select?q.select.split(","):void 0,with:parseJSONOrPassthrough(q.with),distinct:q.distinct==="true",distinctOn:q.distinctOn?q.distinctOn.split(","):void 0}}function buildPaginationMeta(page,limit,offset,totalItems){let totalPages=Math.ceil(totalItems/limit),hasNextPage=page<totalPages,hasPrevPage=page>1;return{page,limit,offset,totalItems,totalPages,hasNextPage,hasPrevPage,nextPage:hasNextPage?page+1:null,prevPage:hasPrevPage?page-1:null}}function getBaseTypeValidator(type){let stringTypes=["varchar","char","text","uuid","citext","bit","varbit"],numberTypes=["integer","smallint","bigint","serial","smallserial","bigserial","real","doublePrecision","numeric","decimal"],booleanTypes=["boolean"];if(stringTypes.includes(type))return(v)=>({valid:typeof v==="string",expectedType:"string"});if(numberTypes.includes(type))return(v)=>({valid:typeof v==="number",expectedType:"number"});if(booleanTypes.includes(type))return(v)=>({valid:typeof v==="boolean",expectedType:"boolean"});if(type==="json"||type==="jsonb")return(v)=>({valid:typeof v==="object",expectedType:"object"});return()=>({valid:!0,expectedType:"any"})}function validatePayload(payload,columns,isPartial=!1){let errors=[];for(let col6 of columns){let value=payload[col6.name]??payload[col6.name.replace(/_([a-z])/g,(_,l)=>l.toUpperCase())],hasDbDefault=col6.default!==void 0||!!col6.defaultRaw||!!col6.generatedByDefaultAsIdentity||!!col6.generatedAlwaysAsIdentity||!!col6.generatedAlwaysAs,isRequired=col6.notNull&&!col6.nullable&&!hasDbDefault;if(value===void 0||value===null){if(isRequired&&!isPartial)errors.push({field:col6.name,message:col6.validation?.customMessage||`${col6.name} is required`});continue}if(col6.array){let baseValidator=getBaseTypeValidator(col6.type),expectedType=baseValidator(void 0).expectedType;if(!Array.isArray(value)){errors.push({field:col6.name,message:col6.validation?.customMessage||`${col6.name} must be an array of ${expectedType}`});continue}if(value.some((el)=>el!==null&&!baseValidator(el).valid))errors.push({field:col6.name,message:col6.validation?.customMessage||`${col6.name} must be an array of ${expectedType}`});continue}let typeCheck=getBaseTypeValidator(col6.type)(value);if(!typeCheck.valid){errors.push({field:col6.name,message:col6.validation?.customMessage||`${col6.name} must be of type ${typeCheck.expectedType}`});continue}if(typeof value==="string"){let len=value.length;if(col6.length&&len>col6.length)errors.push({field:col6.name,message:col6.validation?.customMessage||`${col6.name} exceeds max length of ${col6.length}`});if(col6.validation?.minLength&&len<col6.validation.minLength)errors.push({field:col6.name,message:col6.validation.customMessage||`${col6.name} must be at least ${col6.validation.minLength} characters`});if(col6.validation?.maxLength&&len>col6.validation.maxLength)errors.push({field:col6.name,message:col6.validation.customMessage||`${col6.name} must be at most ${col6.validation.maxLength} characters`});if(col6.validation?.pattern){if(!new RegExp(col6.validation.pattern).test(value))errors.push({field:col6.name,message:col6.validation.customMessage||`${col6.name} does not match required pattern`})}if(col6.validation?.format){let formatRegex=FORMAT_PATTERNS[col6.validation.format];if(formatRegex&&!formatRegex.test(value))errors.push({field:col6.name,message:col6.validation.customMessage||`${col6.name} must be a valid ${col6.validation.format}`})}}if(typeof value==="number"){if(col6.validation?.min!==void 0&&value<col6.validation.min)errors.push({field:col6.name,message:col6.validation.customMessage||`${col6.name} must be at least ${col6.validation.min}`});if(col6.validation?.max!==void 0&&value>col6.validation.max)errors.push({field:col6.name,message:col6.validation.customMessage||`${col6.name} must be at most ${col6.validation.max}`})}if(col6.enumValues&&col6.enumValues.length>0){if(!col6.enumValues.includes(value))errors.push({field:col6.name,message:col6.validation?.customMessage||`${col6.name} must be one of: ${col6.enumValues.join(", ")}`})}}return{valid:errors.length===0,errors}}function escapeHtml(str3){return str3.replace(/[&<>"'`=/]/g,(char)=>HTML_ENTITIES[char]||char)}function stripTags(str3){return str3.replace(/<[^>]*>/g,"")}function normalizeEmail(email){let parts=email.split("@"),localPart=parts[0],domain=parts[1];if(!localPart||!domain)return email;let beforePlus=localPart.split("+")[0];if(!beforePlus)return email;return`${beforePlus.replace(/\./g,"")}@${domain.toLowerCase()}`}function slugify(str3){return str3.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}function applySanitizer(value,sanitizer){if(value===null||value===void 0)return value;switch(sanitizer){case"trim":return typeof value==="string"?value.trim():value;case"lowercase":return typeof value==="string"?value.toLowerCase():value;case"uppercase":return typeof value==="string"?value.toUpperCase():value;case"escapeHtml":return typeof value==="string"?escapeHtml(value):value;case"stripTags":return typeof value==="string"?stripTags(value):value;case"normalizeEmail":return typeof value==="string"?normalizeEmail(value):value;case"toNumber":if(typeof value==="number")return value;if(typeof value==="string"){let num2=Number(value);return Number.isNaN(num2)?value:num2}return value;case"toBoolean":if(typeof value==="boolean")return value;if(typeof value==="string"){let lower=value.toLowerCase();if(lower==="true"||lower==="1"||lower==="yes")return!0;if(lower==="false"||lower==="0"||lower==="no")return!1}if(typeof value==="number")return value!==0;return value;case"slugify":return typeof value==="string"?slugify(value):value;default:return value}}function isSensitiveOutputKey(key2){return SENSITIVE_OUTPUT_KEYS.has(key2)}function redactSensitiveOutput(row){return scrubSensitive(row)}function scrubSensitive(value){if(value===null||typeof value!=="object")return value;if(Array.isArray(value))return value.map(scrubSensitive);let proto=Object.getPrototypeOf(value);if(proto!==Object.prototype&&proto!==null)return value;let out={};for(let[k,v]of Object.entries(value)){if(SENSITIVE_OUTPUT_KEYS.has(k))continue;out[k]=scrubSensitive(v)}return out}function sanitizePayload(payload,columns,opts){let sanitized={},toCamel2=(s)=>s.replace(/_([a-z])/g,(_,l)=>l.toUpperCase()),SERVER_MANAGED=new Set(["id","created_at","updated_at","created_by","updated_by","createdAt","updatedAt","createdBy","updatedBy"]),PROTECTED_SENSITIVE=new Set(["is_god","password","password_hash","email_verified","verified_at","email_verified_at","is_locked","locked_until","failed_login_attempts","login_count","last_login_at","email_verification_token","email_verification_sent_at","email_verification_expires_at","password_reset_token","password_reset_expires_at","password_reset_sent_at","magic_link_token","two_factor_secret"]),STORAGE_MANAGED=opts?.isFormData?new Set(["path","name","original_name","originalName","extension","size","mime_type","mimeType","uploaded_by","uploadedBy"]):null;for(let key2 of Object.keys(payload)){if(SERVER_MANAGED.has(key2))continue;if(STORAGE_MANAGED?.has(key2))continue;let value=payload[key2],snakeKey=key2.replace(/[A-Z]/g,(l)=>`_${l.toLowerCase()}`);if(PROTECTED_SENSITIVE.has(snakeKey))continue;let col6=columns.find((c)=>c.name===key2||c.name===snakeKey);if(col6?.readOnly)continue;if(col6?.sanitize&&col6.sanitize.length>0)for(let sanitizer of col6.sanitize)value=applySanitizer(value,sanitizer);if(col6&&(col6.type==="timestamp"||col6.type==="timestamptz"||col6.type==="date")&&typeof value==="string"){let parsed=new Date(value);if(!Number.isNaN(parsed.getTime()))value=parsed}let normalizedKey=key2.includes("_")?toCamel2(key2):key2;sanitized[normalizedKey]=value}return sanitized}function createAuditLog(db,auditTable,entry){if(!db||!auditTable)return;let logEntry={user_id:entry.user_id,entity_name:entry.entity_name,entity_id:entry.entity_id,operation:entry.operation,old_data:entry.old_data??null,new_data:entry.new_data??null,timestamp:new Date().toISOString()};db.insert(auditTable).values(logEntry).execute().catch((err)=>{logger.error("[Audit] Database audit write failed",err,{entity:logEntry.entity_name,operation:logEntry.operation})})}async function refreshAccessTokenWithLock(userId,sessionId,generateToken){let redis=new RedisManager,lockKey=`${REFRESH_LOCK_PREFIX}${userId}`,cacheKey=`${ACCESS_TOKEN_CACHE_PREFIX}${userId}:${sessionId}`,cachedResult=await redis.read(cacheKey);if(cachedResult.success&&cachedResult.data)return{success:!0,accessToken:cachedResult.data,fromCache:!0};let lockResult=await redis.acquireLock(lockKey,LOCK_TTL_SECONDS);if(!lockResult.success)return{success:!1,error:lockResult.error};if(lockResult.data)try{let newToken=generateToken();return await redis.create(cacheKey,newToken,ACCESS_TOKEN_CACHE_TTL_SECONDS),{success:!0,accessToken:newToken,fromCache:!1}}finally{await redis.releaseLock(lockKey)}let waitResult=await redis.waitForLock(lockKey,LOCK_WAIT_TIMEOUT_MS,50);if(!waitResult.success)return{success:!1,error:waitResult.error};if(!waitResult.data)return{success:!1,error:"Lock wait timeout"};let newCachedResult=await redis.read(cacheKey);if(newCachedResult.success&&newCachedResult.data)return{success:!0,accessToken:newCachedResult.data,fromCache:!0};let fallbackToken=generateToken();return await redis.create(cacheKey,fallbackToken,ACCESS_TOKEN_CACHE_TTL_SECONDS),{success:!0,accessToken:fallbackToken,fromCache:!1}}function validateEnvVariables(config){let errors=[],resolved={},databaseAuthMode=process.env.DATABASE_AUTH_MODE||"password",redisAuthMode=process.env.REDIS_AUTH_MODE||"password";resolved.databaseAuthMode=databaseAuthMode,resolved.redisAuthMode=redisAuthMode;let entraIdModes=["managed_identity","service_principal"];if(entraIdModes.includes(databaseAuthMode)||entraIdModes.includes(redisAuthMode)){if(!process.env.AZURE_CLIENT_ID)logger.warn("[Config] AZURE_CLIENT_ID is not set. Required for user-assigned managed identity.");if([databaseAuthMode,redisAuthMode].filter((m)=>m==="service_principal").length>0){if(!process.env.AZURE_TENANT_ID)errors.push({field:"azure.tenantId",envName:"AZURE_TENANT_ID",message:"AZURE_TENANT_ID is required for service_principal auth mode."});if(!process.env.AZURE_CLIENT_SECRET)errors.push({field:"azure.clientSecret",envName:"AZURE_CLIENT_SECRET",message:"AZURE_CLIENT_SECRET is required for service_principal auth mode."})}}if(config.database?.url){let envValue=process.env[config.database.url];if(!envValue)errors.push({field:"database.url",envName:config.database.url,message:`Environment variable "${config.database.url}" is not set. Please set it in your .env file.`});else resolved.databaseUrl=envValue}let validationWithDapr=typeof config.redis?.withDapr==="string"?process.env[config.redis.withDapr]?.toLowerCase()!=="false":config.redis?.withDapr??!1;if(config.redis&&!validationWithDapr)if(config.redis.url){let envValue=process.env[config.redis.url];if(!envValue)errors.push({field:"redis.url",envName:config.redis.url,message:`Environment variable "${config.redis.url}" is not set. Please set it in your .env file.`});else resolved.redisUrl=envValue}else{if(config.redis.host){if(!process.env[config.redis.host])errors.push({field:"redis.host",envName:config.redis.host,message:`Environment variable "${config.redis.host}" is not set. Please set it in your .env file.`})}if(config.redis.port){if(!process.env[config.redis.port])errors.push({field:"redis.port",envName:config.redis.port,message:`Environment variable "${config.redis.port}" is not set. Please set it in your .env file.`})}}if(config.authentication?.enabled){if(!config.authentication.mode)errors.push({field:"authentication.mode",envName:"",message:'authentication.mode is required when authentication is enabled. Use "full" for IDP/standalone services, "consumer" for resource servers.'});if(config.authentication.accessToken?.secret){let envValue=process.env[config.authentication.accessToken.secret];if(!envValue)errors.push({field:"authentication.accessToken.secret",envName:config.authentication.accessToken.secret,message:`Environment variable "${config.authentication.accessToken.secret}" is not set. Please set it in your .env file.`});else resolved.accessTokenSecret=envValue}else errors.push({field:"authentication.accessToken.secret",envName:"",message:"authentication.accessToken.secret is required when authentication is enabled."});let isConsumerMode=config.authentication.mode==="consumer";if(config.authentication.refreshToken?.secret){let envValue=process.env[config.authentication.refreshToken.secret];if(!envValue)errors.push({field:"authentication.refreshToken.secret",envName:config.authentication.refreshToken.secret,message:`Environment variable "${config.authentication.refreshToken.secret}" is not set. Please set it in your .env file.`});else resolved.refreshTokenSecret=envValue}else if(!isConsumerMode)errors.push({field:"authentication.refreshToken.secret",envName:"",message:"authentication.refreshToken.secret is required when authentication is enabled."});if(config.authentication.sessionToken?.secret){let envValue=process.env[config.authentication.sessionToken.secret];if(!envValue)errors.push({field:"authentication.sessionToken.secret",envName:config.authentication.sessionToken.secret,message:`Environment variable "${config.authentication.sessionToken.secret}" is not set. Please set it in your .env file.`});else resolved.sessionTokenSecret=envValue}else if(!isConsumerMode)errors.push({field:"authentication.sessionToken.secret",envName:"",message:"authentication.sessionToken.secret is required when authentication is enabled."})}if(config.authentication?.oauth?.enabled&&config.authentication.oauth.providers){let resolvedProviders={};for(let[providerName,providerConfig]of Object.entries(config.authentication.oauth.providers)){if(!providerConfig)continue;let{clientId:clientIdEnvName,clientSecret:clientSecretEnvName,redirectUri:redirectUriEnvName,tenantId:tenantIdEnvName}=providerConfig,clientId=process.env[clientIdEnvName],clientSecret=process.env[clientSecretEnvName],redirectUri=process.env[redirectUriEnvName]??redirectUriEnvName,tenantId=tenantIdEnvName?process.env[tenantIdEnvName]??tenantIdEnvName:void 0;if(!clientId)errors.push({field:`authentication.oauth.providers.${providerName}.clientId`,envName:clientIdEnvName,message:`Environment variable "${clientIdEnvName}" is not set (OAuth ${providerName} clientId).`});if(!clientSecret)errors.push({field:`authentication.oauth.providers.${providerName}.clientSecret`,envName:clientSecretEnvName,message:`Environment variable "${clientSecretEnvName}" is not set (OAuth ${providerName} clientSecret).`});if(clientId&&clientSecret)resolvedProviders[providerName]={clientId,clientSecret,redirectUri,tenantId,scopes:providerConfig.scopes,authorizationUrl:providerConfig.authorizationUrl,tokenUrl:providerConfig.tokenUrl,userInfoUrl:providerConfig.userInfoUrl,extraAuthParams:providerConfig.extraAuthParams}}if(Object.keys(resolvedProviders).length>0)resolved.oauthProviders=resolvedProviders}return{valid:errors.length===0,errors,resolved}}async function ensureDatabaseExists(databaseUrl,logger2,authMode){let{Pool:Pool2}=await import("pg"),targetDb=new URL(databaseUrl).pathname.replace("/","");if(!targetDb)return;let adminUrl=new URL(databaseUrl);adminUrl.pathname="/postgres";let pool;if(authMode&&authMode!=="password"){let{getPostgresToken:getPostgresToken2}=await Promise.resolve().then(() => (init_Azure(),exports_Azure));pool=new Pool2({connectionString:adminUrl.toString(),password:getPostgresToken2,ssl:{rejectUnauthorized:!0}})}else pool=new Pool2({connectionString:adminUrl.toString()});try{if((await pool.query("SELECT 1 FROM pg_database WHERE datname = $1",[targetDb])).rowCount===0)logger2.info(`[Database] Creating database "${targetDb}"...`),await pool.query(`CREATE DATABASE "${targetDb}" TEMPLATE template0`),logger2.info(`[Database] Database "${targetDb}" created successfully`);else logger2.info(`[Database] Database "${targetDb}" exists`)}catch(err){let message=err instanceof Error?err.message:String(err);logger2.warn(`[Database] Could not auto-create database: ${message}`)}finally{await pool.end()}}var redisManagerInstance=null,COOKIE_SAFE_TOKEN_BYTES=3500,lastOversizeWarnAt=0,FORMAT_PATTERNS,HTML_ENTITIES,SENSITIVE_OUTPUT_KEYS,ACCESS_TOKEN_CACHE_PREFIX="access_token:",REFRESH_LOCK_PREFIX="refresh_lock:",LOCK_TTL_SECONDS=5,LOCK_WAIT_TIMEOUT_MS=3000,ACCESS_TOKEN_CACHE_TTL_SECONDS=60;var init_utils5=__esm(()=>{init_Managers();init_Services();init_Logger2();FORMAT_PATTERNS={email:/^[^\s@]+@[^\s@]+\.[^\s@]+$/,url:/^https?:\/\/.+/,uuid:/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,date:/^\d{4}-\d{2}-\d{2}$/,datetime:/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/,time:/^\d{2}:\d{2}:\d{2}$/,uri:/^[a-z][a-z0-9+.-]*:/i,ipv4:/^(\d{1,3}\.){3}\d{1,3}$/,ipv6:/^([0-9a-f]{1,4}:){7}[0-9a-f]{1,4}$/i};HTML_ENTITIES={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};SENSITIVE_OUTPUT_KEYS=new Set(["password","passwordHash","password_hash","emailVerificationToken","email_verification_token","emailVerificationTokenExpiresAt","email_verification_token_expires_at","passwordResetToken","password_reset_token","refreshTokenHash","refresh_token_hash"])});import{eq as eq12}from"drizzle-orm";import{pgSchema}from"drizzle-orm/pg-core";class TenantRegistry{db;logger;mainSchemaName;mainSchemaTables;mainSchemaRelations;createAllTablesForSchema;createAllRelationsForSchema;appId;authMode;tenantResolution;tenantHeader;redisCacheTtlSeconds;defaultTrustedSources;idpUrl;allowDataLoss;onTenantProvisioned;tenantsBySubdomain=new Map;tenantsBySchemaName=new Map;tenantsById=new Map;schemaContexts=new Map;tenantFeatures=new Map;tenantsByDomainHostname=new Map;constructor(config){this.db=config.db,this.logger=config.logger,this.mainSchemaName=config.mainSchemaName,this.mainSchemaTables=config.mainSchemaTables,this.mainSchemaRelations=config.mainSchemaRelations,this.createAllTablesForSchema=config.createAllTablesForSchema,this.createAllRelationsForSchema=config.createAllRelationsForSchema,this.appId=config.appId,this.authMode=config.authMode,this.tenantResolution=config.tenantResolution,this.tenantHeader=config.tenantHeader,this.redisCacheTtlSeconds=config.redisCacheTtlSeconds,this.defaultTrustedSources=config.defaultTrustedSources,this.idpUrl=config.idpUrl,this.allowDataLoss=config.allowDataLoss===!0,this.onTenantProvisioned=config.onTenantProvisioned}async initialize(){this.logger.info("[TenantRegistry] Initializing..."),this.schemaContexts.set(this.mainSchemaName,{schemaName:this.mainSchemaName,schemaTables:this.mainSchemaTables,schemaRelations:this.mainSchemaRelations,tenant:null});let tenants=await this.loadTenantsFromDb();this.logger.info(`[TenantRegistry] Loaded ${tenants.length} tenants from database`);let features=await this.loadTenantFeaturesFromDb();this.logger.info(`[TenantRegistry] Loaded ${features.length} tenant feature mappings`);for(let tenant of tenants)this.indexTenant(tenant);for(let feature of features){let existing=this.tenantFeatures.get(feature.tenantId)||[];existing.push(feature),this.tenantFeatures.set(feature.tenantId,existing)}let activeTenants=tenants.filter((t)=>t.status==="active");for(let tenant of activeTenants)await this.buildSchemaContext(tenant);await this.loadDomainHostnames(),this.logger.info(`[TenantRegistry] Initialized with ${activeTenants.length} active tenant schemas + main schema`)}resolveFromRequest(request,vettedClientIp){let url=new URL(request.url),host=request.headers.get("host")||url.host||"",normalizedHost=normalizeHost(host);if(normalizedHost){let byHostname=this.tenantsByDomainHostname.get(normalizedHost);if(byHostname)return this.validateAndReturnTenant(byHostname)}if(this.tenantResolution==="subdomain"||this.tenantResolution==="both"){let subdomain=extractSubdomain(host);if(subdomain){let tenant=this.tenantsBySubdomain.get(subdomain);if(tenant)return this.validateAndReturnTenant(tenant);return{resolved:!1,error:`Tenant not found for subdomain: ${subdomain}`,statusCode:404}}}if(this.tenantResolution==="header"||this.tenantResolution==="both"){let tenantIdOrSubdomain=request.headers.get(this.tenantHeader);if(tenantIdOrSubdomain){let result=this.resolveFromHeader(tenantIdOrSubdomain,request,vettedClientIp);if(result)return result}}let mainContext=this.schemaContexts.get(this.mainSchemaName);if(mainContext)return{resolved:!0,context:mainContext};return{resolved:!1,error:"No tenant could be resolved and main schema is unavailable",statusCode:500}}getSchemaContext(schemaName){return this.schemaContexts.get(schemaName)}getMainContext(){let ctx=this.schemaContexts.get(this.mainSchemaName);if(!ctx)throw Error("[TenantRegistry] Main schema context not initialized");return ctx}getActiveTenants(){return Array.from(this.tenantsById.values()).filter((t)=>t.status==="active")}getTenantById(id){return this.tenantsById.get(id)}getTenantBySchemaName(schemaName){return this.tenantsBySchemaName.get(schemaName)}getTenantFeatures(tenantId){return this.tenantFeatures.get(tenantId)||[]}isTenantFeatureEnabled(tenantId,featureName){return(this.tenantFeatures.get(tenantId)||[]).find((f)=>f.featureName===featureName)?.enabled??!1}getTenantIdsWithFeature(featureName){let result=[];for(let[tenantId,features]of this.tenantFeatures)if(features.find((f)=>f.featureName===featureName&&f.enabled))result.push(tenantId);return result}getSchemaNamesWithFeature(featureName){let tenantIds=this.getTenantIdsWithFeature(featureName),schemaNames=[];for(let tenantId of tenantIds){let tenant=this.tenantsById.get(tenantId);if(tenant&&tenant.status==="active")schemaNames.push(tenant.schemaName)}return schemaNames}getAllSchemaNames(){return Array.from(this.schemaContexts.keys())}async provisionTenant(tenant){this.logger.info(`[TenantRegistry] Provisioning tenant: ${tenant.subdomain} \u2192 ${tenant.schemaName}`),await ensureSchemaExists(this.db,tenant.schemaName);let context=await this.buildSchemaContext(tenant);if(this.indexTenant(tenant),await this.syncSchemaToDb(context),this.onTenantProvisioned)try{await this.onTenantProvisioned(context)}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[TenantRegistry] onTenantProvisioned hook failed for ${tenant.schemaName}: ${msg}`)}return this.logger.info(`[TenantRegistry] Tenant provisioned: ${tenant.subdomain}`),context}async syncSchemaToDb(context){let{pushSchema}=await import("drizzle-kit/api"),{applySchemaPush:applySchemaPush2}=await Promise.resolve().then(() => (init_schema(),exports_schema)),targetSchema=pgSchema(context.schemaName);try{let push=await pushSchema({schema:targetSchema,...context.schemaTables},this.db,[context.schemaName]);if(await applySchemaPush2(push,{schemaName:context.schemaName,allowDataLoss:this.allowDataLoss,logger:this.logger}))this.logger.info(`[TenantRegistry] Schema sync completed for: ${context.schemaName}`)}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[TenantRegistry] Schema sync warning for ${context.schemaName}: ${msg}`)}}async syncAllSchemas(){for(let[schemaName,context]of this.schemaContexts)this.logger.info(`[TenantRegistry] Syncing schema: ${schemaName}`),await ensureSchemaExists(this.db,schemaName),await this.syncSchemaToDb(context)}async invalidateCache(subdomain){try{let{getRedisManager:getRedisManager2}=await Promise.resolve().then(() => (init_utils5(),exports_utils)),redis=getRedisManager2();if(redis)await redis.remove(`tenant:${subdomain}`),this.logger.info(`[TenantRegistry] Cache invalidated for: ${subdomain}`)}catch{}}async refreshTenant(tenantId){let tenantsTable=this.mainSchemaTables.tenants;if(!tenantsTable)return;let row=(await this.db.select().from(tenantsTable).where(eq12(tenantsTable.id,tenantId)).limit(1))[0];if(!row)return;let tenant=rowToTenantRecord(row),oldTenant=this.tenantsById.get(tenantId);if(oldTenant)this.tenantsBySubdomain.delete(oldTenant.subdomain),this.tenantsBySchemaName.delete(oldTenant.schemaName);if(this.indexTenant(tenant),tenant.status==="active")await this.buildSchemaContext(tenant);else this.schemaContexts.delete(tenant.schemaName);if(oldTenant)await this.invalidateCache(oldTenant.subdomain);await this.invalidateCache(tenant.subdomain)}async initializeFromIdp(){if(!this.idpUrl){this.logger.error("[TenantRegistry] Consumer multi-tenant requires idpUrl (IDP_URL)");return}this.logger.info(`[TenantRegistry] Initializing from IDP: ${this.idpUrl}`),this.schemaContexts.set(this.mainSchemaName,{schemaName:this.mainSchemaName,schemaTables:this.mainSchemaTables,schemaRelations:this.mainSchemaRelations,tenant:null});let tenants=await this.loadTenantsFromIdp();this.logger.info(`[TenantRegistry] Fetched ${tenants.length} tenants from IDP`);for(let tenant of tenants)this.indexTenant(tenant);let activeTenants=tenants.filter((t)=>t.status==="active");for(let tenant of activeTenants)await this.buildSchemaContext(tenant);await this.loadDomainHostnames(),this.logger.info(`[TenantRegistry] Consumer initialized with ${activeTenants.length} active tenant schemas + main schema`)}isConsumerMode(){return this.authMode==="consumer"&&!!this.idpUrl}async syncFromIdp(){if(!this.isConsumerMode())return{added:[],removed:[],total:this.tenantsById.size};let tenants=await this.loadTenantsFromIdp(),added=[],removed=[],seenSchemaNames=new Set;for(let tenant of tenants){seenSchemaNames.add(tenant.schemaName);let known=this.tenantsById.get(tenant.id);if(known)this.tenantsBySubdomain.delete(known.subdomain),this.tenantsBySchemaName.delete(known.schemaName);if(this.indexTenant(tenant),tenant.status==="active"){if(!this.schemaContexts.has(tenant.schemaName)){await ensureSchemaExists(this.db,tenant.schemaName);let ctx=await this.buildSchemaContext(tenant);await this.syncSchemaToDb(ctx),added.push(tenant.schemaName),await this.invalidateCache(tenant.subdomain),this.logger.info(`[TenantRegistry] Synced new tenant from IDP: ${tenant.subdomain}`)}}else if(this.schemaContexts.has(tenant.schemaName))this.schemaContexts.delete(tenant.schemaName),removed.push(tenant.schemaName),await this.invalidateCache(tenant.subdomain),this.logger.info(`[TenantRegistry] Deactivated tenant context: ${tenant.subdomain}`)}for(let[schemaName,ctx]of this.schemaContexts){if(schemaName===this.mainSchemaName)continue;if(!seenSchemaNames.has(schemaName)){if(this.schemaContexts.delete(schemaName),removed.push(schemaName),ctx.tenant)this.tenantsBySubdomain.delete(ctx.tenant.subdomain),this.tenantsById.delete(ctx.tenant.id),this.tenantsBySchemaName.delete(schemaName),await this.invalidateCache(ctx.tenant.subdomain)}}return{added,removed,total:tenants.length}}registerDomainHostname(hostname,tenantId){let tenant=this.tenantsById.get(tenantId);if(!tenant)return;this.tenantsByDomainHostname.set(normalizeHost(hostname),tenant)}unregisterDomainHostname(hostname){this.tenantsByDomainHostname.delete(normalizeHost(hostname))}async loadDomainHostnames(){let table=this.mainSchemaTables.domainHostnames;if(!table)return 0;try{let rows=await this.db.select().from(table),count=0;this.tenantsByDomainHostname.clear();for(let row of rows){let status=String(row.status??""),tenantId=String(row.tenantId??row.tenant_id??""),hostname=String(row.normalizedHostname??row.normalized_hostname??"");if(status!=="active"||!tenantId||!hostname)continue;let tenant=this.tenantsById.get(tenantId);if(!tenant)continue;this.tenantsByDomainHostname.set(normalizeHost(hostname),tenant),count++}if(count>0)this.logger.info(`[TenantRegistry] Indexed ${count} active custom hostnames`);return count}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.warn(`[TenantRegistry] Failed to load custom hostnames: ${msg}`),0}}async loadTenantsFromIdp(){if(!this.idpUrl)return[];try{let response=await fetch(`${this.idpUrl}/tenants`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!response.ok)return this.logger.warn(`[TenantRegistry] IDP tenant fetch failed: ${response.status} ${response.statusText}`),[];return((await response.json())?.data?.items||[]).map((item)=>rowToTenantRecord(item))}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.warn(`[TenantRegistry] Failed to fetch tenants from IDP: ${msg}`),[]}}async loadTenantsFromDb(){let tenantsTable=this.mainSchemaTables.tenants;if(!tenantsTable)return this.logger.warn("[TenantRegistry] No tenants table found in main schema"),[];try{return(await this.db.select().from(tenantsTable)).map((row)=>rowToTenantRecord(row))}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.warn(`[TenantRegistry] Failed to load tenants: ${msg}`),[]}}async loadTenantFeaturesFromDb(){let featuresTable=this.mainSchemaTables.tenantFeatures;if(!featuresTable)return this.logger.warn("[TenantRegistry] No tenant_features table found in main schema"),[];try{return(await this.db.select().from(featuresTable)).map((row)=>rowToFeatureRecord(row,parseJsonbToConfig))}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.warn(`[TenantRegistry] Failed to load tenant features: ${msg}`),[]}}indexTenant(tenant){if(this.tenantsById.set(tenant.id,tenant),this.tenantsBySubdomain.set(tenant.subdomain,tenant),this.tenantsBySchemaName.set(tenant.schemaName,tenant),tenant.domain)this.tenantsBySubdomain.set(tenant.domain,tenant)}async buildSchemaContext(tenant){let schema=pgSchema(tenant.schemaName),schemaTables=this.createAllTablesForSchema(schema),schemaRelations=this.createAllRelationsForSchema?this.createAllRelationsForSchema(schema):{},context={schemaName:tenant.schemaName,schemaTables,schemaRelations,tenant};return this.schemaContexts.set(tenant.schemaName,context),context}resolveFromHeader(tenantIdOrSubdomain,request,vettedClientIp){let tenant=this.tenantsBySubdomain.get(tenantIdOrSubdomain);if(!tenant)tenant=this.tenantsById.get(tenantIdOrSubdomain);if(!tenant)tenant=this.tenantsBySchemaName.get(tenantIdOrSubdomain);if(!tenant)return{resolved:!1,error:`Tenant not found for header value: ${tenantIdOrSubdomain}`,statusCode:404};if(!isTrustedSource(tenant,request,this.authMode,this.defaultTrustedSources,vettedClientIp))return{resolved:!1,error:`Untrusted source for tenant: ${tenant.subdomain}`,statusCode:403};return this.validateAndReturnTenant(tenant)}validateAndReturnTenant(tenant){if(tenant.status==="suspended")return{resolved:!1,error:`Tenant ${tenant.subdomain} is suspended: ${tenant.suspendedReason||"No reason provided"}`,statusCode:403};if(tenant.status==="provisioning")return{resolved:!1,error:`Tenant ${tenant.subdomain} is still being provisioned`,statusCode:503};if(tenant.status==="archived")return{resolved:!1,error:`Tenant ${tenant.subdomain} has been archived`,statusCode:410};let context=this.schemaContexts.get(tenant.schemaName);if(!context)return{resolved:!1,error:`Schema context not found for tenant: ${tenant.subdomain}`,statusCode:500};return{resolved:!0,context}}}var init_TenantRegistry=__esm(()=>{init_schema()});var init_Tenant=__esm(()=>{init_schema();init_TenantRegistry()});var init_types5=()=>{};import{and as and7,desc as desc2,eq as eq13,inArray as inArray2}from"drizzle-orm";function toCamel2(obj){let result={};for(let[key2,value]of Object.entries(obj)){let camelKey=key2.replace(/_([a-z])/g,(_,c)=>c.toUpperCase());result[camelKey]=value}return result}function fromCamel2(obj){let result={};for(let[key2,value]of Object.entries(obj)){let snakeKey=key2.replace(/[A-Z]/g,(c)=>`_${c.toLowerCase()}`);result[snakeKey]=value}return result}class VerificationService{db;schemaTables;config;logger;onNotificationTrigger;constructor(serviceConfig){this.db=serviceConfig.db,this.schemaTables=serviceConfig.schemaTables,this.config=serviceConfig.config,this.logger=serviceConfig.logger}setNotificationHandler(handler){this.onNotificationTrigger=handler}getConnectedNotificationNodeIds(stepNodeId,steps,edges){let result=new Set,getNeighbors=(nid)=>{let neighbors=[];for(let edge of edges){let{sourceNodeId:src,targetNodeId:tgt}=edge;if(src===nid)neighbors.push(tgt);else if(tgt===nid)neighbors.push(src)}return neighbors},directNeighbors=getNeighbors(stepNodeId);for(let neighborId of directNeighbors)if(steps.find((s)=>s.nodeId===neighborId)?.nodeType==="notification")result.add(neighborId);for(let neighborId of directNeighbors)if(steps.find((s)=>s.nodeId===neighborId)?.nodeType==="verifier"){let verifierNeighbors=getNeighbors(neighborId);for(let vNeighborId of verifierNeighbors){if(vNeighborId===stepNodeId)continue;if(steps.find((s)=>s.nodeId===vNeighborId)?.nodeType==="notification")result.add(vNeighborId)}}let ids=[...result];return this.logger.info(`[Verification] Connected notification nodes for step ${stepNodeId}: [${ids.join(", ")}]`),ids}getTable(name){return resolveSchemaTable(this.schemaTables,name,this.logger)}getCol(table,col6){return table[col6]}async listFlows(entityName){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return[];return(await(entityName?this.db.select().from(flowsTable).where(eq13(this.getCol(flowsTable,"entityName"),entityName)):this.db.select().from(flowsTable))).map((r)=>fromCamel2(r))}async getFlow(flowId){let flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),notifRulesTable=this.getTable("verificationNotificationRules"),notifRecipientsTable=this.getTable("verificationNotificationRecipients"),notifChannelsTable=this.getTable("verificationNotificationChannels");if(!flowsTable)return null;let flowRow=(await this.db.select().from(flowsTable).where(eq13(this.getCol(flowsTable,"id"),flowId)).limit(1))[0];if(!flowRow)return null;let flow=fromCamel2(flowRow),steps=(stepsTable?await this.db.select().from(stepsTable).where(eq13(this.getCol(stepsTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),edges=(edgesTable?await this.db.select().from(edgesTable).where(eq13(this.getCol(edgesTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),verifierConfigs=(verifierConfigsTable?await this.db.select().from(verifierConfigsTable).where(eq13(this.getCol(verifierConfigsTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),notifRules=(notifRulesTable?await this.db.select().from(notifRulesTable).where(eq13(this.getCol(notifRulesTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),ruleIds=notifRules.map((r)=>r.id),notifRecipients=(notifRecipientsTable&&ruleIds.length>0?await this.db.select().from(notifRecipientsTable).where(inArray2(this.getCol(notifRecipientsTable,"ruleId"),ruleIds)):[]).map((r)=>fromCamel2(r)),notifChannels=(notifChannelsTable&&ruleIds.length>0?await this.db.select().from(notifChannelsTable).where(inArray2(this.getCol(notifChannelsTable,"ruleId"),ruleIds)):[]).map((r)=>fromCamel2(r));return{flow,graph:{steps,edges,verifier_configs:verifierConfigs,notification_rules:notifRules,notification_recipients:notifRecipients,notification_channels:notifChannels}}}async saveFlow(params){let flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),notifRulesTable=this.getTable("verificationNotificationRules"),notifRecipientsTable=this.getTable("verificationNotificationRecipients"),notifChannelsTable=this.getTable("verificationNotificationChannels");if(!flowsTable||!stepsTable||!edgesTable)throw Error("Verification tables not configured");let existingFlows=await this.db.select().from(flowsTable).where(eq13(this.getCol(flowsTable,"id"),params.flow_id)).limit(1),flowId=params.flow_id;if(existingFlows.length>0)await this.db.update(flowsTable).set(toCamel2({entity_name:params.entity_name,name:params.name,description:params.description||null,trigger_on:params.trigger_on,trigger_fields:params.trigger_fields||null,is_draft:params.is_draft,viewport:params.viewport||null})).where(eq13(this.getCol(flowsTable,"id"),flowId));else{let[newFlow]=await this.db.insert(flowsTable).values(toCamel2({id:flowId,entity_name:params.entity_name,name:params.name,description:params.description||null,trigger_on:params.trigger_on,trigger_fields:params.trigger_fields||null,is_draft:params.is_draft,viewport:params.viewport||null})).returning();flowId=newFlow.id}if(await this.db.delete(stepsTable).where(eq13(this.getCol(stepsTable,"flowId"),flowId)),edgesTable)await this.db.delete(edgesTable).where(eq13(this.getCol(edgesTable,"flowId"),flowId));if(verifierConfigsTable)await this.db.delete(verifierConfigsTable).where(eq13(this.getCol(verifierConfigsTable,"flowId"),flowId));if(notifRulesTable){let oldRuleIds=(await this.db.select().from(notifRulesTable).where(eq13(this.getCol(notifRulesTable,"flowId"),flowId))).map((r)=>r.id);if(oldRuleIds.length>0){if(notifRecipientsTable)for(let rid of oldRuleIds)await this.db.delete(notifRecipientsTable).where(eq13(this.getCol(notifRecipientsTable,"ruleId"),rid));if(notifChannelsTable)for(let rid of oldRuleIds)await this.db.delete(notifChannelsTable).where(eq13(this.getCol(notifChannelsTable,"ruleId"),rid))}await this.db.delete(notifRulesTable).where(eq13(this.getCol(notifRulesTable,"flowId"),flowId))}let{graph}=params;if(graph.steps.length>0)await this.db.insert(stepsTable).values(graph.steps.map((s)=>toCamel2({flow_id:flowId,entity_name:params.entity_name,node_id:s.node_id,node_type:s.node_type,step_order:s.step_order,name:s.name||null,description:s.description||null,position_x:s.position_x,position_y:s.position_y,width:s.width||null,height:s.height||null,style:s.style||null,data:s.data||null})));if(graph.edges.length>0&&edgesTable)await this.db.insert(edgesTable).values(graph.edges.map((e)=>toCamel2({flow_id:flowId,edge_id:e.edge_id,source_node_id:e.source_node_id,target_node_id:e.target_node_id,source_handle:e.source_handle||null,target_handle:e.target_handle||null,edge_type:e.edge_type,label:e.label||null,condition:e.condition||null,style:e.style||null,animated:e.animated})));if(graph.verifier_configs.length>0&&verifierConfigsTable)await this.db.insert(verifierConfigsTable).values(graph.verifier_configs.map((vc)=>toCamel2({flow_id:flowId,node_id:vc.node_id,verifier_type:vc.verifier_type,verifier_user_id:vc.verifier_user_id||null,verifier_role:vc.verifier_role||null,require_signature:vc.require_signature,all_must_approve:vc.all_must_approve})));if(this.logger.info(`[Verification] Save: ${graph.notification_rules.length} rules, ${graph.notification_recipients.length} recipients, ${graph.notification_channels.length} channels`),graph.notification_rules.length>0&¬ifRulesTable)for(let rule of graph.notification_rules){this.logger.info(`[Verification] Saving notification rule: node_id=${rule.node_id}, trigger=${rule.trigger}, title_template=${JSON.stringify(rule.title_template)}, body_template=${JSON.stringify(rule.body_template)}`);let[insertedRule]=await this.db.insert(notifRulesTable).values(toCamel2({flow_id:flowId,node_id:rule.node_id,trigger:rule.trigger,title_template:rule.title_template||null,body_template:rule.body_template||null,starts_at:rule.starts_at||null,expires_at:rule.expires_at||null})).returning(),ruleId=insertedRule.id,ruleRecipients=graph.notification_recipients.filter((r)=>r.rule_id===rule.node_id);if(ruleRecipients.length>0&¬ifRecipientsTable)await this.db.insert(notifRecipientsTable).values(ruleRecipients.map((r)=>toCamel2({rule_id:ruleId,recipient_type:r.recipient_type,recipient_user_id:r.recipient_user_id||null,recipient_role:r.recipient_role||null})));let ruleChannels=graph.notification_channels.filter((c)=>c.rule_id===rule.node_id);if(ruleChannels.length>0&¬ifChannelsTable)await this.db.insert(notifChannelsTable).values(ruleChannels.map((c)=>toCamel2({rule_id:ruleId,channel:c.channel})))}return this.logger.info(`[Verification] Flow saved: ${flowId} for ${params.entity_name}`),{success:!0,flow_id:flowId}}async publishFlow(flowId){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return{success:!1,message:"Flow table not configured"};return await this.db.update(flowsTable).set(toCamel2({is_draft:!1,published_at:new Date})).where(eq13(this.getCol(flowsTable,"id"),flowId)),this.logger.info(`[Verification] Flow published: ${flowId}`),{success:!0,message:"Flow published"}}async deleteFlow(flowId){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return{success:!1,message:"Flow table not configured"};return await this.db.delete(flowsTable).where(eq13(this.getCol(flowsTable,"id"),flowId)),this.logger.info(`[Verification] Flow deleted: ${flowId}`),{success:!0,message:"Flow deleted"}}async startFlow(params){let flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),instancesTable=this.getTable("verificationInstances"),requirementsTable=this.getTable("verificationRequirements"),userRolesTable=this.getTable("userRoles");if(!flowsTable||!stepsTable||!edgesTable||!instancesTable||!requirementsTable)return{success:!1,message:"Verification tables not configured"};let flow=(await this.db.select().from(flowsTable).where(and7(eq13(this.getCol(flowsTable,"id"),params.flow_id),eq13(this.getCol(flowsTable,"isDraft"),!1))).limit(1))[0];if(!flow)return{success:!1,message:"Published flow not found"};if((await this.db.select().from(instancesTable).where(and7(eq13(this.getCol(instancesTable,"entityName"),params.entity_name),eq13(this.getCol(instancesTable,"entityId"),params.entity_id),eq13(this.getCol(instancesTable,"status"),"active"))).limit(1)).length>0)return{success:!1,message:"An active verification instance already exists for this entity"};let steps=await this.db.select().from(stepsTable).where(eq13(this.getCol(stepsTable,"flowId"),params.flow_id)),edges=await this.db.select().from(edgesTable).where(eq13(this.getCol(edgesTable,"flowId"),params.flow_id)),stepNodes=steps.filter((s)=>s.nodeType==="step");if(stepNodes.sort((a,b)=>a.stepOrder-b.stepOrder),stepNodes.length===0)return{success:!1,message:"Flow has no step nodes"};let[instance]=await this.db.insert(instancesTable).values(toCamel2({flow_id:params.flow_id,entity_name:params.entity_name,entity_id:params.entity_id,started_by:params.started_by||null,status:"active",current_step_order:1,started_at:new Date})).returning(),instanceId=instance.id;if(await this.materializeRequirementsForStep(instanceId,params.flow_id,params.entity_name,params.entity_id,1,steps,edges,verifierConfigsTable,requirementsTable,userRolesTable),this.onNotificationTrigger){let firstStep=stepNodes[0],firstStepNodeId=firstStep?.nodeId,connectedNotifIds=firstStepNodeId?this.getConnectedNotificationNodeIds(firstStepNodeId,steps,edges):[],ctx={flow_name:flow.name,step_name:firstStep?.name||"Step 1",step_order:1,total_steps:stepNodes.length};if(connectedNotifIds.length>0)for(let notifNodeId of connectedNotifIds)await this.onNotificationTrigger({trigger:"on_flow_started",flow_id:params.flow_id,entity_name:params.entity_name,entity_id:params.entity_id,node_id:notifNodeId,context:ctx});else await this.onNotificationTrigger({trigger:"on_flow_started",flow_id:params.flow_id,entity_name:params.entity_name,entity_id:params.entity_id,context:ctx})}return this.logger.info(`[Verification] Flow started: instance ${instanceId} for ${params.entity_name}:${params.entity_id}`),{success:!0,instance_id:instanceId,message:"Flow started"}}async materializeRequirementsForStep(instanceId,flowId,entityName,entityId,stepOrder,steps,edges,verifierConfigsTable,requirementsTable,userRolesTable){if(!requirementsTable)return;let stepNode=steps.find((s)=>s.nodeType==="step"&&s.stepOrder===stepOrder);if(!stepNode)return;let stepNodeId=stepNode.nodeId,verifierNodeIds=edges.filter((e)=>e.targetNodeId===stepNodeId).map((e)=>e.sourceNodeId),verifierNodes=steps.filter((s)=>s.nodeType==="verifier"&&verifierNodeIds.includes(s.nodeId));if(verifierNodes.length===0)return;let verifierConfigs=[];if(verifierConfigsTable)verifierConfigs=await this.db.select().from(verifierConfigsTable).where(eq13(this.getCol(verifierConfigsTable,"flowId"),flowId));for(let verifierNode of verifierNodes){let nodeId=verifierNode.nodeId,config=verifierConfigs.find((vc)=>vc.nodeId===nodeId);if(!config)continue;let{verifierType,allMustApprove}=config;if(verifierType==="role"&&allMustApprove&&userRolesTable){let rolesTable=this.getTable("roles");if(rolesTable){let rolesCols=rolesTable,userRolesCols=userRolesTable,role=(await this.db.select().from(rolesTable).where(eq13(rolesCols.name,config.verifierRole)).limit(1))[0];if(role){let usersWithRole=await this.db.select({user_id:userRolesCols.userId}).from(userRolesTable).where(eq13(userRolesCols.roleId,role.id));for(let userRole of usersWithRole)await this.db.insert(requirementsTable).values(toCamel2({instance_id:instanceId,step_node_id:stepNodeId,verifier_node_id:nodeId,entity_name:entityName,entity_id:entityId,verifier_type:"user",verifier_user_id:userRole.user_id,verifier_role:config.verifierRole||null,require_signature:config.requireSignature,all_must_approve:!0,step_order:stepOrder,status:"pending"}))}}}else await this.db.insert(requirementsTable).values(toCamel2({instance_id:instanceId,step_node_id:stepNodeId,verifier_node_id:nodeId,entity_name:entityName,entity_id:entityId,verifier_type:verifierType,verifier_user_id:config.verifierUserId||null,verifier_role:config.verifierRole||null,require_signature:config.requireSignature,all_must_approve:allMustApprove,step_order:stepOrder,status:"pending"}))}if(this.onNotificationTrigger){let connectedNotifIds=this.getConnectedNotificationNodeIds(stepNodeId,steps,edges);if(this.logger.info(`[Verification] on_step_reached: stepNodeId=${stepNodeId}, connectedNotifIds=[${connectedNotifIds.join(", ")}]`),connectedNotifIds.length>0)for(let notifNodeId of connectedNotifIds)this.logger.info(`[Verification] Triggering on_step_reached for notifNodeId=${notifNodeId}`),await this.onNotificationTrigger({trigger:"on_step_reached",flow_id:flowId,entity_name:entityName,entity_id:entityId,node_id:notifNodeId,context:{step_name:stepNode.name||`Step ${stepOrder}`,step_order:stepOrder}});else await this.onNotificationTrigger({trigger:"on_step_reached",flow_id:flowId,entity_name:entityName,entity_id:entityId,context:{step_name:stepNode.name||`Step ${stepOrder}`,step_order:stepOrder}})}}async getStatus(entityName,entityId){let instancesTable=this.getTable("verificationInstances"),flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),verificationsTable=this.getTable("verifications"),requirementsTable=this.getTable("verificationRequirements"),emptyStatus={entity_name:entityName,entity_id:entityId,instance:null,flow:null,current_step:0,total_steps:0,is_completed:!1,is_rejected:!1,verifications:[],pending_requirements:[]};if(!instancesTable||!flowsTable||!verificationsTable||!requirementsTable)return this.logger.error("[Verification] Required tables not found"),emptyStatus;let instanceRow=(await this.db.select().from(instancesTable).where(and7(eq13(this.getCol(instancesTable,"entityName"),entityName),eq13(this.getCol(instancesTable,"entityId"),entityId))).orderBy(desc2(this.getCol(instancesTable,"createdAt"))).limit(1))[0];if(!instanceRow)return emptyStatus;let instance=fromCamel2(instanceRow),flows=await this.db.select().from(flowsTable).where(eq13(this.getCol(flowsTable,"id"),instance.flow_id)).limit(1),flow=flows[0]?fromCamel2(flows[0]):void 0,totalSteps=(stepsTable?await this.db.select().from(stepsTable).where(and7(eq13(this.getCol(stepsTable,"flowId"),instance.flow_id),eq13(this.getCol(stepsTable,"nodeType"),"step"))):[]).length,verifications=(await this.db.select().from(verificationsTable).where(eq13(this.getCol(verificationsTable,"instanceId"),instance.id)).orderBy(desc2(this.getCol(verificationsTable,"createdAt")))).map((r)=>fromCamel2(r)),pendingRequirements=(await this.db.select().from(requirementsTable).where(and7(eq13(this.getCol(requirementsTable,"instanceId"),instance.id),eq13(this.getCol(requirementsTable,"status"),"pending")))).map((r)=>fromCamel2(r));return{entity_name:entityName,entity_id:entityId,instance,flow:flow||null,current_step:instance.current_step_order,total_steps:totalSteps,is_completed:instance.status==="completed",is_rejected:instance.status==="rejected",verifications,pending_requirements:pendingRequirements}}async decide(params){let{entity_name,entity_id,user_id,decision,reason,signature_id,diff}=params,verificationsTable=this.getTable("verifications"),requirementsTable=this.getTable("verificationRequirements"),instancesTable=this.getTable("verificationInstances"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),userRolesTable=this.getTable("userRoles"),rolesTable=this.getTable("roles");if(!verificationsTable||!requirementsTable||!instancesTable)return{success:!1,message:"Verification tables not configured"};let status=await this.getStatus(entity_name,entity_id);if(!status.instance||status.instance.status!=="active")return{success:!1,message:"No active verification instance"};let currentPending=status.pending_requirements.filter((r)=>r.step_order===status.current_step);if(currentPending.length===0)return{success:!1,message:"No pending requirements for current step"};let matchedReq=null;for(let req of currentPending){if(req.verifier_type==="user"&&req.verifier_user_id===user_id){matchedReq=req;break}if(req.verifier_type==="role"&&req.verifier_role&&userRolesTable&&rolesTable){let userRolesCols=userRolesTable,rolesCols=rolesTable;if((await this.db.select({role_name:rolesCols.name}).from(userRolesTable).innerJoin(rolesTable,eq13(userRolesCols.roleId,rolesCols.id)).where(eq13(userRolesCols.userId,user_id))).some((ur)=>ur.role_name===req.verifier_role)){matchedReq=req;break}}}if(!matchedReq)return{success:!1,message:"User is not authorized to verify at this step"};if(matchedReq.require_signature){if(!signature_id)return{success:!1,message:"Signature is required for this verification step"};let filesTable=resolveSchemaTable(this.schemaTables,"files",this.logger);if(filesTable){if((await this.db.select().from(filesTable).where(and7(eq13(this.getCol(filesTable,"id"),signature_id),eq13(this.getCol(filesTable,"uploadedBy"),user_id))).limit(1)).length===0)return{success:!1,message:"Signature file not found or not owned by the verifier"}}}if((await this.db.update(requirementsTable).set({status:decision}).where(and7(eq13(this.getCol(requirementsTable,"id"),matchedReq.id),eq13(this.getCol(requirementsTable,"status"),"pending"))).returning()).length===0)return{success:!1,message:"This requirement has already been decided"};let[newVerification]=await this.db.insert(verificationsTable).values(toCamel2({instance_id:status.instance.id,requirement_id:matchedReq.id,verifier_id:user_id,signature_id:signature_id||null,entity_name,entity_id,step_order:status.current_step,decision,reason:reason||null,diff:diff||null})).returning();if(this.onNotificationTrigger&&status.instance){let stepName=`Step ${status.current_step}`,allSteps=[],allEdges=[];if(stepsTable){allSteps=await this.db.select().from(stepsTable).where(eq13(this.getCol(stepsTable,"flowId"),status.instance.flow_id));let stepRow=allSteps.find((s)=>s.nodeId===matchedReq.step_node_id);if(stepRow?.name)stepName=stepRow.name}if(edgesTable)allEdges=await this.db.select().from(edgesTable).where(eq13(this.getCol(edgesTable,"flowId"),status.instance.flow_id));let triggerName=decision==="approved"?"on_approved":"on_rejected",ctx={flow_name:status.flow?.name||"",step_name:stepName,step_order:status.current_step,total_steps:status.total_steps,decision},connectedNotifIds=this.getConnectedNotificationNodeIds(matchedReq.step_node_id,allSteps,allEdges);if(connectedNotifIds.length>0)for(let notifNodeId of connectedNotifIds)await this.onNotificationTrigger({trigger:triggerName,flow_id:status.instance.flow_id,entity_name,entity_id,node_id:notifNodeId,verifier_id:user_id,decision,context:ctx});else await this.onNotificationTrigger({trigger:triggerName,flow_id:status.instance.flow_id,entity_name,entity_id,verifier_id:user_id,decision,context:ctx})}if(decision==="rejected"){await this.db.update(instancesTable).set(toCamel2({status:"rejected",completed_at:new Date})).where(eq13(this.getCol(instancesTable,"id"),status.instance.id));let newInstanceId;if(this.config.autoResetOnRejection){this.logger.info(`[Verification] Flow rejected for ${entity_name}:${entity_id}, auto-restarting from step 1`);let restartResult=await this.startFlow({flow_id:status.instance.flow_id,entity_name,entity_id,started_by:status.instance.started_by});if(restartResult.success)newInstanceId=restartResult.instance_id}return{success:!0,message:this.config.autoResetOnRejection?"Verification rejected \u2014 flow restarted from step 1":"Verification rejected",verification:newVerification,flow_completed:!1,new_instance_id:newInstanceId}}let matchedReqId=matchedReq.id,remainingPending=currentPending.filter((r)=>r.id!==matchedReqId);if(remainingPending.length>0)return{success:!0,message:`Step ${status.current_step} partially approved, ${remainingPending.length} verifier(s) remaining`,verification:newVerification,flow_completed:!1};let nextStep=status.current_step+1;if(nextStep>status.total_steps){if(await this.db.update(instancesTable).set(toCamel2({status:"completed",completed_at:new Date})).where(eq13(this.getCol(instancesTable,"id"),status.instance.id)),this.onNotificationTrigger){let completedSteps=[],completedEdges=[];if(stepsTable)completedSteps=await this.db.select().from(stepsTable).where(eq13(this.getCol(stepsTable,"flowId"),status.instance.flow_id));if(edgesTable)completedEdges=await this.db.select().from(edgesTable).where(eq13(this.getCol(edgesTable,"flowId"),status.instance.flow_id));let lastStepNodeId=matchedReq.step_node_id,completedNotifIds=this.getConnectedNotificationNodeIds(lastStepNodeId,completedSteps,completedEdges),completedCtx={flow_name:status.flow?.name||"",step_order:status.current_step,total_steps:status.total_steps};if(completedNotifIds.length>0)for(let notifNodeId of completedNotifIds)await this.onNotificationTrigger({trigger:"on_flow_completed",flow_id:status.instance.flow_id,entity_name,entity_id,node_id:notifNodeId,context:completedCtx});else await this.onNotificationTrigger({trigger:"on_flow_completed",flow_id:status.instance.flow_id,entity_name,entity_id,context:completedCtx})}return{success:!0,message:"Verification flow completed",verification:newVerification,flow_completed:!0}}if(await this.db.update(instancesTable).set(toCamel2({current_step_order:nextStep})).where(eq13(this.getCol(instancesTable,"id"),status.instance.id)),stepsTable&&edgesTable){let steps=await this.db.select().from(stepsTable).where(eq13(this.getCol(stepsTable,"flowId"),status.instance.flow_id)),edges=await this.db.select().from(edgesTable).where(eq13(this.getCol(edgesTable,"flowId"),status.instance.flow_id));await this.materializeRequirementsForStep(status.instance.id,status.instance.flow_id,entity_name,entity_id,nextStep,steps,edges,verifierConfigsTable,requirementsTable,userRolesTable)}return{success:!0,message:`Step ${status.current_step} approved, moving to step ${nextStep}`,verification:newVerification,flow_completed:!1,next_step:nextStep}}async startFlowForEntity(params){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return{success:!1,message:"Flow table not configured"};let flow=(await this.db.select().from(flowsTable).where(and7(eq13(this.getCol(flowsTable,"entityName"),params.entity_name),eq13(this.getCol(flowsTable,"isDraft"),!1))).limit(1))[0];if(!flow)return{success:!1,message:`No published flow found for entity '${params.entity_name}'`};return this.startFlow({flow_id:flow.id,entity_name:params.entity_name,entity_id:params.entity_id,started_by:params.started_by})}async listEntityStatuses(params){let instancesTable=this.getTable("verificationInstances"),flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),emptyResult={items:[],total:0,page:1,limit:20};if(!instancesTable||!flowsTable)return emptyResult;let page=params.page||1,limit=params.limit||20,offset=(page-1)*limit,conditions=[eq13(this.getCol(instancesTable,"entityName"),params.entity_name)];if(params.status)conditions.push(eq13(this.getCol(instancesTable,"status"),params.status));let whereClause=conditions.length===1?conditions[0]:and7(...conditions),allInstances=(await this.db.select().from(instancesTable).where(whereClause).orderBy(desc2(this.getCol(instancesTable,"createdAt")))).map((r)=>fromCamel2(r)),total=allInstances.length,paged=allInstances.slice(offset,offset+limit),items=[];for(let inst of paged){let flowId=inst.flow_id,flows=await this.db.select().from(flowsTable).where(eq13(this.getCol(flowsTable,"id"),flowId)).limit(1),flow=flows[0]?fromCamel2(flows[0]):void 0,totalSteps=0;if(stepsTable)totalSteps=(await this.db.select().from(stepsTable).where(and7(eq13(this.getCol(stepsTable,"flowId"),flowId),eq13(this.getCol(stepsTable,"nodeType"),"step")))).length;items.push({instance_id:inst.id,entity_name:inst.entity_name,entity_id:inst.entity_id,flow_id:flowId,flow_name:flow?.name||"Unknown",status:inst.status,current_step_order:inst.current_step_order,total_steps:totalSteps,started_by:inst.started_by,started_at:inst.started_at,completed_at:inst.completed_at})}return{items,total,page,limit}}async getPending(userId){let requirementsTable=this.getTable("verificationRequirements"),instancesTable=this.getTable("verificationInstances"),flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),userRolesTable=this.getTable("userRoles"),rolesTable=this.getTable("roles");if(this.logger.info(`[Verification.getPending] userId=${userId}, tables: req=${!!requirementsTable} inst=${!!instancesTable} flow=${!!flowsTable} steps=${!!stepsTable} roles=${!!rolesTable} userRoles=${!!userRolesTable}`),!requirementsTable||!instancesTable||!flowsTable)return this.logger.warn("[Verification.getPending] Missing required tables, returning empty"),[];let userRolesCols=userRolesTable,rolesCols=rolesTable,userRoleNames=(userRolesTable&&rolesTable?await this.db.select({role_name:rolesCols.name}).from(userRolesTable).innerJoin(rolesTable,eq13(userRolesCols.roleId,rolesCols.id)).where(eq13(userRolesCols.userId,userId)):[]).map((ur)=>ur.role_name),pendingReqs=(await this.db.select().from(requirementsTable).where(eq13(this.getCol(requirementsTable,"status"),"pending"))).map((r)=>fromCamel2(r));this.logger.info(`[Verification.getPending] Found ${pendingReqs.length} pending requirements, userRoles=${JSON.stringify(userRoleNames)}`);for(let req of pendingReqs)this.logger.info(`[Verification.getPending] Req: verifier_type=${req.verifier_type} verifier_user_id=${req.verifier_user_id} verifier_role=${req.verifier_role} step_order=${req.step_order} entity=${req.entity_name}/${req.entity_id}`);let pendingItems=[];for(let req of pendingReqs){if(!(req.verifier_type==="user"&&req.verifier_user_id===userId||req.verifier_type==="role"&&userRoleNames.includes(req.verifier_role))){this.logger.info(`[Verification.getPending] Skipping req: canVerify=false (type=${req.verifier_type}, reqUserId=${req.verifier_user_id}, loggedInUserId=${userId})`);continue}let instances=await this.db.select().from(instancesTable).where(and7(eq13(this.getCol(instancesTable,"id"),req.instance_id),eq13(this.getCol(instancesTable,"status"),"active"))).limit(1),instance=instances[0]?fromCamel2(instances[0]):void 0;if(!instance)continue;if(instance.current_step_order!==req.step_order)continue;let flows=await this.db.select().from(flowsTable).where(eq13(this.getCol(flowsTable,"id"),instance.flow_id)).limit(1),flow=flows[0]?fromCamel2(flows[0]):void 0;if(!flow)continue;let stepName;if(stepsTable&&req.step_node_id){let stepRow=(await this.db.select().from(stepsTable).where(and7(eq13(this.getCol(stepsTable,"flowId"),instance.flow_id),eq13(this.getCol(stepsTable,"nodeId"),req.step_node_id))).limit(1))[0];if(stepRow?.name)stepName=stepRow.name}pendingItems.push({instance_id:instance.id,entity_name:req.entity_name,entity_id:req.entity_id,flow_name:flow.name,step_order:req.step_order,step_name:stepName,require_signature:req.require_signature,created_at:req.created_at})}return pendingItems}}var init_Verification=__esm(()=>{init_types5()});var genLookup=(target)=>{let lookupTemp=typeof Uint8Array>"u"?[]:new Uint8Array(256),len=64;for(let i=0;i<64;i++)lookupTemp[target.charCodeAt(i)]=i;return lookupTemp},lookup,lookupUrl,base64UrlPattern,base64Pattern,base64,base64_default;var init_base64=__esm(()=>{lookup=genLookup("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),lookupUrl=genLookup("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),base64UrlPattern=/^[-A-Za-z0-9\-_]*$/,base64Pattern=/^[-A-Za-z0-9+/]*={0,3}$/,base64={};base64.toArrayBuffer=(data,urlMode)=>{let len=data.length,bufferLength=data.length*0.75,i,p=0,encoded1,encoded2,encoded3,encoded4;if(data[data.length-1]==="="){if(bufferLength--,data[data.length-2]==="=")bufferLength--}let arraybuffer=new ArrayBuffer(bufferLength),bytes=new Uint8Array(arraybuffer),target=urlMode?lookupUrl:lookup;for(i=0;i<len;i+=4)encoded1=target[data.charCodeAt(i)],encoded2=target[data.charCodeAt(i+1)],encoded3=target[data.charCodeAt(i+2)],encoded4=target[data.charCodeAt(i+3)],bytes[p++]=encoded1<<2|encoded2>>4,bytes[p++]=(encoded2&15)<<4|encoded3>>2,bytes[p++]=(encoded3&3)<<6|encoded4&63;return arraybuffer};base64.fromArrayBuffer=(arrBuf,urlMode)=>{let bytes=new Uint8Array(arrBuf),i,result="",len=bytes.length,target=urlMode?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(i=0;i<len;i+=3)result+=target[bytes[i]>>2],result+=target[(bytes[i]&3)<<4|bytes[i+1]>>4],result+=target[(bytes[i+1]&15)<<2|bytes[i+2]>>6],result+=target[bytes[i+2]&63];let remainder=len%3;if(remainder===2)result=result.substring(0,result.length-1)+(urlMode?"":"=");else if(remainder===1)result=result.substring(0,result.length-2)+(urlMode?"":"==");return result};base64.toString=(str3,urlMode)=>{return new TextDecoder().decode(base64.toArrayBuffer(str3,urlMode))};base64.fromString=(str3,urlMode)=>{return base64.fromArrayBuffer(new TextEncoder().encode(str3),urlMode)};base64.validate=(encoded,urlMode)=>{if(!(typeof encoded==="string"||encoded instanceof String))return!1;try{return urlMode?base64UrlPattern.test(encoded):base64Pattern.test(encoded)}catch(_e){return!1}};base64.base64=base64;base64_default=base64});var exports_isoBase64URL={};__export(exports_isoBase64URL,{trimPadding:()=>trimPadding,toUTF8String:()=>toUTF8String,toBuffer:()=>toBuffer,toBase64:()=>toBase64,isBase64URL:()=>isBase64URL,isBase64:()=>isBase64,fromUTF8String:()=>fromUTF8String,fromBuffer:()=>fromBuffer});function toBuffer(base64urlString,from="base64url"){let _buffer=base64_default.toArrayBuffer(base64urlString,from==="base64url");return new Uint8Array(_buffer)}function fromBuffer(buffer,to="base64url"){let _normalized=new Uint8Array(buffer);return base64_default.fromArrayBuffer(_normalized.buffer,to==="base64url")}function toBase64(base64urlString){let fromBase64Url=base64_default.toArrayBuffer(base64urlString,!0);return base64_default.fromArrayBuffer(fromBase64Url)}function fromUTF8String(utf8String){return base64_default.fromString(utf8String,!0)}function toUTF8String(base64urlString){return base64_default.toString(base64urlString,!0)}function isBase64(input){return base64_default.validate(input,!1)}function isBase64URL(input){return input=trimPadding(input),base64_default.validate(input,!0)}function trimPadding(input){return input.replace(/=/g,"")}var init_isoBase64URL=__esm(()=>{init_base64()});function decodeLength(data,argument,index){if(argument<24)return[argument,1];let remainingDataLength=data.byteLength-index-1,view=new DataView(data.buffer,index+1),output,bytes=0;switch(argument){case 24:{if(remainingDataLength>0)output=view.getUint8(0),bytes=2;break}case 25:{if(remainingDataLength>1)output=view.getUint16(0,!1),bytes=3;break}case 26:{if(remainingDataLength>3)output=view.getUint32(0,!1),bytes=5;break}case 27:{if(remainingDataLength>7){let bigOutput=view.getBigUint64(0,!1);if(bigOutput>=24n&&bigOutput<=Number.MAX_SAFE_INTEGER)return[Number(bigOutput),9]}break}}if(output&&output>=24)return[output,bytes];throw Error("Length not supported or not well formed")}function encodeLength(major,argument){let majorEncoded=major<<5;if(argument<0)throw Error("CBOR Data Item argument must not be negative");let bigintArgument;if(typeof argument=="number"){if(!Number.isInteger(argument))throw Error("CBOR Data Item argument must be an integer");bigintArgument=BigInt(argument)}else bigintArgument=argument;if(major==MAJOR_TYPE_NEGATIVE_INTEGER){if(bigintArgument==0n)throw Error("CBOR Data Item argument cannot be zero when negative");bigintArgument=bigintArgument-1n}if(bigintArgument>18446744073709551615n)throw Error("CBOR number out of range");let buffer=new Uint8Array(8);if(new DataView(buffer.buffer).setBigUint64(0,bigintArgument,!1),bigintArgument<=23)return[majorEncoded|buffer[7]];else if(bigintArgument<=255)return[majorEncoded|24,buffer[7]];else if(bigintArgument<=65535)return[majorEncoded|25,...buffer.slice(6)];else if(bigintArgument<=4294967295)return[majorEncoded|26,...buffer.slice(4)];else return[majorEncoded|27,...buffer]}var MAJOR_TYPE_UNSIGNED_INTEGER=0,MAJOR_TYPE_NEGATIVE_INTEGER=1,MAJOR_TYPE_BYTE_STRING=2,MAJOR_TYPE_TEXT_STRING=3,MAJOR_TYPE_ARRAY=4,MAJOR_TYPE_MAP=5,MAJOR_TYPE_TAG=6,MAJOR_TYPE_SIMPLE_OR_FLOAT=7;class CBORTag{constructor(tag,value){Object.defineProperty(this,"tagId",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"tagValue",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.tagId=tag,this.tagValue=value}get tag(){return this.tagId}get value(){return this.tagValue}}function decodeUnsignedInteger(data,argument,index){return decodeLength(data,argument,index)}function decodeNegativeInteger(data,argument,index){let[value,length]=decodeUnsignedInteger(data,argument,index);return[-value-1,length]}function decodeByteString(data,argument,index){let[lengthValue,lengthConsumed]=decodeLength(data,argument,index),dataStartIndex=index+lengthConsumed;return[new Uint8Array(data.buffer.slice(dataStartIndex,dataStartIndex+lengthValue)),lengthConsumed+lengthValue]}function decodeString(data,argument,index){let[value,length]=decodeByteString(data,argument,index);return[TEXT_DECODER.decode(value),length]}function decodeArray(data,argument,index){if(argument===0)return[[],1];let[length,lengthConsumed]=decodeLength(data,argument,index),consumedLength=lengthConsumed,value=[];for(let i=0;i<length;i++){if(data.byteLength-index-consumedLength<=0)throw Error("array is not supported or well formed");let[decodedValue,consumed]=decodeNext(data,index+consumedLength);value.push(decodedValue),consumedLength+=consumed}return[value,consumedLength]}function decodeMap(data,argument,index){if(argument===0)return[new Map,1];let[length,lengthConsumed]=decodeLength(data,argument,index),consumedLength=lengthConsumed,result=new Map;for(let i=0;i<length;i++){let remainingDataLength=data.byteLength-index-consumedLength;if(remainingDataLength<=0)throw Error(MAP_ERROR);let[key2,keyConsumed]=decodeNext(data,index+consumedLength);if(consumedLength+=keyConsumed,remainingDataLength-=keyConsumed,remainingDataLength<=0)throw Error(MAP_ERROR);if(typeof key2!=="string"&&typeof key2!=="number")throw Error(MAP_ERROR);if(result.has(key2))throw Error(MAP_ERROR);let[value,valueConsumed]=decodeNext(data,index+consumedLength);consumedLength+=valueConsumed,result.set(key2,value)}return[result,consumedLength]}function decodeFloat16(data,index){if(index+3>data.byteLength)throw Error("CBOR stream ended before end of Float 16");let result=data.getUint16(index+1,!1);if(result==31744)return[1/0,3];else if(result==32256)return[NaN,3];else if(result==64512)return[-1/0,3];throw Error("Float16 data is unsupported")}function decodeFloat32(data,index){if(index+5>data.byteLength)throw Error("CBOR stream ended before end of Float 32");return[data.getFloat32(index+1,!1),5]}function decodeFloat64(data,index){if(index+9>data.byteLength)throw Error("CBOR stream ended before end of Float 64");return[data.getFloat64(index+1,!1),9]}function decodeTag(data,argument,index){let[tag,tagBytes]=decodeLength(data,argument,index),[value,valueBytes]=decodeNext(data,index+tagBytes);return[new CBORTag(tag,value),tagBytes+valueBytes]}function decodeNext(data,index){if(index>=data.byteLength)throw Error("CBOR stream ended before tag value");let byte=data.getUint8(index),majorType=byte>>5,argument=byte&31;switch(majorType){case MAJOR_TYPE_UNSIGNED_INTEGER:return decodeUnsignedInteger(data,argument,index);case MAJOR_TYPE_NEGATIVE_INTEGER:return decodeNegativeInteger(data,argument,index);case MAJOR_TYPE_BYTE_STRING:return decodeByteString(data,argument,index);case MAJOR_TYPE_TEXT_STRING:return decodeString(data,argument,index);case MAJOR_TYPE_ARRAY:return decodeArray(data,argument,index);case MAJOR_TYPE_MAP:return decodeMap(data,argument,index);case MAJOR_TYPE_TAG:return decodeTag(data,argument,index);case MAJOR_TYPE_SIMPLE_OR_FLOAT:switch(argument){case 20:return[!1,1];case 21:return[!0,1];case 22:return[null,1];case 23:return[void 0,1];case 25:return decodeFloat16(data,index);case 26:return decodeFloat32(data,index);case 27:return decodeFloat64(data,index)}}throw Error(`Unsupported or not well formed at ${index}`)}function encodeSimple(data){if(data===!0)return 245;else if(data===!1)return 244;else if(data===null)return 246;return 247}function encodeFloat(data){if(Math.fround(data)==data||!Number.isFinite(data)||Number.isNaN(data)){let output=new Uint8Array(5);return output[0]=250,new DataView(output.buffer).setFloat32(1,data,!1),output}else{let output=new Uint8Array(9);return output[0]=251,new DataView(output.buffer).setFloat64(1,data,!1),output}}function encodeNumber(data){if(typeof data=="number"){if(Number.isSafeInteger(data))if(data<0)return encodeLength(MAJOR_TYPE_NEGATIVE_INTEGER,Math.abs(data));else return encodeLength(MAJOR_TYPE_UNSIGNED_INTEGER,data);return[encodeFloat(data)]}else if(data<0n)return encodeLength(MAJOR_TYPE_NEGATIVE_INTEGER,data*-1n);else return encodeLength(MAJOR_TYPE_UNSIGNED_INTEGER,data)}function encodeString(data,output){output.push(...encodeLength(MAJOR_TYPE_TEXT_STRING,data.length)),output.push(ENCODER.encode(data))}function encodeBytes(data,output){output.push(...encodeLength(MAJOR_TYPE_BYTE_STRING,data.length)),output.push(data)}function encodeArray(data,output){output.push(...encodeLength(MAJOR_TYPE_ARRAY,data.length));for(let element of data)encodePartialCBOR(element,output)}function encodeMap(data,output){output.push(new Uint8Array(encodeLength(MAJOR_TYPE_MAP,data.size)));for(let[key2,value]of data.entries())encodePartialCBOR(key2,output),encodePartialCBOR(value,output)}function encodeTag(tag,output){output.push(...encodeLength(MAJOR_TYPE_TAG,tag.tag)),encodePartialCBOR(tag.value,output)}function encodePartialCBOR(data,output){if(typeof data=="boolean"||data===null||data==null){output.push(encodeSimple(data));return}if(typeof data=="number"||typeof data=="bigint"){output.push(...encodeNumber(data));return}if(typeof data=="string"){encodeString(data,output);return}if(data instanceof Uint8Array){encodeBytes(data,output);return}if(Array.isArray(data)){encodeArray(data,output);return}if(data instanceof Map){encodeMap(data,output);return}if(data instanceof CBORTag){encodeTag(data,output);return}throw Error("Not implemented")}function decodePartialCBOR(data,index){if(data.byteLength===0||data.byteLength<=index||index<0)throw Error("No data");if(data instanceof Uint8Array)return decodeNext(new DataView(data.buffer),index);else if(data instanceof ArrayBuffer)return decodeNext(new DataView(data),index);return decodeNext(data,index)}function encodeCBOR(data){let results=[];encodePartialCBOR(data,results);let length=0;for(let result of results)if(typeof result=="number")length+=1;else length+=result.length;let output=new Uint8Array(length),index=0;for(let result of results)if(typeof result=="number")output[index]=result,index+=1;else output.set(result,index),index+=result.length;return output}var TEXT_DECODER,MAP_ERROR="Map is not supported or well formed",ENCODER;var init_cbor=__esm(()=>{TEXT_DECODER=new TextDecoder;ENCODER=new TextEncoder});var init_esm=__esm(()=>{init_cbor()});var exports_isoCBOR={};__export(exports_isoCBOR,{encode:()=>encode,decodeFirst:()=>decodeFirst});function decodeFirst(input){let _input=new Uint8Array(input),decoded=decodePartialCBOR(_input,0),[first]=decoded;return first}function encode(input){return encodeCBOR(input)}var init_isoCBOR=__esm(()=>{init_esm()});function isCOSEPublicKeyOKP(cosePublicKey){let kty=cosePublicKey.get(COSEKEYS.kty);return isCOSEKty(kty)&&kty===COSEKTY.OKP}function isCOSEPublicKeyEC2(cosePublicKey){let kty=cosePublicKey.get(COSEKEYS.kty);return isCOSEKty(kty)&&kty===COSEKTY.EC2}function isCOSEPublicKeyRSA(cosePublicKey){let kty=cosePublicKey.get(COSEKEYS.kty);return isCOSEKty(kty)&&kty===COSEKTY.RSA}function isCOSEKty(kty){return Object.values(COSEKTY).indexOf(kty)>=0}function isCOSECrv(crv){return Object.values(COSECRV).indexOf(crv)>=0}function isCOSEAlg(alg){return Object.values(COSEALG).indexOf(alg)>=0}var COSEKEYS,COSEKTY,COSECRV,COSEALG;var init_cose=__esm(()=>{(function(COSEKEYS2){COSEKEYS2[COSEKEYS2.kty=1]="kty",COSEKEYS2[COSEKEYS2.alg=3]="alg",COSEKEYS2[COSEKEYS2.crv=-1]="crv",COSEKEYS2[COSEKEYS2.x=-2]="x",COSEKEYS2[COSEKEYS2.y=-3]="y",COSEKEYS2[COSEKEYS2.n=-1]="n",COSEKEYS2[COSEKEYS2.e=-2]="e"})(COSEKEYS||(COSEKEYS={}));(function(COSEKTY2){COSEKTY2[COSEKTY2.OKP=1]="OKP",COSEKTY2[COSEKTY2.EC2=2]="EC2",COSEKTY2[COSEKTY2.RSA=3]="RSA"})(COSEKTY||(COSEKTY={}));(function(COSECRV2){COSECRV2[COSECRV2.P256=1]="P256",COSECRV2[COSECRV2.P384=2]="P384",COSECRV2[COSECRV2.P521=3]="P521",COSECRV2[COSECRV2.ED25519=6]="ED25519",COSECRV2[COSECRV2.SECP256K1=8]="SECP256K1"})(COSECRV||(COSECRV={}));(function(COSEALG2){COSEALG2[COSEALG2.ES256=-7]="ES256",COSEALG2[COSEALG2.EdDSA=-8]="EdDSA",COSEALG2[COSEALG2.ES384=-35]="ES384",COSEALG2[COSEALG2.ES512=-36]="ES512",COSEALG2[COSEALG2.PS256=-37]="PS256",COSEALG2[COSEALG2.PS384=-38]="PS384",COSEALG2[COSEALG2.PS512=-39]="PS512",COSEALG2[COSEALG2.ES256K=-47]="ES256K",COSEALG2[COSEALG2.RS256=-257]="RS256",COSEALG2[COSEALG2.RS384=-258]="RS384",COSEALG2[COSEALG2.RS512=-259]="RS512",COSEALG2[COSEALG2.RS1=-65535]="RS1"})(COSEALG||(COSEALG={}))});function mapCoseAlgToWebCryptoAlg(alg){if([COSEALG.RS1].indexOf(alg)>=0)return"SHA-1";else if([COSEALG.ES256,COSEALG.PS256,COSEALG.RS256].indexOf(alg)>=0)return"SHA-256";else if([COSEALG.ES384,COSEALG.PS384,COSEALG.RS384].indexOf(alg)>=0)return"SHA-384";else if([COSEALG.ES512,COSEALG.PS512,COSEALG.RS512,COSEALG.EdDSA].indexOf(alg)>=0)return"SHA-512";throw Error(`Could not map COSE alg value of ${alg} to a WebCrypto alg`)}var init_mapCoseAlgToWebCryptoAlg=__esm(()=>{init_cose()});function getWebCrypto(){return new Promise((resolve2,reject)=>{if(webCrypto)return resolve2(webCrypto);let _globalThisCrypto=_getWebCryptoInternals.stubThisGlobalThisCrypto();if(_globalThisCrypto)return webCrypto=_globalThisCrypto,resolve2(webCrypto);return reject(new MissingWebCrypto)})}var webCrypto=void 0,MissingWebCrypto,_getWebCryptoInternals;var init_getWebCrypto=__esm(()=>{MissingWebCrypto=class MissingWebCrypto extends Error{constructor(){super("An instance of the Crypto API could not be located");this.name="MissingWebCrypto"}};_getWebCryptoInternals={stubThisGlobalThisCrypto:()=>globalThis.crypto,setCachedCrypto:(newCrypto)=>{webCrypto=newCrypto}}});async function digest(data,algorithm){let WebCrypto=await getWebCrypto(),subtleAlgorithm=mapCoseAlgToWebCryptoAlg(algorithm),hashed=await WebCrypto.subtle.digest(subtleAlgorithm,data);return new Uint8Array(hashed)}var init_digest=__esm(()=>{init_mapCoseAlgToWebCryptoAlg();init_getWebCrypto()});async function getRandomValues(array){return(await getWebCrypto()).getRandomValues(array),array}var init_getRandomValues=__esm(()=>{init_getWebCrypto()});async function importKey(opts){let WebCrypto=await getWebCrypto(),{keyData,algorithm}=opts;return WebCrypto.subtle.importKey("jwk",keyData,algorithm,!1,["verify"])}var init_importKey=__esm(()=>{init_getWebCrypto()});async function verifyEC2(opts){let{cosePublicKey,signature,data,shaHashOverride}=opts,WebCrypto=await getWebCrypto(),alg=cosePublicKey.get(COSEKEYS.alg),crv=cosePublicKey.get(COSEKEYS.crv),x=cosePublicKey.get(COSEKEYS.x),y=cosePublicKey.get(COSEKEYS.y);if(!alg)throw Error("Public key was missing alg (EC2)");if(!crv)throw Error("Public key was missing crv (EC2)");if(!x)throw Error("Public key was missing x (EC2)");if(!y)throw Error("Public key was missing y (EC2)");let _crv;if(crv===COSECRV.P256)_crv="P-256";else if(crv===COSECRV.P384)_crv="P-384";else if(crv===COSECRV.P521)_crv="P-521";else throw Error(`Unexpected COSE crv value of ${crv} (EC2)`);let keyData={kty:"EC",crv:_crv,x:exports_isoBase64URL.fromBuffer(x),y:exports_isoBase64URL.fromBuffer(y),ext:!1},key2=await importKey({keyData,algorithm:{name:"ECDSA",namedCurve:_crv}}),subtleAlg=mapCoseAlgToWebCryptoAlg(alg);if(shaHashOverride)subtleAlg=mapCoseAlgToWebCryptoAlg(shaHashOverride);let verifyAlgorithm={name:"ECDSA",hash:{name:subtleAlg}};return WebCrypto.subtle.verify(verifyAlgorithm,key2,signature,data)}var init_verifyEC2=__esm(()=>{init_cose();init_mapCoseAlgToWebCryptoAlg();init_importKey();init_iso();init_getWebCrypto()});function mapCoseAlgToWebCryptoKeyAlgName(alg){if([COSEALG.EdDSA].indexOf(alg)>=0)return"Ed25519";else if([COSEALG.ES256,COSEALG.ES384,COSEALG.ES512,COSEALG.ES256K].indexOf(alg)>=0)return"ECDSA";else if([COSEALG.RS256,COSEALG.RS384,COSEALG.RS512,COSEALG.RS1].indexOf(alg)>=0)return"RSASSA-PKCS1-v1_5";else if([COSEALG.PS256,COSEALG.PS384,COSEALG.PS512].indexOf(alg)>=0)return"RSA-PSS";throw Error(`Could not map COSE alg value of ${alg} to a WebCrypto key alg name`)}var init_mapCoseAlgToWebCryptoKeyAlgName=__esm(()=>{init_cose()});async function verifyRSA(opts){let{cosePublicKey,signature,data,shaHashOverride}=opts,WebCrypto=await getWebCrypto(),alg=cosePublicKey.get(COSEKEYS.alg),n=cosePublicKey.get(COSEKEYS.n),e=cosePublicKey.get(COSEKEYS.e);if(!alg)throw Error("Public key was missing alg (RSA)");if(!isCOSEAlg(alg))throw Error(`Public key had invalid alg ${alg} (RSA)`);if(!n)throw Error("Public key was missing n (RSA)");if(!e)throw Error("Public key was missing e (RSA)");let keyData={kty:"RSA",alg:"",n:exports_isoBase64URL.fromBuffer(n),e:exports_isoBase64URL.fromBuffer(e),ext:!1},keyAlgorithm={name:mapCoseAlgToWebCryptoKeyAlgName(alg),hash:{name:mapCoseAlgToWebCryptoAlg(alg)}},verifyAlgorithm={name:mapCoseAlgToWebCryptoKeyAlgName(alg)};if(shaHashOverride)keyAlgorithm.hash.name=mapCoseAlgToWebCryptoAlg(shaHashOverride);if(keyAlgorithm.name==="RSASSA-PKCS1-v1_5"){if(keyAlgorithm.hash.name==="SHA-256")keyData.alg="RS256";else if(keyAlgorithm.hash.name==="SHA-384")keyData.alg="RS384";else if(keyAlgorithm.hash.name==="SHA-512")keyData.alg="RS512";else if(keyAlgorithm.hash.name==="SHA-1")keyData.alg="RS1"}else if(keyAlgorithm.name==="RSA-PSS"){let saltLength=0;if(keyAlgorithm.hash.name==="SHA-256")keyData.alg="PS256",saltLength=32;else if(keyAlgorithm.hash.name==="SHA-384")keyData.alg="PS384",saltLength=48;else if(keyAlgorithm.hash.name==="SHA-512")keyData.alg="PS512",saltLength=64;verifyAlgorithm.saltLength=saltLength}else throw Error(`Unexpected RSA key algorithm ${alg} (${keyAlgorithm.name})`);let key2=await importKey({keyData,algorithm:keyAlgorithm});return WebCrypto.subtle.verify(verifyAlgorithm,key2,signature,data)}var init_verifyRSA=__esm(()=>{init_cose();init_mapCoseAlgToWebCryptoAlg();init_importKey();init_iso();init_mapCoseAlgToWebCryptoKeyAlgName();init_getWebCrypto()});function convertAAGUIDToString(aaguid){let hex=exports_isoUint8Array.toHex(aaguid);return[hex.slice(0,8),hex.slice(8,12),hex.slice(12,16),hex.slice(16,20),hex.slice(20,32)].join("-")}var init_convertAAGUIDToString=__esm(()=>{init_iso()});function convertCertBufferToPEM(certBuffer){let b64cert;if(typeof certBuffer==="string")if(exports_isoBase64URL.isBase64URL(certBuffer))b64cert=exports_isoBase64URL.toBase64(certBuffer);else if(exports_isoBase64URL.isBase64(certBuffer))b64cert=certBuffer;else throw Error("Certificate is not a valid base64 or base64url string");else b64cert=exports_isoBase64URL.fromBuffer(certBuffer,"base64");let PEMKey="";for(let i=0;i<Math.ceil(b64cert.length/64);i+=1){let start=64*i;PEMKey+=`${b64cert.substr(start,64)}
|
|
102
102
|
`}return PEMKey=`-----BEGIN CERTIFICATE-----
|
|
103
103
|
${PEMKey}-----END CERTIFICATE-----
|
|
104
104
|
`,PEMKey}var init_convertCertBufferToPEM=__esm(()=>{init_iso()});function convertCOSEtoPKCS(cosePublicKey){let struct=exports_isoCBOR.decodeFirst(cosePublicKey),tag=Uint8Array.from([4]),x=struct.get(COSEKEYS.x),y=struct.get(COSEKEYS.y);if(!x)throw Error("COSE public key was missing x");if(y)return exports_isoUint8Array.concat([tag,x,y]);return exports_isoUint8Array.concat([tag,x])}var init_convertCOSEtoPKCS=__esm(()=>{init_iso();init_cose()});function decodeAttestationObject(attestationObject){return _decodeAttestationObjectInternals.stubThis(exports_isoCBOR.decodeFirst(attestationObject))}var _decodeAttestationObjectInternals;var init_decodeAttestationObject=__esm(()=>{init_iso();_decodeAttestationObjectInternals={stubThis:(value)=>value}});function decodeClientDataJSON(data){let toString=exports_isoBase64URL.toUTF8String(data),clientData=JSON.parse(toString);return _decodeClientDataJSONInternals.stubThis(clientData)}var _decodeClientDataJSONInternals;var init_decodeClientDataJSON=__esm(()=>{init_iso();_decodeClientDataJSONInternals={stubThis:(value)=>value}});function decodeCredentialPublicKey(publicKey){return _decodeCredentialPublicKeyInternals.stubThis(exports_isoCBOR.decodeFirst(publicKey))}var _decodeCredentialPublicKeyInternals;var init_decodeCredentialPublicKey=__esm(()=>{init_iso();_decodeCredentialPublicKeyInternals={stubThis:(value)=>value}});async function generateUserID(){let newUserID=new Uint8Array(32);return await exports_isoCrypto.getRandomValues(newUserID),_generateUserIDInternals.stubThis(newUserID)}var _generateUserIDInternals;var init_generateUserID=__esm(()=>{init_iso();_generateUserIDInternals={stubThis:(value)=>value}});class BufferSourceConverter{static isArrayBuffer(data){return Object.prototype.toString.call(data)==="[object ArrayBuffer]"}static toArrayBuffer(data){if(this.isArrayBuffer(data))return data;if(data.byteLength===data.buffer.byteLength)return data.buffer;if(data.byteOffset===0&&data.byteLength===data.buffer.byteLength)return data.buffer;return this.toUint8Array(data.buffer).slice(data.byteOffset,data.byteOffset+data.byteLength).buffer}static toUint8Array(data){return this.toView(data,Uint8Array)}static toView(data,type){if(data.constructor===type)return data;if(this.isArrayBuffer(data))return new type(data);if(this.isArrayBufferView(data))return new type(data.buffer,data.byteOffset,data.byteLength);throw TypeError("The provided value is not of type '(ArrayBuffer or ArrayBufferView)'")}static isBufferSource(data){return this.isArrayBufferView(data)||this.isArrayBuffer(data)}static isArrayBufferView(data){return ArrayBuffer.isView(data)||data&&this.isArrayBuffer(data.buffer)}static isEqual(a,b){let aView=BufferSourceConverter.toUint8Array(a),bView=BufferSourceConverter.toUint8Array(b);if(aView.length!==bView.byteLength)return!1;for(let i=0;i<aView.length;i++)if(aView[i]!==bView[i])return!1;return!0}static concat(...args){let buffers;if(Array.isArray(args[0])&&!(args[1]instanceof Function))buffers=args[0];else if(Array.isArray(args[0])&&args[1]instanceof Function)buffers=args[0];else if(args[args.length-1]instanceof Function)buffers=args.slice(0,args.length-1);else buffers=args;let size=0;for(let buffer of buffers)size+=buffer.byteLength;let res=new Uint8Array(size),offset=0;for(let buffer of buffers){let view=this.toUint8Array(buffer);res.set(view,offset),offset+=view.length}if(args[args.length-1]instanceof Function)return this.toView(res,args[args.length-1]);return res.buffer}}class Utf8Converter{static fromString(text){let s=unescape(encodeURIComponent(text)),uintArray=new Uint8Array(s.length);for(let i=0;i<s.length;i++)uintArray[i]=s.charCodeAt(i);return uintArray.buffer}static toString(buffer){let buf=BufferSourceConverter.toUint8Array(buffer),encodedString="";for(let i=0;i<buf.length;i++)encodedString+=String.fromCharCode(buf[i]);return decodeURIComponent(escape(encodedString))}}class Utf16Converter{static toString(buffer,littleEndian=!1){let arrayBuffer=BufferSourceConverter.toArrayBuffer(buffer),dataView=new DataView(arrayBuffer),res="";for(let i=0;i<arrayBuffer.byteLength;i+=2){let code=dataView.getUint16(i,littleEndian);res+=String.fromCharCode(code)}return res}static fromString(text,littleEndian=!1){let res=new ArrayBuffer(text.length*2),dataView=new DataView(res);for(let i=0;i<text.length;i++)dataView.setUint16(i*2,text.charCodeAt(i),littleEndian);return res}}class Convert{static isHex(data){return typeof data===STRING_TYPE&&HEX_REGEX.test(data)}static isBase64(data){return typeof data===STRING_TYPE&&BASE64_REGEX.test(data)}static isBase64Url(data){return typeof data===STRING_TYPE&&BASE64URL_REGEX.test(data)}static ToString(buffer,enc="utf8"){let buf=BufferSourceConverter.toUint8Array(buffer);switch(enc.toLowerCase()){case"utf8":return this.ToUtf8String(buf);case"binary":return this.ToBinary(buf);case"hex":return this.ToHex(buf);case"base64":return this.ToBase64(buf);case"base64url":return this.ToBase64Url(buf);case"utf16le":return Utf16Converter.toString(buf,!0);case"utf16":case"utf16be":return Utf16Converter.toString(buf);default:throw Error(`Unknown type of encoding '${enc}'`)}}static FromString(str3,enc="utf8"){if(!str3)return new ArrayBuffer(0);switch(enc.toLowerCase()){case"utf8":return this.FromUtf8String(str3);case"binary":return this.FromBinary(str3);case"hex":return this.FromHex(str3);case"base64":return this.FromBase64(str3);case"base64url":return this.FromBase64Url(str3);case"utf16le":return Utf16Converter.fromString(str3,!0);case"utf16":case"utf16be":return Utf16Converter.fromString(str3);default:throw Error(`Unknown type of encoding '${enc}'`)}}static ToBase64(buffer){let buf=BufferSourceConverter.toUint8Array(buffer);if(typeof btoa<"u"){let binary=this.ToString(buf,"binary");return btoa(binary)}else return Buffer.from(buf).toString("base64")}static FromBase64(base642){let formatted=this.formatString(base642);if(!formatted)return new ArrayBuffer(0);if(!Convert.isBase64(formatted))throw TypeError("Argument 'base64Text' is not Base64 encoded");if(typeof atob<"u")return this.FromBinary(atob(formatted));else return new Uint8Array(Buffer.from(formatted,"base64")).buffer}static FromBase64Url(base64url){let formatted=this.formatString(base64url);if(!formatted)return new ArrayBuffer(0);if(!Convert.isBase64Url(formatted))throw TypeError("Argument 'base64url' is not Base64Url encoded");return this.FromBase64(this.Base64Padding(formatted.replace(/\-/g,"+").replace(/\_/g,"/")))}static ToBase64Url(data){return this.ToBase64(data).replace(/\+/g,"-").replace(/\//g,"_").replace(/\=/g,"")}static FromUtf8String(text,encoding=Convert.DEFAULT_UTF8_ENCODING){switch(encoding){case"ascii":return this.FromBinary(text);case"utf8":return Utf8Converter.fromString(text);case"utf16":case"utf16be":return Utf16Converter.fromString(text);case"utf16le":case"usc2":return Utf16Converter.fromString(text,!0);default:throw Error(`Unknown type of encoding '${encoding}'`)}}static ToUtf8String(buffer,encoding=Convert.DEFAULT_UTF8_ENCODING){switch(encoding){case"ascii":return this.ToBinary(buffer);case"utf8":return Utf8Converter.toString(buffer);case"utf16":case"utf16be":return Utf16Converter.toString(buffer);case"utf16le":case"usc2":return Utf16Converter.toString(buffer,!0);default:throw Error(`Unknown type of encoding '${encoding}'`)}}static FromBinary(text){let stringLength=text.length,resultView=new Uint8Array(stringLength);for(let i=0;i<stringLength;i++)resultView[i]=text.charCodeAt(i);return resultView.buffer}static ToBinary(buffer){let buf=BufferSourceConverter.toUint8Array(buffer),res="";for(let i=0;i<buf.length;i++)res+=String.fromCharCode(buf[i]);return res}static ToHex(buffer){let buf=BufferSourceConverter.toUint8Array(buffer),result="",len=buf.length;for(let i=0;i<len;i++){let byte=buf[i];if(byte<16)result+="0";result+=byte.toString(16)}return result}static FromHex(hexString){let formatted=this.formatString(hexString);if(!formatted)return new ArrayBuffer(0);if(!Convert.isHex(formatted))throw TypeError("Argument 'hexString' is not HEX encoded");if(formatted.length%2)formatted=`0${formatted}`;let res=new Uint8Array(formatted.length/2);for(let i=0;i<formatted.length;i=i+2){let c=formatted.slice(i,i+2);res[i/2]=parseInt(c,16)}return res.buffer}static ToUtf16String(buffer,littleEndian=!1){return Utf16Converter.toString(buffer,littleEndian)}static FromUtf16String(text,littleEndian=!1){return Utf16Converter.fromString(text,littleEndian)}static Base64Padding(base642){let padCount=4-base642.length%4;if(padCount<4)for(let i=0;i<padCount;i++)base642+="=";return base642}static formatString(data){return(data===null||data===void 0?void 0:data.replace(/[\n\r\t ]/g,""))||""}}function combine(...buf){let totalByteLength=buf.map((item)=>item.byteLength).reduce((prev,cur)=>prev+cur),res=new Uint8Array(totalByteLength),currentPos=0;return buf.map((item)=>new Uint8Array(item)).forEach((arr)=>{for(let item2 of arr)res[currentPos++]=item2}),res.buffer}function isEqual(bytes1,bytes2){if(!(bytes1&&bytes2))return!1;if(bytes1.byteLength!==bytes2.byteLength)return!1;let b1=new Uint8Array(bytes1),b2=new Uint8Array(bytes2);for(let i=0;i<bytes1.byteLength;i++)if(b1[i]!==b2[i])return!1;return!0}var STRING_TYPE="string",HEX_REGEX,BASE64_REGEX,BASE64URL_REGEX;var init_index_es=__esm(()=>{/*!
|