UNPKG

js-use-core

Version:

JavaScript Comprehensive tool library, including full screen, copy and paste functions

2 lines (1 loc) 27.6 kB
"use strict";function e(e,t={}){if(!e||"string"!=typeof e)return!1;const{protocols:r=["http:","https:"],requireProtocol:s=!0,allowLocalhost:i=!0,allowIp:n=!0}=t;try{let t=e;s||e.includes("://")||(t=`https://${e}`);const o=new URL(t);return!!r.includes(o.protocol)&&(!(!i&&("localhost"===o.hostname||"127.0.0.1"===o.hostname||o.hostname.endsWith(".local")))&&!(!n&&/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(o.hostname)))}catch{return!1}}function t(e,t){if(!e)return"";try{return new URL(e,t).href}catch{return e}}function r(e,t){if(!e||!t||"object"!=typeof t)return e;try{const r=new URL(e);for(const[e,s]of Object.entries(t))if(null==s)r.searchParams.delete(e);else if(Array.isArray(s)){r.searchParams.delete(e);for(const t of s)r.searchParams.append(e,String(t))}else r.searchParams.set(e,String(s));return r.href}catch{return e}}function s(e,t){if(!e||!t)return e;try{const r=new URL(e),s=Array.isArray(t)?t:[t];for(const e of s)r.searchParams.delete(e);return r.href}catch{return e}}function i(e){return!!e&&(!e.includes("://")&&!e.startsWith("//"))}function n(e,t=!1){if(!e||"string"!=typeof e)return"";try{return t?encodeURIComponent(e):encodeURI(e)}catch{return e}}function o(e,t=!1){if(!e||"string"!=typeof e)return"";try{return t?decodeURIComponent(e):decodeURI(e)}catch{return e}}Object.defineProperty(exports,"__esModule",{value:!0});function a(e){const t={};if(!e||"string"!=typeof e)return t;try{const r=e.startsWith("?")?e.slice(1):e;if(!r)return t;const s=new URLSearchParams(r),i=new Map;for(const[e,t]of s.entries())i.has(e)||i.set(e,[]),i.get(e).push(t);for(const[e,r]of i.entries())if(e.endsWith("[]")){t[e.slice(0,-2)]=r}else 1===r.length?t[e]=r[0]:t[e]=r}catch(r){const s=(e.startsWith("?")?e.slice(1):e).split("&");for(const e of s){if(!e)continue;const r=e.indexOf("="),s=-1!==r?e.slice(0,r):e,i=-1!==r?e.slice(r+1):"";if(s)try{const e=o(s,!0),r=o(i,!0);if(e.endsWith("[]")){const s=e.slice(0,-2);t[s]||(t[s]=[]),t[s].push(r)}else t[e]?Array.isArray(t[e])?t[e].push(r):t[e]=[t[e],r]:t[e]=r}catch{t[s]=i}}}return t}function h(e,t=!0){if(!e||"object"!=typeof e)return"";const r=[];try{for(const[t,s]of Object.entries(e))if(null!=s)if(Array.isArray(s)){for(const e of s)if(null!=e){const s=encodeURIComponent(t)+"[]",i=encodeURIComponent(String(e));r.push(`${s}=${i}`)}}else{const e=encodeURIComponent(t),i=encodeURIComponent(String(s));r.push(`${e}=${i}`)}const s=r.join("&");return s?t?`?${s}`:s:""}catch(e){return""}}class EventEmitter{constructor(){this.events=new Map,this.maxListeners=10}on(e,t,r){if("function"!=typeof t)throw new Error("Listener must be a function");const s={listener:t,once:r?.once||!1,priority:r?.priority||0};this.events.has(e)||this.events.set(e,[]);const i=this.events.get(e);i.length,this.maxListeners;let n=!1;for(let e=0;e<i.length;e++)if(s.priority>(i[e].priority||0)){i.splice(e,0,s),n=!0;break}return n||i.push(s),this}once(e,t,r){return this.on(e,t,{once:!0,priority:r})}off(e,t){if(!this.events.has(e))return this;const r=this.events.get(e);if(t){const s=r.findIndex(e=>e.listener===t);-1!==s&&(r.splice(s,1),0===r.length&&this.events.delete(e))}else this.events.delete(e);return this}emit(e,...t){if(!this.events.has(e))return!1;const r=this.events.get(e).slice(),s=[];for(const e of r)try{e.listener.apply(this,t),e.once&&s.push(e)}catch(e){}if(s.length>0){const t=this.events.get(e);if(t){for(const e of s){const r=t.indexOf(e);-1!==r&&t.splice(r,1)}0===t.length&&this.events.delete(e)}}return!0}listenerCount(e){return this.events.get(e)?.length||0}listeners(e){return this.events.get(e)?.map(e=>e.listener)||[]}eventNames(){return Array.from(this.events.keys())}removeAllListeners(e){return e?this.events.delete(e):this.events.clear(),this}setMaxListeners(e){if(e<0||!Number.isInteger(e))throw new Error("Max listeners must be a non-negative integer");return this.maxListeners=e,this}getMaxListeners(){return this.maxListeners}prependListener(e,t){return this.on(e,t,{priority:Number.MAX_SAFE_INTEGER})}prependOnceListener(e,t){return this.once(e,t,Number.MAX_SAFE_INTEGER)}}var c,l,u,d;!function(e){e.USER_ERROR="USER_ERROR",e.SYSTEM_ERROR="SYSTEM_ERROR",e.NETWORK_ERROR="NETWORK_ERROR",e.PERMISSION_ERROR="PERMISSION_ERROR",e.CONFIG_ERROR="CONFIG_ERROR",e.VALIDATION_ERROR="VALIDATION_ERROR",e.TIMEOUT_ERROR="TIMEOUT_ERROR",e.UNSUPPORTED_ERROR="UNSUPPORTED_ERROR",e.INTERNAL_ERROR="INTERNAL_ERROR",e.EXTERNAL_ERROR="EXTERNAL_ERROR",e.UNKNOWN_ERROR="UNKNOWN_ERROR"}(c||(c={})),function(e){e.LOW="low",e.MEDIUM="medium",e.HIGH="high",e.CRITICAL="critical"}(l||(l={})),function(e){e.USER_ERROR="USER_ERROR",e.SYSTEM_ERROR="SYSTEM_ERROR",e.NETWORK_ERROR="NETWORK_ERROR",e.PERMISSION_ERROR="PERMISSION_ERROR",e.CONFIG_ERROR="CONFIG_ERROR",e.TIMEOUT_ERROR="TIMEOUT_ERROR",e.VALIDATION_ERROR="VALIDATION_ERROR",e.INTERNAL_ERROR="INTERNAL_ERROR",e.UNKNOWN_ERROR="UNKNOWN_ERROR"}(u||(u={})),function(e){e[e.DEBUG=0]="DEBUG",e[e.INFO=1]="INFO",e[e.WARN=2]="WARN",e[e.ERROR=3]="ERROR"}(d||(d={}));class Logger{constructor(e="Core",t){this.level=d.INFO,this.logs=[],this.maxLogs=1e3,this.enableConsole=!0,this.module=e,t&&(this.level=t.level??d.INFO,this.maxLogs=t.maxLogs??1e3,this.enableConsole=t.enableConsole??!0)}setLevel(e){this.level=e}getLevel(){return this.level}debug(e,t){this.log(d.DEBUG,e,t)}info(e,t){this.log(d.INFO,e,t)}warn(e,t){this.log(d.WARN,e,t)}error(e,t){this.log(d.ERROR,e,t)}log(e,t,r){if(e<this.level)return;const s={level:e,message:t,timestamp:Date.now(),module:this.module,data:r};this.logs.push(s),this.logs.length>this.maxLogs&&this.logs.shift(),this.enableConsole&&this.outputToConsole(s)}outputToConsole(e){new Date(e.timestamp).toISOString(),d[e.level],e.module,e.message,void 0!==e.data&&e.data;switch(e.level){case d.DEBUG:case d.INFO:case d.WARN:case d.ERROR:}}getLogs(){return[...this.logs]}getLogsByLevel(e){return this.logs.filter(t=>t.level===e)}getLogsByTimeRange(e,t){return this.logs.filter(r=>r.timestamp>=e&&r.timestamp<=t)}clear(){this.logs=[]}setMaxLogs(e){if(e<0)throw new Error("Max logs must be non-negative");this.maxLogs=e,this.logs.length>e&&(this.logs=this.logs.slice(-e))}setConsoleOutput(e){this.enableConsole=e}exportLogs(){return JSON.stringify(this.logs,null,2)}importLogs(e){try{const t=JSON.parse(e);Array.isArray(t)&&(this.logs=t.filter(e=>e&&"number"==typeof e.level&&"string"==typeof e.message&&"number"==typeof e.timestamp))}catch(e){this.error("Failed to import logs",e)}}createChild(e){return new Logger(`${this.module}.${e}`,{level:this.level,maxLogs:this.maxLogs,enableConsole:this.enableConsole})}}class R extends Error{constructor(e,t,r){super(t),this.name="CustomError",this.type=e,this.code=r?.code,this.context=r?.context,this.recoverable=r?.recoverable??!1,r?.cause&&(this.cause=r.cause),Error.captureStackTrace&&Error.captureStackTrace(this,R)}}class ErrorHandler{constructor(e){this.errorSolutions=new Map,this.logger=e||new Logger("ErrorHandler"),this.initializeErrorSolutions()}handleError(e,t){const r=this.classifyError(e),s={module:"Unknown",method:"Unknown",timestamp:Date.now(),userAgent:"undefined"!=typeof navigator?navigator.userAgent:"Node.js",...t},i={type:r,severity:this.getErrorSeverity(r),message:e.message,userMessage:this.getUserFriendlyMessage(e,r),originalError:e,context:s,code:this.getErrorCode(e)||this.generateErrorCode(r),recoverable:this.isRecoverableError(e),solutions:this.getErrorSolutions(e),id:this.generateErrorId(),processedAt:Date.now(),relatedErrors:[]};return this.logger.error(`[${r}] ${i.message}`,{error:e.message,stack:e.stack,context:s,recoverable:i.recoverable}),i}createError(e,t,r){const s={module:"Unknown",method:"Unknown",timestamp:Date.now(),userAgent:"undefined"!=typeof navigator?navigator.userAgent:"Node.js",...r?.context};return new R(e,t,{code:r?.code,context:s,recoverable:r?.recoverable,cause:r?.cause})}isRecoverableError(e){if(e instanceof R)return e.recoverable;switch(this.classifyError(e)){case c.NETWORK_ERROR:case c.TIMEOUT_ERROR:return!0;case c.PERMISSION_ERROR:case c.SYSTEM_ERROR:return!1;case c.USER_ERROR:case c.CONFIG_ERROR:return!0;default:return!1}}getErrorSolution(e){const t=this.getErrorCode(e);if(t&&this.errorSolutions.has(t))return this.errorSolutions.get(t);const r=this.classifyError(e);return this.getDefaultSolution(r)}getErrorSolutions(e){const t=this.getErrorSolution(e);return t?[{description:t,steps:[t],automatic:!1,priority:1}]:[]}getErrorSeverity(e){switch(e){case c.USER_ERROR:case c.CONFIG_ERROR:return l.LOW;case c.NETWORK_ERROR:case c.TIMEOUT_ERROR:return l.MEDIUM;case c.PERMISSION_ERROR:case c.VALIDATION_ERROR:return l.HIGH;case c.SYSTEM_ERROR:case c.INTERNAL_ERROR:return l.CRITICAL;default:return l.MEDIUM}}generateErrorCode(e){return`${e}_${Date.now().toString(36)}_${Math.random().toString(36).substr(2,5)}`.toUpperCase()}generateErrorId(){return`error_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}addErrorSolution(e,t){this.errorSolutions.set(e,t)}addErrorSolutions(e){for(const[t,r]of Object.entries(e))this.errorSolutions.set(t,r)}classifyError(e){if(e instanceof R)return e.type;const t=(e.message||"").toLowerCase(),r=(e.name||"").toLowerCase();return t.includes("network")||t.includes("fetch")||t.includes("xhr")||r.includes("networkerror")?c.NETWORK_ERROR:t.includes("timeout")||t.includes("timed out")||r.includes("timeouterror")?c.TIMEOUT_ERROR:t.includes("permission")||t.includes("denied")||t.includes("unauthorized")||t.includes("forbidden")||r.includes("notallowederror")?c.PERMISSION_ERROR:t.includes("not supported")||t.includes("not available")||t.includes("not implemented")||r.includes("notsupportederror")?c.SYSTEM_ERROR:t.includes("invalid")||t.includes("configuration")||t.includes("config")||r.includes("configerror")?c.CONFIG_ERROR:e instanceof TypeError||e instanceof RangeError||t.includes("invalid argument")||t.includes("invalid parameter")?c.USER_ERROR:c.UNKNOWN_ERROR}getUserFriendlyMessage(e,t){switch(t){case c.NETWORK_ERROR:return"网络连接失败,请检查网络连接后重试";case c.TIMEOUT_ERROR:return"操作超时,请稍后重试";case c.PERMISSION_ERROR:return"权限不足,请检查浏览器权限设置";case c.SYSTEM_ERROR:return"当前浏览器不支持此功能,请使用其他浏览器或升级浏览器版本";case c.CONFIG_ERROR:return"配置参数错误,请检查配置";case c.USER_ERROR:return"输入参数错误,请检查输入参数";default:return e.message||"发生未知错误"}}getErrorCode(e){if(e instanceof R)return e.code;const t=e;return t.code||t.errno||void 0}getDefaultSolution(e){switch(e){case c.NETWORK_ERROR:return"请检查网络连接,确保网络正常后重试";case c.TIMEOUT_ERROR:return"请稍后重试,或增加超时时间设置";case c.PERMISSION_ERROR:return"请在浏览器设置中允许相关权限,或使用HTTPS协议";case c.SYSTEM_ERROR:return"请使用支持此功能的现代浏览器,或升级浏览器版本";case c.CONFIG_ERROR:return"请检查配置参数是否正确,参考文档进行配置";case c.USER_ERROR:return"请检查输入参数的类型和格式是否正确";default:return null}}initializeErrorSolutions(){this.errorSolutions.set("ENOTFOUND","域名解析失败,请检查网络连接"),this.errorSolutions.set("ECONNREFUSED","连接被拒绝,请检查服务器状态"),this.errorSolutions.set("ETIMEDOUT","连接超时,请检查网络连接或稍后重试"),this.errorSolutions.set("CERT_UNTRUSTED","SSL证书不受信任,请检查证书配置"),this.errorSolutions.set("MIXED_CONTENT","混合内容错误,请使用HTTPS协议")}}class Cache{constructor(e){this.cache=new Map,this.config={maxSize:e?.maxSize??100,defaultTTL:e?.defaultTTL??3e5,enableLRU:e?.enableLRU??!0,cleanupInterval:e?.cleanupInterval??6e4},this.startCleanup()}set(e,t,r){const s=Date.now(),i={value:t,expireAt:s+(r??this.config.defaultTTL),createdAt:s,accessCount:0,lastAccessed:s};this.cache.size>=this.config.maxSize&&!this.cache.has(e)&&this.evictLRU(),this.cache.set(e,i)}get(e){const t=this.cache.get(e);if(!t)return;const r=Date.now();if(!(r>t.expireAt))return t.accessCount++,t.lastAccessed=r,t.value;this.cache.delete(e)}has(e){const t=this.cache.get(e);return!!t&&(!(Date.now()>t.expireAt)||(this.cache.delete(e),!1))}delete(e){return this.cache.delete(e)}clear(){this.cache.clear()}size(){return this.cache.size}keys(){return Array.from(this.cache.keys())}getInfo(e){const t=this.cache.get(e);if(t){if(!(Date.now()>t.expireAt))return{...t};this.cache.delete(e)}}touch(e,t){const r=this.cache.get(e);if(!r)return!1;const s=Date.now();if(s>r.expireAt)return this.cache.delete(e),!1;const i=t??this.config.defaultTTL;return r.expireAt=s+i,r.lastAccessed=s,!0}async getOrSet(e,t,r){const s=this.get(e);if(void 0!==s)return s;const i=await t();return this.set(e,i,r),i}mset(e,t){for(const[r,s]of e)this.set(r,s,t)}mget(e){return e.map(e=>this.get(e))}mdel(e){let t=0;for(const r of e)this.delete(r)&&t++;return t}getStats(){let e=0,t=0;const r=Date.now();for(const[s,i]of this.cache.entries())e+=i.accessCount,r>i.expireAt&&t++;return{size:this.cache.size,maxSize:this.config.maxSize,hitRate:e>0?(e-t)/e:0,totalAccess:e,expiredCount:t}}cleanup(){const e=Date.now();let t=0;for(const[r,s]of this.cache.entries())e>s.expireAt&&(this.cache.delete(r),t++);return t}evictLRU(){if(!this.config.enableLRU||0===this.cache.size)return;let e=null,t=1/0;for(const[r,s]of this.cache.entries())s.lastAccessed<t&&(t=s.lastAccessed,e=r);e&&this.cache.delete(e)}startCleanup(){this.cleanupTimer&&clearInterval(this.cleanupTimer),this.cleanupTimer=setInterval(()=>{this.cleanup()},this.config.cleanupInterval)}stopCleanup(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=void 0)}updateConfig(e){if(this.config={...this.config,...e},void 0!==e.cleanupInterval&&this.startCleanup(),void 0!==e.maxSize&&this.cache.size>e.maxSize)for(;this.cache.size>e.maxSize;)this.evictLRU()}destroy(){this.stopCleanup(),this.clear()}}class BaseManager{constructor(e,t="BaseManager"){this.initialized=!1,this.destroyed=!1,this.initializing=!1,this.options=this.mergeDefaultOptions(e),this.logger=new Logger(t,{level:this.options.debug?0:1,enableConsole:this.options.debug}),this.eventEmitter=new EventEmitter,this.errorHandler=new ErrorHandler(this.logger),this.options.cache&&(this.cache=new Cache),this.setupErrorHandling(),this.startAutoInitialization()}on(e,t,r){return this.eventEmitter.on(e,t,r),this}off(e,t){return this.eventEmitter.off(e,t),this}emit(e,...t){return this.eventEmitter.emit(e,...t)}once(e,t,r){return this.eventEmitter.once(e,t,r),this}listenerCount(e){return this.eventEmitter.listenerCount(e)}eventNames(){return this.eventEmitter.eventNames()}handleError(e,t){const r={module:this.constructor.name,method:t},s=this.errorHandler.handleError(e,r);return this.emit("error",s),s}validateInput(e,t){try{if(t.type){const r=typeof e;if(r!==t.type)throw this.errorHandler.createError("USER_ERROR",`Expected ${t.type}, got ${r}`,{context:{method:"validateInput"}})}if(t.required&&null==e)throw this.errorHandler.createError("USER_ERROR","Required parameter is missing",{context:{method:"validateInput"}});if(t.isArray&&!Array.isArray(e))throw this.errorHandler.createError("USER_ERROR","Expected array",{context:{method:"validateInput"}});if(t.properties&&"object"==typeof e&&null!==e)for(const[r,s]of Object.entries(t.properties))if(!this.validateInput(e[r],s))return!1;return!0}catch(e){return this.handleError(e,"validateInput"),!1}}async safeExecute(e,t,r){const s=r??this.options.retries??0;let i=null;for(let r=0;r<=s;r++)try{const s=new Promise((e,r)=>{setTimeout(()=>{r(this.errorHandler.createError("TIMEOUT_ERROR",`Operation timed out after ${this.options.timeout}ms`,{context:{method:t}}))},this.options.timeout)}),i=await Promise.race([e(),s]);return r>0&&this.logger.info(`Operation succeeded after ${r} retries`,{context:t}),i}catch(e){if(i=e,r===s||!this.errorHandler.isRecoverableError(i))throw this.handleError(i,t);const n=Math.min(1e3*Math.pow(2,r),5e3);this.logger.warn(`Operation failed, retrying in ${n}ms (attempt ${r+1}/${s+1})`,{context:t,error:i.message}),await new Promise(e=>setTimeout(e,n))}throw this.handleError(i,t)}getCached(e){return this.cache?.get(e)}setCached(e,t,r){this.cache?.set(e,t,r)}async getOrSetCached(e,t,r){return this.cache?this.cache.getOrSet(e,t,r):t()}async ensureInitialized(){if(this.destroyed)throw this.errorHandler.createError("SYSTEM_ERROR","Manager has been destroyed and cannot be used.",{context:{method:"ensureInitialized"}});if(!this.initialized)if(this.initPromise)try{await this.initPromise,this.initPromise=void 0}catch(e){throw this.errorHandler.createError("SYSTEM_ERROR",`Manager initialization failed: ${e.message}`,{context:{method:"ensureInitialized"}})}else if(!this.initializing){this.initializing=!0;try{await this.initialize()}finally{this.initializing=!1}}}ensureInitializedSync(){if(!this.initialized)throw this.errorHandler.createError("SYSTEM_ERROR","Manager not initialized. Operations requiring initialization should be awaited.",{context:{method:"ensureInitializedSync"}})}ensureNotDestroyed(){if(this.destroyed)throw this.errorHandler.createError("SYSTEM_ERROR","Manager has been destroyed and cannot be used.",{context:{method:"ensureNotDestroyed"}})}async ready(){await this.ensureInitialized()}getStatus(){return{initialized:this.initialized,destroyed:this.destroyed,eventListeners:this.eventNames().reduce((e,t)=>e+this.listenerCount(t),0),cacheSize:this.cache?.size(),initializing:this.initializing||!!this.initPromise}}updateOptions(e){this.options={...this.options,...e},void 0!==e.debug&&(this.logger.setLevel(e.debug?0:1),this.logger.setConsoleOutput(e.debug)),this.emit("optionsUpdated",this.options)}mergeDefaultOptions(e){return{...this.getDefaultOptions(),...e}}setupErrorHandling(){"undefined"!=typeof window?window.addEventListener("unhandledrejection",e=>{this.handleError(new Error(e.reason),"unhandledrejection")}):"undefined"!=typeof process&&process.on("unhandledRejection",e=>{this.handleError(new Error(String(e)),"unhandledRejection")})}startAutoInitialization(){this.initPromise=this.initialize().catch(e=>(this.logger.error("Auto-initialization failed:",e),Promise.reject(e))),this.initPromise.catch(()=>{})}baseDestroy(){this.destroyed||(this.emit("beforeDestroy"),this.eventEmitter.removeAllListeners(),this.cache?.destroy(),this.logger.clear(),this.destroyed=!0,this.initialized=!1,this.emit("destroyed"))}}class p extends BaseManager{constructor(e){const t="string"==typeof e?{url:e}:e;super(t,"UrlManager"),this._url=t?.url||("undefined"!=typeof window?window.location.href:"http://localhost");try{this._urlObj=new URL(this._url)}catch(e){this._urlObj=new URL("http://localhost"),this.handleError(e,"constructor")}this.initialize().catch(e=>{this.handleError(e,"auto-initialize")})}getDefaultOptions(){return{debug:!1,timeout:5e3,retries:1,cache:!0,url:"undefined"!=typeof window?window.location.href:"http://localhost",validateUrls:!0,allowedProtocols:["http:","https:"],maxUrlLength:2048}}async initialize(){if(!this.initialized)try{if(this.options.validateUrls&&!this.isValidUrl(this._url))throw this.errorHandler.createError(u.VALIDATION_ERROR,`Invalid initial URL: ${this._url}`,{context:{method:"initialize"}});this.initialized=!0,this.emit("initialized"),this.logger.info("UrlManager initialized successfully")}catch(e){throw this.handleError(e,"initialize")}}destroy(){this.baseDestroy(),this.logger.info("UrlManager destroyed")}getUrlInfo(){this.ensureInitializedSync(),this.ensureNotDestroyed();try{const e=`urlInfo:${this._url}`;return this.getCached(e)||(()=>{const t={url:this._urlObj.href,protocol:this._urlObj.protocol,hostname:this._urlObj.hostname,port:this._urlObj.port,origin:this._urlObj.origin,pathname:this._urlObj.pathname,search:this._urlObj.search,hash:this._urlObj.hash,host:this._urlObj.host};return this.setCached(e,t,6e4),t})()}catch(e){throw this.handleError(e,"getUrlInfo")}}getQuery(){this.ensureInitializedSync(),this.ensureNotDestroyed();try{const e=`query:${this._urlObj.search}`;return this.getCached(e)||(()=>{const t=a(this._urlObj.search);return this.setCached(e,t,3e4),t})()}catch(e){throw this.handleError(e,"getQuery")}}setQuery(e){if(this.ensureInitializedSync(),this.ensureNotDestroyed(),!this.validateInput(e,{type:"object",required:!0}))throw this.errorHandler.createError(u.VALIDATION_ERROR,"Invalid query parameters",{context:{method:"setQuery",input:e}});try{const t=h(e,!1);return this._urlObj.search=t,this._updateUrl(),this.emit("queryChanged",e),this}catch(e){throw this.handleError(e,"setQuery")}}addQuery(e){if(this.ensureInitializedSync(),this.ensureNotDestroyed(),!this.validateInput(e,{type:"object",required:!0}))throw this.errorHandler.createError(u.VALIDATION_ERROR,"Invalid query parameters",{context:{method:"addQuery",input:e}});try{return this._url=r(this._url,e),this._urlObj=new URL(this._url),this._validateUrl(),this.emit("queryAdded",e),this}catch(e){throw this.handleError(e,"addQuery")}}removeQuery(e){if(this.ensureInitializedSync(),this.ensureNotDestroyed(),!e)throw this.errorHandler.createError(u.VALIDATION_ERROR,"Keys parameter is required",{context:{method:"removeQuery"}});try{return this._url=s(this._url,e),this._urlObj=new URL(this._url),this.emit("queryRemoved",e),this}catch(e){throw this.handleError(e,"removeQuery")}}setHash(e){if(this.ensureInitializedSync(),this.ensureNotDestroyed(),!this.validateInput(e,{type:"string",required:!0}))throw this.errorHandler.createError(u.VALIDATION_ERROR,"Hash must be a string",{context:{method:"setHash",input:e}});try{return this._urlObj.hash=e.startsWith("#")?e:`#${e}`,this._updateUrl(),this.emit("hashChanged",e),this}catch(e){throw this.handleError(e,"setHash")}}setPathname(e){if(this.ensureInitializedSync(),this.ensureNotDestroyed(),!this.validateInput(e,{type:"string",required:!0}))throw this.errorHandler.createError(u.VALIDATION_ERROR,"Pathname must be a string",{context:{method:"setPathname",input:e}});try{return this._urlObj.pathname=e,this._updateUrl(),this.emit("pathnameChanged",e),this}catch(e){throw this.handleError(e,"setPathname")}}toString(){return this.ensureNotDestroyed(),this._url}reset(e){if(this.ensureInitializedSync(),this.ensureNotDestroyed(),!this.validateInput(e,{type:"string",required:!0}))throw this.errorHandler.createError(u.VALIDATION_ERROR,"URL must be a string",{context:{method:"reset",input:e}});try{if(this.options.validateUrls&&!this.isValidUrl(e))throw this.errorHandler.createError(u.VALIDATION_ERROR,`Invalid URL: ${e}`,{context:{method:"reset",input:e}});return this._url=e,this._urlObj=new URL(e),this._validateUrl(),this.emit("urlReset",e),this}catch(e){throw this.handleError(e,"reset")}}isValidUrl(t){try{return e(t,{protocols:this.options.allowedProtocols,requireProtocol:!0,allowLocalhost:!0,allowIp:!0})}catch(e){return this.handleError(e,"isValidUrl"),!1}}_updateUrl(){this._url=this._urlObj.href,this._validateUrl()}_validateUrl(){if(this.options.validateUrls){if(this._url.length>this.options.maxUrlLength)throw this.errorHandler.createError(u.VALIDATION_ERROR,`URL length exceeds maximum allowed length of ${this.options.maxUrlLength}`,{context:{method:"_validateUrl"}});if(!this.options.allowedProtocols.includes(this._urlObj.protocol))throw this.errorHandler.createError(u.VALIDATION_ERROR,`Protocol ${this._urlObj.protocol} is not allowed`,{context:{method:"_validateUrl"}})}}}exports.QueryParser=class{constructor(){this.cache=new Map,this.maxCacheSize=100}parse(e){if(!e)return{};if(this.cache.has(e))return this.cache.get(e);const t=a(e);if(this.cache.size>=this.maxCacheSize){const e=this.cache.keys().next().value;void 0!==e&&this.cache.delete(e)}return this.cache.set(e,t),t}clearCache(){this.cache.clear()}getCacheSize(){return this.cache.size}},exports.UrlBuilder=class{constructor(){this._protocol="https:",this._hostname="",this._port="",this._pathname="",this._search=new URLSearchParams,this._hash=""}protocol(e){return this._protocol=e.endsWith(":")?e:`${e}:`,this}hostname(e){return this._hostname=e,this}port(e){return this._port=String(e),this}pathname(e){return this._pathname=e.startsWith("/")?e:`/${e}`,this}query(e,t){return Array.isArray(t)?(this._search.delete(e),t.forEach(t=>this._search.append(e,t))):this._search.set(e,t),this}queries(e){return Object.entries(e).forEach(([e,t])=>{this.query(e,t)}),this}hash(e){return this._hash=e.startsWith("#")?e:`#${e}`,this}build(){if(!this._hostname)throw new Error("Hostname is required");let e=`${this._protocol}//${this._hostname}`;this._port&&(e+=`:${this._port}`),this._pathname&&(e+=this._pathname);const t=this._search.toString();return t&&(e+=`?${t}`),this._hash&&(e+=this._hash),e}reset(){return this._protocol="https:",this._hostname="",this._port="",this._pathname="",this._search=new URLSearchParams,this._hash="",this}},exports.UrlManager=p,exports.addQuery=r,exports.buildUrl=function(e){const{base:r="",pathname:s="",query:i,hash:n}=e;let o=r;if(s&&(o=o.endsWith("/")?o+s.replace(/^\//,""):o+"/"+s.replace(/^\//,"")),i){const e=h(i);e&&(o+=e)}return n&&(o+=n.startsWith("#")?n:`#${n}`),t(o)},exports.createUrlManager=function(e){return new p(e)},exports.decodeUrl=o,exports.default=p,exports.encodeUrl=n,exports.getFileExtensionFromUrl=function(e){if(!e)return"";try{const t=new URL(e).pathname,r=t.lastIndexOf(".");if(r>t.lastIndexOf("/")&&-1!==r)return t.slice(r+1).toLowerCase()}catch{const t=e.lastIndexOf(".");if(t>e.lastIndexOf("/")&&-1!==t)return e.slice(t+1).toLowerCase()}return""},exports.getFileNameFromUrl=function(e,t=!0){if(!e)return"";try{const r=new URL(e),s=r.pathname.split("/").pop()||"";if(!t){const e=s.lastIndexOf(".");return-1!==e?s.slice(0,e):s}return s}catch{const r=e.split("/").pop()||"";if(!t){const e=r.lastIndexOf(".");return-1!==e?r.slice(0,e):r}return r}},exports.getHash=function(){return"undefined"==typeof window?"":window.location.hash.slice(1)},exports.getQuery=function(){return"undefined"==typeof window?{}:a(window.location.search)},exports.getUrl=function(e){return new p(e).getUrlInfo()},exports.isAbsoluteUrl=function(e){return!i(e)},exports.isRelativeUrl=i,exports.isSameOrigin=function(e,t){try{const r=new URL(e),s=new URL(t);return r.origin===s.origin}catch{return!1}},exports.isSecureUrl=function(e){if(!e||"string"!=typeof e)return!1;try{const t=new URL(e);if(["javascript:","data:","vbscript:","file:","ftp:"].includes(t.protocol))return!1;t.hostname.toLowerCase();return!0}catch{return!1}},exports.isValidUrl=e,exports.joinPath=function(e,...t){if(!e)return t.join("/");let r=e.replace(/\/+$/,"");for(const e of t){if(!e)continue;const t=e.replace(/^\/+/,"").replace(/\/+$/,"");t&&(r+=`/${t}`)}return r},exports.normalizeUrl=t,exports.objToUrl=function(e,t="?"){if(!e||"object"!=typeof e||0===Object.keys(e).length)return"";const r=[];try{for(const t in e)if(Object.prototype.hasOwnProperty.call(e,t)&&"HASH"!==t){const s=e[t];if(null!=s){const e=n(String(t),!0),i=n(String(s),!0);r.push(`${e}=${i}`)}}}catch(e){return""}return`${r.length>0?`${t}${r.join("&")}`:""}${e.HASH?`#${n(String(e.HASH),!0)}`:""}`},exports.parseQuery=a,exports.removeQuery=s,exports.sanitizeUrl=function(e){if(!e||"string"!=typeof e)return"";let t=e.replace(/[\x00-\x1F\x7F-\x9F]/g,"");t=t.trim();try{return new URL(t).href}catch{return""}},exports.stringifyQuery=h,exports.urlToObj=function(e){const t={};if(!e||"string"!=typeof e)return t;try{const r=e.match(/[?&]([^=&#]+)=([^&#]*)/g);r&&r.forEach(e=>{const[,r,s]=e.match(/[?&]([^=&#]+)=([^&#]*)/)||[];if(r)try{t[o(r,!0)]=o(s||"",!0)}catch{t[r]=s||""}});const s=e.match(/#([^?]*)/);if(s&&s[1])try{t.HASH=o(s[1],!0)}catch{t.HASH=s[1]}}catch(e){}return t};