gramstax 0.8.7 → 0.8.9

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.
@@ -4,4 +4,4 @@
4
4
  `):l.map(m=>d(m.innerContent)).join(`
5
5
  `)}return a}static _processImportBlocks(e){let t=/([ \t]*)<import(?:\s+([^>]*))?\/?>/gi,n=[];return{processed:e.replace(t,(i,o,a)=>{let r={},c=/(\w+)="([^"]*)"/g;if(a)for(let m of a.matchAll(c))r[m[1]]=m[2];let l=r.src;if(!l)return"";let d;r.block&&(r.block==="all"?d="all":r.block.includes(",")?d=r.block.split(",").map(m=>m.trim()).filter(m=>m):d=r.block);let h={src:l,blocks:d,base:r.base||"default",lang:r.lang,section:r.section||"all",indent:o||""};return n.push(h),`${o}__IMPORT_${n.length-1}__`}),imports:n}}static processImportBlocks(e,t,n=0,s){if(n>10)return"";let{processed:i,imports:o}=this._processImportBlocks(e),a=i;for(let r=0;r<o.length;r++){let c=o[r],l=`${c.src}|${c.base}|${c.lang||""}|${c.section}|${Array.isArray(c.blocks)?c.blocks.join(","):c.blocks||""}`,d;if(s&&s.has(l))d=s.get(l);else{let m=t(c.src);d=m?this._extractBlock(m,c.blocks,c.base,c.section,c.lang):"",d&&d.includes("<import")&&(d=this.processImportBlocks(d,t,n+1,s)),s&&s.set(l,d)}let h=d.split(`
6
6
  `).map((m,g)=>g===0?m:c.indent+m).join(`
7
- `);a=a.replace(`__IMPORT_${r}__`,h)}return a}};var $=class{static{p(this,"TemplateManager")}_map=new Map;_engine=M;_watcher=[];_pageManager=x;_supportedExtensions=new Set([".html",".ts",".js"]);_path;_isWatchEnabled;constructor(e){let{path:t,enableWatch:n=!1}=e;this._path=t,this._isWatchEnabled=n,this._validatePath(),this._initializeWatcher(e.watchOptions),this._loadAllFiles()}_validatePath(){try{if(!this._path||!Array.isArray(this._path))throw new Error("Path must be set as string array");for(let e=0;e<this._path.length;e++){let t=this._path[e];if(!(0,C.existsSync)(t))throw new Error(`Template base path is not exists: ${t}`);if(!(0,C.statSync)(t).isDirectory())throw new Error(`Template base path is not a directory: ${t}`)}return!0}catch(e){throw new Error(`Failed to validate Template base path: ${String(e)}`)}}_initializeWatcher(e){if(this._isWatchEnabled){if(this._watcher.length>0)throw new Error("Watcher already enabled");for(let t=0;t<this._path.length;t++){let n=this._path[t],s=(0,de.watch)(n,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},...e});this._watcher[t]=s,s.on("change",this._handleFileChange.bind(this)),s.on("add",this._handleFileAdd.bind(this)),s.on("unlink",this._handleFileDelete.bind(this)),s.on("error",this._handleWatchError.bind(this))}}}_handleFileChange(e){let t=(0,w.basename)(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileAdd(e){let t=(0,w.basename)(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileDelete(e){let t=(0,w.basename)(e),n=this._getKey(t);this._map.has(n)&&this._map.delete(n)}_handleWatchError(e){}_loadAllFiles(){let e=new Map,t=[];for(let s=0;s<this._path.length;s++){let i=this._path[s],a=(0,C.readdirSync)(i,"utf8").filter(r=>this._isValidFile(r));for(let r of a){let c=(0,w.join)(i,r),l=this._getExtension(r),d=this._getKey(r);if(l===".html")e.set(d,(0,C.readFileSync)(c,"utf8"));else if(l===".ts"||l===".js"){let h=x.getFileSync(c);h?.template!==void 0&&(e.set(d,h.template),t.push(h))}}}let n=new Map;for(let[s,i]of e.entries())this._compile(s,i,void 0,n,e);e.clear(),n.clear();for(let s of t)s.template=void 0}_loadFile(e){for(let t=0;t<this._path.length;t++){let n=this._path[t],s=(0,w.join)(n,e),i=this._getExtension(e),o=this._getKey(e);if(i==".html"){let a=(0,C.readFileSync)(s,"utf8");this._compile(o,a)}else if(i==".ts"||i==".js"){let a=x.getFileSync(s);a?.template!==void 0&&(this._compile(o,a.template),a.template=void 0)}else throw new Error(`File ${e} is not support`)}}_getExtension(e){return(0,w.extname)(e).toLowerCase()}_readTemplateFile(e){for(let t of this._path){let n=(0,w.extname)(e).toLowerCase();if(n){let a=(0,w.join)(t,e);if((0,C.existsSync)(a)&&(0,C.statSync)(a).isFile()){if(n===".html")return(0,C.readFileSync)(a,"utf8");if(n===".ts"||n===".js")try{return x.getFileSync(a)?.template??null}catch{return null}}continue}let s=(0,w.join)(t,`${e}.ts`),i=(0,w.join)(t,`${e}.js`);if((0,C.existsSync)(s)&&(0,C.statSync)(s).isFile())try{return x.getFileSync(s)?.template??null}catch{}else if((0,C.existsSync)(i)&&(0,C.statSync)(i).isFile())try{return x.getFileSync(s)?.template??null}catch{}let o=(0,w.join)(t,`${e}.html`);if((0,C.existsSync)(o)&&(0,C.statSync)(o).isFile())return(0,C.readFileSync)(o,"utf8")}return null}_isValidFile(e){return this._supportedExtensions.has(this._getExtension(e))}_getKey(e){return e.replace(/\.[^/.]+$/,"")}_compile(e,t,n,s,i){let o=this._map.get(e),a=o||{},r=!1,c=M.processImportBlocks(t,d=>i&&i.has(d)?i.get(d):this._readTemplateFile(d),0,s),l=M._processBaseBlocks(c);(n===void 0||n?.media===!1||o?.media===void 0)&&(a.media=M.compileBlockMedia(c,l),r=!0),(n===void 0||n?.message===!1||o?.message===void 0)&&(a.message=M.compileBlockMessage(c,l),r=!0),(n===void 0||n?.keyboard===!1||o?.keyboard===void 0)&&(a.keyboard=M.compileBlockKeyboards(c,l),r=!0),(n===void 0||n?.description===!1||o?.description===void 0)&&(a.description=M.compileBlockDescription(c,l),r=!0),r&&this._map.set(e,a)}getMedia(e,t="default",n="default",s){let o=this._map.get(e)?.media?.[t],a=o?.[n]||o?.default;try{if(!a)throw new Error("Media function not found, please check your template");return a(s)}catch{return{}}}getMessage(e,t="default",n="default",s){try{let o=this._map.get(e)?.message?.[t],a=o?.[n]||o?.default;if(!a)throw"";return a(s)}catch{return""}}getDescription(e,t="default",n="default",s="default",i){try{let a=this._map.get(e)?.description?.[t]?.[s],r=a?.[n]||a?.default;if(!r)throw"";return r(i)}catch{return""}}getDescriptionLanguage(e,t="default",n="default"){try{let i=this._map.get(e)?.description?.[t]?.[n];return i?Object.keys(i):[]}catch{return[]}}getDescriptionScopes(e,t="default"){try{let s=this._map.get(e)?.description?.[t];return s?Object.keys(s):[]}catch{return[]}}getKeyboard(e,t="default",n="default",s="inline",i){try{let a=this._map.get(e)?.keyboard?.[t],r=a?.[n]?.[s]||a?.default?.[s];if(!r)throw[];return r(i)}catch{return[]}}async write(e,t){if(this._getExtension(e)!=".html")return null;for(let n=0;n<this._path.length;n++){let s=(0,w.join)(this._path[n],e);if((0,C.existsSync)(s))return(0,C.writeFileSync)(s,t,"utf8"),this._loadFile(e),!0}return null}has(e){return this._map.has(e)}async destroy(){if(this._watcher)for(let e of this._watcher)await e.close();this._map.clear()}};var L=require("grammy");var E=class{constructor(e){this.maxSize=e;if(!Number.isFinite(e)||e<=0)throw new Error("WebhookQueue maxSize must be a positive number")}static{p(this,"WebhookQueue")}queue=[];waitEnqueue=[];waitDequeue=[];getStats(){return{length:this.queue.length,maxSize:this.maxSize,waitingEnqueue:this.waitEnqueue.length,waitingDequeue:this.waitDequeue.length}}get length(){return this.queue.length}async enqueue(e){if(this.queue.length>=this.maxSize&&await new Promise(t=>this.waitEnqueue.push(t)),this.waitDequeue.length>0){this.waitDequeue.shift()(e);return}this.queue.push(e)}async dequeue(){if(this.queue.length>0){let e=this.queue.shift();return this.waitEnqueue.shift()?.(),e}return await new Promise(e=>this.waitDequeue.push(e))}};var Ie=(0,v.dirname)((()=>{try{return __filename}catch{return(0,me.fileURLToPath)(f)}})()),xe=JSON.parse((0,le.readFileSync)((0,v.join)(Ie,"../../package.json"),"utf-8")).version,J=class{static{p(this,"Gramstax")}templateManager;cacheKeyboard;cacheSession;pages;optionsPage={shortCallbackData:!1};log;bot;botConfig;webhookQueue;webhookQueueInstance;webhookServer;handlerBotUpdate;constructor(e){if(!e?.token||e?.token?.length==0)throw new Error("Token is not valid or empty");if(typeof e.optionsPage?.shortCallbackData=="boolean"&&(this.optionsPage.shortCallbackData=e.optionsPage.shortCallbackData),this.log=e.log===!0?U:e.log?e.log:void 0,this.log?.info?.(`Gramstax v${xe}`),this.cacheSession=e.cacheSession||new W("memory"),this.cacheKeyboard=e.cacheKeyboard||new Map,this.botConfig=e.botConfig,this.webhookQueue=e.webhookQueue,this.templateManager=e.templateManager||new $({path:[(0,v.join)(process.cwd(),"src","pages")]}),this.bot=this.createBot(e.token),this.bot.catch(this._onCatch),this._registerOnCallbackQueryData(),this._registerOnMessageText(),this._registerOnMessagePhoto(),this._registerOnMessageVideo(),this._registerOnMessageAudio(),this._registerOnMessageDocument(),this._registerOnMessageAnimation(),this._registerOnMessageVoice(),this._registerOnMessageVideoNote(),this._registerOnMessageSticker(),this._registerOnMessageLocation(),this._registerOnMessageContact(),this.handlerBotUpdate=this.bot.handleUpdate,this.pages=this._pageLoads(),process.once("SIGINT",()=>this.bot.stop()),process.once("SIGTERM",()=>this.bot.stop()),this.hookBeforeStart(),e.deploy.startsWith("polling"))this._runPolling();else if(e.deploy.startsWith("webhook:"))this._runWebhook(e.deploy.split("webhook:")[1]);else if(e.deploy.startsWith("serverless:"))this._runServerless(e.deploy.split("serverless:")[1]);else if(!e.deploy.startsWith("test"))throw new Error("Params deploy is not valid, expected: polling, webhook:<public-url>, serverless:<your-adapter>")}_onCatch(e){if(this.log?.errorMake)this.log?.errorMake(e,"Bot","catch");else{let t=JSON.stringify(e,null,2);this.log?.error?.(`[Bot.catch]: ${t}`)}}hookBeforeStart(){}hookAfterStart(){}async _onStart(e,t,n){await this.executeSyncBlocksDescription(this.pages);let{username:s}=e;this.log?.success?.(`Telegram bot polling started: ${s} ${t=="webhook"||t=="serverless"?`(${n})`:""}`),this.hookAfterStart()}createBot(e){return new L.Bot(e,this.botConfig)}createCtx(e){return new K({ct:e,cacheSession:this.cacheSession,cacheKeyboard:this.cacheKeyboard,templateManager:this.templateManager,temp:{isAnswer:!1,session:{},data:{}}})}_runPolling(){this.bot.start({drop_pending_updates:!0,onStart:p(e=>{this._onStart(e,"polling",null)},"onStart")})}async _runWebhook(e){let{serve:t}=await import("bun"),n=(0,L.webhookCallback)(this.bot,"bun"),s=this.webhookQueue,i=s?.enabled===!0;this.handlerBotUpdate=i?this.bot.handleUpdate.bind(this.bot):n;let o=i?new E(s?.maxQueueSize??5e3):void 0,a=s?.workerCount??8,r=s?.perChatConcurrency??1,c=s?.blockWhenFull!==!1,l=new Map,d=new Map;this.webhookQueueInstance=o;let h=p(y=>y?.message?.chat?.id??y?.edited_message?.chat?.id??y?.channel_post?.chat?.id??y?.edited_channel_post?.chat?.id??y?.callback_query?.message?.chat?.id??y?.callback_query?.from?.id??y?.inline_query?.from?.id??y?.chosen_inline_result?.from?.id,"getChatId"),m=p(async y=>{if(!i||r<=0||y===void 0||y===null)return()=>{};let S=String(y),b=l.get(S)||0;if(b<r)return l.set(S,b+1),()=>this._releaseWebhookChat(S,l,d);await new Promise(ge=>{let ne=d.get(S)||[];ne.push(ge),d.set(S,ne)});let R=(l.get(S)||0)+1;return l.set(S,R),()=>this._releaseWebhookChat(S,l,d)},"acquireChat");if(i&&o){await this.bot.init();for(let y=0;y<a;y++)this._startWebhookWorker(o,m,h)}let g=new URL(e).pathname,_=this.log,T="/stats_queue";this.webhookServer?.stop();let I=t({async fetch(y){let{pathname:S}=new URL(y.url);if(y.method=="POST"&&S==g){if(!i||!o)return n(y);if(!c&&o.length>=(s?.maxQueueSize??5e3))return new Response("Queue full",{status:429});try{let b=await y.json();return await o.enqueue(b),new Response("OK",{status:200})}catch(b){return _?.error?.(`Webhook queue error: ${String(b)}`),new Response("Bad Request",{status:400})}}if(y.method=="GET"&&S==T){let b=o?.getStats()||{length:0,maxSize:s?.maxQueueSize??5e3,waitingEnqueue:0,waitingDequeue:0};return new Response(JSON.stringify({enabled:i,path:T,timestamp:new Date().toISOString(),maxQueueSize:s?.maxQueueSize??5e3,workerCount:a,perChatConcurrency:r,blockWhenFull:c,queue:b,activeChats:l.size}),{status:200,headers:{"Content-Type":"application/json"}})}if(y.method=="GET"&&S=="/"){let b=new Date().toISOString();return new Response(JSON.stringify({status:"OK",timestamp:b}),{status:200,headers:{"Content-Type":"application/json"}})}return new Response("Not found",{status:404})}});this.webhookServer=I;let k=p(()=>{this.webhookServer?.stop(),this.webhookServer=void 0},"stopServer");process.once("SIGINT",k),process.once("SIGTERM",k),(await this.bot.api.getWebhookInfo()).url!=e&&await this.bot.api.setWebhook(e);let D=await this.bot.api.getMe();await this._onStart(D,"webhook",e)}_startWebhookWorker(e,t,n){p(async()=>{for(;;){let i=await e.dequeue(),o=await t(n(i));try{await this.bot.handleUpdate(i)}catch(a){this.log?.error?.(`Webhook worker error: ${String(a)}`)}finally{o()}}},"run")()}_releaseWebhookChat(e,t,n){let s=t.get(e)||0,i=Math.max(0,s-1);i===0?t.delete(e):t.set(e,i);let o=n.get(e);o&&o.length>0&&(o.shift()(),o.length===0&&n.delete(e))}getWebhookQueueStats(){if(!this.webhookQueue?.enabled||!this.webhookQueueInstance)return null;let e=this.webhookQueueInstance.getStats(),t=this.webhookQueue.maxQueueSize??5e3,n=this.webhookQueue.workerCount??8,s=this.webhookQueue.perChatConcurrency??1,i=this.webhookQueue.blockWhenFull!==!1;return{enabled:!0,maxQueueSize:t,workerCount:n,perChatConcurrency:s,blockWhenFull:i,...e}}async _runServerless(e){this.handlerBotUpdate=(0,L.webhookCallback)(this.bot,e);let t=await this.bot.api.getMe();await this._onStart(t,"serverless",e)}_pageBuildData(e,t){e?.data===void 0&&(e.data=e.buildData());let{name:n}=(0,v.parse)(t);e.data.name||(e.data.name=n),e.data.intentText||(e.data.intentText=e.data.name),e.data.intentCommandText||(e.data.intentCommandText=e.data.name),e.data.intentCallbackData||(e.data.intentCallbackData=e.data.name)}_pageSorts(e,t,n){let s=e.data.name,i=e.prototype,o="handle",a="Args",r="Command",c="Caption",l="Free",d=t.routeDynamic,h=t.routeDynamicSpesific;t.all[s]=e;for(let m=0;m<t.lenListRouteStaticSession;m++){let g=t.listRouteStaticSession[m];if(typeof i[g]!="function")continue;let _=t.routeStatic[g],T=t.routeStaticIntent[g],I=t.routeStaticSession[g],k={name:s,routeName:g},A=_||T;if(A!==void 0){let D=g.includes(r),y=g.endsWith("CallbackData"),S=g.endsWith("Text"),b;if(D){let R=e.data.intentCommandText;b=R?`/${R}`:void 0}else if(y){let R=e.data.intentCallbackData;this.optionsPage.shortCallbackData===!0&&(R=String(n),e.data.intentCallbackData=R),b=R}else S?b=e.data.intentText:b=e.data.name;b&&(A[b]=k)}if(I!==void 0){let y=`methodSession${g.replace("handle","")}`,S=i[y]?.(s);I[S]=k}if(g.startsWith("handleFree")){let D=g.replace(o,"").replace(a,"").replace(r,"").replace(c,"").replace(l,"").toLowerCase();h[D].push(k)}}i.handleFree&&d.push(s)}async executeSyncBlocksDescription(e){let t=new Map,n=e.routeStatic.handleCommandText;for(let[,s]of Object.entries(n)){let i=s.name,o=this.templateManager.getDescriptionScopes(i);for(let a of o){t.has(a)||t.set(a,new Set);let r=this.templateManager.getDescriptionLanguage(i,"default",a);for(let c of r)t.get(a).add(c)}}for(let[s,i]of t)for(let o of i){let a=[];for(let[,l]of Object.entries(n)){let d=l.name,h=this.templateManager.getDescription(d,"default",o,s);h&&a.push({command:d,description:h})}if(a.length===0)continue;let r={type:s},c=o==="default"?void 0:o;try{let l=await this.bot.api.getMyCommands({scope:r,language_code:c}),d=JSON.stringify(l.map(m=>({command:m.command,description:m.description})).sort((m,g)=>m.command.localeCompare(g.command))),h=JSON.stringify(a.sort((m,g)=>m.command.localeCompare(g.command)));d!==h&&(await this.bot.api.setMyCommands(a,{scope:r,language_code:c}),this.log?.info?.(`Synced descriptions for scope: ${s},${c?` lang: ${c},`:""} total (${a.length})`))}catch(l){this.log?.error?.(`Failed to sync descriptions for scope: ${s},${c?` lang: ${c},`:""} error: ${String(l)}`)}}}_pageLoads(){this.log?.info?.("Load pages..");let e=["handleCallbackData","handleText","handleCommandText","handleCaptionPhoto","handleCommandCaptionPhoto","handleCaptionVideo","handleCommandCaptionVideo","handleCaptionAudio","handleCommandCaptionAudio","handleCaptionDocument","handleCommandCaptionDocument","handleCaptionAnimation","handleCommandCaptionAnimation","handleCaptionVoice","handleCommandCaptionVoice"],t=["handleArgsCallbackData","handleArgsText","handleCommandArgsText","handleCaptionArgsPhoto","handleCommandCaptionArgsPhoto","handleCaptionArgsVideo","handleCommandCaptionArgsVideo","handleCaptionArgsAudio","handleCommandCaptionArgsAudio","handleCaptionArgsDocument","handleCommandCaptionArgsDocument","handleCaptionArgsAnimation","handleCommandCaptionArgsAnimation","handleCaptionArgsVoice","handleCommandCaptionArgsAnimation"],n=[...e,...t,"handleFreeText","handleFreePhoto","handleFreeVideo","handleFreeAudio","handleFreeDocument","handleFreeAnimation","handleFreeVoice","handleFreeVideoNote","handleFreeSticker","handleFreeLocation","handleFreeContact"],s=p((a,r)=>Object.fromEntries(a.map(c=>[c,r()])),"makeObject"),i=p(()=>[],"initDynamicSpesific"),o={all:{},routeDynamic:[],routeDynamicSpesific:{text:i(),photo:i(),video:i(),audio:i(),document:i(),animation:i(),voice:i(),videoNote:i(),sticker:i(),location:i(),contact:i()},routeStatic:s(e,()=>({})),routeStaticIntent:s(t,()=>({})),routeStaticSession:s(n,()=>({})),listRouteStatic:e,listRouteStaticIntent:t,listRouteStaticSession:n,lenListRouteStatic:e.length,lenListRouteStaticIntent:t.length,lenListRouteStaticSession:n.length};return x.getFileManySync(void 0).forEach(({path:a,page:r},c)=>{this._pageBuildData(r,a),this._pageSorts(r,o,c),r.template=void 0}),this.log?.info?.(`Finish load pages with total (${Object.keys(o.all).length})`),o}async _pageRoutes(e,t){let n,s;if(n===void 0){let o=await e.getSession();if(o){let a=o.method,r=this.pages.routeStaticSession,c=e.callbackData,l=e.msgText,d=e.msgCaption,h=c||l||d,m=t==="callbackdata",g=m?"colon":"space",_=h&&e.haveArgs(h,g)?e.getIntent(h,g,1):void 0,T=!m&&h?e.getIntent(h,"space",2):void 0;for(let I=0;I<this.pages.lenListRouteStaticSession;I++){let k=this.pages.listRouteStaticSession[I];if(k.toLowerCase().endsWith(t)){if(h){if(this.pages.routeStatic[k]?.[h])continue;let A=this.pages.routeStaticIntent[k];if(A&&(_&&A[_]||T&&A[T]))continue}s=r[k][a]}if(s)break}s!==void 0&&(n=this.pages.all[s.name])}}if(n===void 0){let o=e.callbackData,a=e.msgText,r=e.msgCaption,c=this.pages.routeStatic;for(let l=0;l<this.pages.lenListRouteStatic;l++){let d=this.pages.listRouteStatic[l];if(d.toLowerCase().endsWith(t)&&(s=c[d][o||a||r]),s)break}s!==void 0&&(n=this.pages.all[s.name])}if(n===void 0){let o=this.pages.routeStaticIntent,a=t==="callbackdata",r=a?"colon":"space",c=a?e.callbackData:e.msgText||e.msgCaption,l=e.haveArgs(c,r);if(c&&l)for(let d=0;d<this.pages.lenListRouteStaticIntent;d++){let h=this.pages.listRouteStaticIntent[d];if(!h.toLowerCase().endsWith(t))continue;let m=o[h];if(s=m[e.getIntent(c,r,1)],!s&&!a&&(s=m[e.getIntent(c,"space",2)]),s)break}s!==void 0&&(n=this.pages.all[s.name])}if(n!==void 0&&s!==void 0){if(!n.prototype[s.routeName])return;let a=await new n(e)[s.routeName]?.();return e.temp.isAnswer===!0?a:null}let i=this.pages.routeDynamicSpesific[t]||[];for(let o=0;o<i.length;o++){let a=i[o];if(a===void 0)continue;let r=this.pages.all[a.name];r!==void 0&&typeof r.prototype[a.routeName]=="function"&&await new r(e)[a.routeName]()}for(let o=0;o<this.pages.routeDynamic.length;o++){let a=this.pages.routeDynamic[o];if(a===void 0)continue;let r=this.pages.all[a];r!==void 0&&typeof r.prototype.handleFree=="function"&&await new r(e).handleFree()}if(e.temp.isAnswer===!1)return null}async hookBeforeRoute(e,t){return!!(e||t)}async hookErrorPage(e,t,n,s){}async hookErrorInputNotFoundPage(e){}async _onMessage(e,t){let n=this.createCtx(e);try{if(await this.hookBeforeRoute(n,t)===!1)return;await this._pageRoutes(n,t)===null&&await this.hookErrorInputNotFoundPage(n)}catch(s){await this.hookErrorPage(n,t,s,!1)}}async _onCallbackQueryData(e){let t=this.createCtx(e);try{if(await this.hookBeforeRoute(t,"onCallbackQueryData")===!1)return;await this._pageRoutes(t,"callbackdata")}catch(n){await this.hookErrorPage(t,"onCallbackQueryData",n,!0)}}async _onMessageText(e){await this._onMessage(e,"text")}async _onMessagePhoto(e){await this._onMessage(e,"photo")}async _onMessageVideo(e){await this._onMessage(e,"video")}async _onMessageAudio(e){await this._onMessage(e,"audio")}async _onMessageDocument(e){await this._onMessage(e,"document")}async _onMessageAnimation(e){await this._onMessage(e,"animation")}async _onMessageVoice(e){await this._onMessage(e,"voice")}async _onMessageVideoNote(e){await this._onMessage(e,"videoNote")}async _onMessageSticker(e){await this._onMessage(e,"sticker")}async _onMessageLocation(e){await this._onMessage(e,"location")}async _onMessageContact(e){await this._onMessage(e,"contact")}_registerOnCallbackQueryData(){this.bot.on("callback_query:data",this._onCallbackQueryData.bind(this))}_registerOnMessageText(){this.bot.on("message:text",this._onMessageText.bind(this))}_registerOnMessagePhoto(){this.bot.on("message:photo",this._onMessagePhoto.bind(this))}_registerOnMessageVideo(){this.bot.on("message:video",this._onMessageVideo.bind(this))}_registerOnMessageAudio(){this.bot.on("message:audio",this._onMessageAudio.bind(this))}_registerOnMessageDocument(){this.bot.on("message:document",this._onMessageDocument.bind(this))}_registerOnMessageAnimation(){this.bot.on("message:animation",this._onMessageAnimation.bind(this))}_registerOnMessageVoice(){this.bot.on("message:voice",this._onMessageVoice.bind(this))}_registerOnMessageVideoNote(){this.bot.on("message:video_note",this._onMessageVideoNote.bind(this))}_registerOnMessageSticker(){this.bot.on("message:sticker",this._onMessageSticker.bind(this))}_registerOnMessageLocation(){this.bot.on("message:location",this._onMessageLocation.bind(this))}_registerOnMessageContact(){this.bot.on("message:contact",this._onMessageContact.bind(this))}};var X=class{static{p(this,"BlockKeyboard")}static label;static _build(e,t,n,s){if(!this.label)throw new Error("Label not found, make sure set this.label from class extends LabelKeyboard");n||(n="inline");let i=this.label[e];if(!i)throw new Error(`Object value ${e} not found`);let o=p((a,r)=>`<keyboard type="${n}" lang="${r}">${s?this.label._reverse(a):a}</keyboard>`,"pro");return t?o(i[t],t):Object.keys(i).map(a=>o(i[a],a)).join(" ")}};var Y=class{static{p(this,"LabelKeyboard")}static _reverse(e){return e.split(/(?<!\\), */).reverse().join(", ")}static _reverseObj(e){return Object.keys(e).reduce((t,n)=>(t[n]=this._reverse(e[n]),t),{})}};var H=require("worker_threads");var P=class{constructor(e,t){this.send=e;this.register=t}static{p(this,"WorkerThreadRpc")}map=new Map;async make(e){let t=this.map,n=this.send,{id:s,method:i,params:o,result:a,error:r}=e;if(i!==void 0)try{let c=this.register[i];if(typeof c!="function")throw new Error(`Method ${i} not found or not function`);let l=await c.apply(this.register,o);n({id:s,result:l})}catch(c){n({id:s,error:c instanceof Error?{message:c.message,stack:c.stack,name:c.name}:c})}else if(a!==void 0){let c=t.get(s);c&&(c.resolve(a),t.delete(s))}else if(r!==void 0){let c=t.get(s);c&&(c.reject(r),t.delete(s))}}makeId(){return Math.random()}makeRequest(e,t,n=!0,s){let i=this.makeId(),o={id:i,method:e,params:t,...s};return n?new Promise((a,r)=>{this.map.set(i,{resolve:a,reject:r}),this.send(o)}):this.send(o)}};var N=class{constructor(e,t,n){this.path=e;this.argv=t;this.register=n;this.init(),n||(n=this),this.rpc=new P(this.send.bind(this),n)}static{p(this,"WorkerThreadLaunch")}static isMainThread=H.isMainThread;_readyResolve;_readyPromise=new Promise(e=>this._readyResolve=e);pid=process.pid;thread={};threadId={};rpc={};ready(){return this._readyPromise}readyResolve(){this._readyResolve?.()}init(){this.thread=new H.Worker(this.path,{argv:this.argv.length==0&&this.argv[0]===void 0?void 0:this.argv}),this.threadId=this.thread.threadId,this.thread.on("message",e=>this.handleOnMessage(e)),this.thread.on("exit",()=>this.kill()),process.once("SIGINT",()=>this.kill()),process.once("SIGTERM",()=>this.kill())}async handleOnMessage(e){this.rpc.make(e)}kill(){this.thread.terminate()}send(e){this.thread.postMessage(e)}async request(e,t,n=!0,s){return this.rpc.makeRequest(e,t,n,s)}};var Z=class u{static{p(this,"WorkerThreadExport")}static launchGatewayClient(e){let t=new Proxy({},{get(s,i){if(!(typeof i!="string"||i==="then"))return async(o,...a)=>{let r=o.gatewayClients.get(e);return r||(r=await o.createGatewayClient(e)),r.request(i,a)}}}),n=p(function(s){return new Proxy({},{get(i,o){if(!(typeof o!="string"||o==="then"))return async(...a)=>{let r=s.gatewayClients.get(e);return r||(r=await s.createGatewayClient(e)),r.request(o,a)}}})},"ctor");return Object.setPrototypeOf(n,t),n}static init(e){let{WTInit:t,WTLaunch:n=N,path:s,wrap:i}=e,o=`for-${s}`;if(process.argv[2]===o)return new t,{launchGatewayClient:p(d=>u.launchGatewayClient(d||t.gatewayServerPath),"launchGatewayClient")};let a,r=new Proxy({},{get(d,h){if(h!=="then")return h==="sendRequest"||h==="request"||h==="kill"||h==="send"?(...m)=>{if(!a)throw new Error(`Thread at ${s} not launched yet.`);return a[h](...m)}:(...m)=>{if(!a)throw new Error(`Thread at ${s} not launched yet.`);return a.request(h,m)}}}),l={...i?i(r):{},launchWorker:p(async(d=[])=>(a=new n(s,[o,...d]),await a.ready(),a),"launchWorker"),launchGatewayClient:p(d=>u.launchGatewayClient(d||t.gatewayServerPath),"launchGatewayClient")};return new Proxy(l,{get(d,h){if(h!=="then")return h==="launchGatewayClient"?d.launchGatewayClient:h==="launchWorker"?d.launchWorker:h in d?d[h]:typeof h=="string"?(...m)=>{if(!a)throw new Error(`Thread at ${s} not launched yet.`);return a.request(h,m)}:d[h]}})}};var pe=require("net-ipc");var j=class{static{p(this,"WorkerThreadGatewayClient")}client=new pe.Client;rpc;constructor(){this.rpc=new P(e=>this.client.send(e),{}),this.client.on("message",e=>{this.rpc.make(e)})}async connect(e){this.client.options.path=e;let t=new Promise(n=>{this.client.once("ready",()=>n(this))});return await this.client.connect(),t}async request(e,t,n=!0,s){return this.rpc.makeRequest(e,t,n,s)}};var ue=require("net-ipc");var q=class{static{p(this,"WorkerThreadGatewayServer")}server=new ue.Server;rpc=new Map;register={};constructor(){this.server.on("connect",e=>{let t=new P(n=>e.send(n),this.register);this.rpc.set(e.id,t)}),this.server.on("disconnect",e=>{this.rpc.delete(e.id)}),this.server.on("message",(e,t)=>{let n=this.rpc.get(t.id);n&&n.make(e)}),this.server.on("error",e=>{console.error(e)})}async start(e,t={}){this.register=t,this.server.options.path=e;let n=new Promise(s=>{this.server.once("ready",()=>s(this))});return await this.server.start(),n}};var B=require("worker_threads");var ee=class{static{p(this,"WorkerThreadInit")}argv=process.argv;id=B.threadId;pid=process.pid;rpc={};parentPort=B.parentPort;gatewayServer;gatewayClients=new Map;gatewayClientLatest;static gatewayServerPath;gatewayServerPath=this.constructor.gatewayServerPath;get gatewayClient(){return this.gatewayClientLatest}static isMainThread=B.isMainThread;constructor(){this.init(),this.rpc=new P(this.send.bind(this),this),this.send({method:"readyResolve"})}init(){this.parentPort?.on("message",e=>this.handleOnMessage(e))}handleOnMessage(e){this.rpc.make(e)}send(e){this.parentPort?.postMessage(e)}request(e,t,n=!0,s){return this.rpc.makeRequest(e,t,n,s)}async createGatewayServer(e,t){return e||(e=this),t||(t=this.constructor.gatewayServerPath),this.gatewayServer=new q,await this.gatewayServer.start(t,e),this.constructor.gatewayServerPath=t,!0}async createGatewayClient(e){let t=new j;return await t.connect(e),this.gatewayClients.set(e,t),this.gatewayClientLatest=t,t}};var te=class{static{p(this,"WorkerThreadPool")}thread=new Map;threadCount=0;constructor(e){this.addMany(e)}add(e){this.thread.set(e.threadId,e),this.threadCount+=1}addMany(e){e.forEach(t=>this.add(t))}getInstance(e){return this.thread.get(e)}kill(e){let t=this.thread.get(e);return t?.kill(),this.thread.delete(e),this.threadCount-=1,t?.threadId}killAll(){this.thread.values().forEach(({threadId:e})=>this.kill(e))}async broadcastRequest(e,t){return await Promise.all(Object.values(this.thread).map(n=>n.request(e,t,!0)))}async request(e,t,n,s=!0,i){return await this.thread.get(e)?.request(t,n,s,i)}};var se=class{static{p(this,"MockTelegramServer")}token;hostname;port;handlers;defaultHandler;apiRoot="";server;constructor(e){this.token=e.token,this.hostname=e.hostname??"127.0.0.1",this.port=e.port??0,this.handlers=e.handlers??{},this.defaultHandler=e.defaultHandler}async start(){if(this.server)return this.apiRoot;let e=Bun.serve({port:this.port,hostname:this.hostname,fetch:p(async t=>this._handleRequest(t),"fetch")});return this.server=e,this.apiRoot=`http://${this.hostname}:${e.port??this.port}`,this.apiRoot}async stop(){this.server?.stop(),this.server=void 0}_json(e){return new Response(JSON.stringify(e),{status:200,headers:{"Content-Type":"application/json"}})}_defaultResponse(e){return e==="getMe"?{ok:!0,result:{id:123456789,is_bot:!0,first_name:"Mock",username:"mock_gramstax_bot"}}:e==="getUpdates"?{ok:!0,result:[]}:e==="getMyCommands"?{ok:!0,result:[]}:e==="setMyCommands"?{ok:!0,result:!0}:e==="setWebhook"?{ok:!0,result:!0}:e==="getWebhookInfo"?{ok:!0,result:{url:""}}:{ok:!0,result:!0}}async _handleRequest(e){let{pathname:t}=new URL(e.url),n=`/bot${this.token}/`;if(!t.startsWith(n))return new Response("Not found",{status:404});let s=t.slice(n.length),i=this.handlers[s]??this.defaultHandler,o=i?await i({method:s,request:e}):this._defaultResponse(s);return this._json(o)}};0&&(module.exports={BlockKeyboard,CacheExternal,Ctx,Gramstax,LabelKeyboard,LoggingHelper,MockTelegramServer,PageManager,TemplateEngine,TemplateManager,WebhookQueue,WorkerThreadExport,WorkerThreadGatewayClient,WorkerThreadGatewayServer,WorkerThreadInit,WorkerThreadLaunch,WorkerThreadPool,WorkerThreadRpc,log});
7
+ `);a=a.replace(`__IMPORT_${r}__`,h)}return a}};var $=class{static{p(this,"TemplateManager")}_map=new Map;_engine=M;_watcher=[];_pageManager=x;_supportedExtensions=new Set([".html",".ts",".js"]);_path;_isWatchEnabled;constructor(e){let{path:t,enableWatch:n=!1}=e;this._path=t,this._isWatchEnabled=n,this._validatePath(),this._initializeWatcher(e.watchOptions),this._loadAllFiles()}_validatePath(){try{if(!this._path||!Array.isArray(this._path))throw new Error("Path must be set as string array");for(let e=0;e<this._path.length;e++){let t=this._path[e];if(!(0,C.existsSync)(t))throw new Error(`Template base path is not exists: ${t}`);if(!(0,C.statSync)(t).isDirectory())throw new Error(`Template base path is not a directory: ${t}`)}return!0}catch(e){throw new Error(`Failed to validate Template base path: ${String(e)}`)}}_initializeWatcher(e){if(this._isWatchEnabled){if(this._watcher.length>0)throw new Error("Watcher already enabled");for(let t=0;t<this._path.length;t++){let n=this._path[t],s=(0,de.watch)(n,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},...e});this._watcher[t]=s,s.on("change",this._handleFileChange.bind(this)),s.on("add",this._handleFileAdd.bind(this)),s.on("unlink",this._handleFileDelete.bind(this)),s.on("error",this._handleWatchError.bind(this))}}}_handleFileChange(e){let t=(0,w.basename)(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileAdd(e){let t=(0,w.basename)(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileDelete(e){let t=(0,w.basename)(e),n=this._getKey(t);this._map.has(n)&&this._map.delete(n)}_handleWatchError(e){}_loadAllFiles(){let e=new Map,t=[];for(let s=0;s<this._path.length;s++){let i=this._path[s],a=(0,C.readdirSync)(i,"utf8").filter(r=>this._isValidFile(r));for(let r of a){let c=(0,w.join)(i,r),l=this._getExtension(r),d=this._getKey(r);if(l===".html")e.set(d,(0,C.readFileSync)(c,"utf8"));else if(l===".ts"||l===".js"){let h=x.getFileSync(c);h?.template!==void 0&&(e.set(d,h.template),t.push(h))}}}let n=new Map;for(let[s,i]of e.entries())this._compile(s,i,void 0,n,e);e.clear(),n.clear();for(let s of t)s.template=void 0}_loadFile(e){for(let t=0;t<this._path.length;t++){let n=this._path[t],s=(0,w.join)(n,e),i=this._getExtension(e),o=this._getKey(e);if(i==".html"){let a=(0,C.readFileSync)(s,"utf8");this._compile(o,a)}else if(i==".ts"||i==".js"){let a=x.getFileSync(s);a?.template!==void 0&&(this._compile(o,a.template),a.template=void 0)}else throw new Error(`File ${e} is not support`)}}_getExtension(e){return(0,w.extname)(e).toLowerCase()}_readTemplateFile(e){for(let t of this._path){let n=(0,w.extname)(e).toLowerCase();if(n){let a=(0,w.join)(t,e);if((0,C.existsSync)(a)&&(0,C.statSync)(a).isFile()){if(n===".html")return(0,C.readFileSync)(a,"utf8");if(n===".ts"||n===".js")try{return x.getFileSync(a)?.template??null}catch{return null}}continue}let s=(0,w.join)(t,`${e}.ts`),i=(0,w.join)(t,`${e}.js`);if((0,C.existsSync)(s)&&(0,C.statSync)(s).isFile())try{return x.getFileSync(s)?.template??null}catch{}else if((0,C.existsSync)(i)&&(0,C.statSync)(i).isFile())try{return x.getFileSync(s)?.template??null}catch{}let o=(0,w.join)(t,`${e}.html`);if((0,C.existsSync)(o)&&(0,C.statSync)(o).isFile())return(0,C.readFileSync)(o,"utf8")}return null}_isValidFile(e){return this._supportedExtensions.has(this._getExtension(e))}_getKey(e){return e.replace(/\.[^/.]+$/,"")}_compile(e,t,n,s,i){let o=this._map.get(e),a=o||{},r=!1,c=M.processImportBlocks(t,d=>i&&i.has(d)?i.get(d):this._readTemplateFile(d),0,s),l=M._processBaseBlocks(c);(n===void 0||n?.media===!1||o?.media===void 0)&&(a.media=M.compileBlockMedia(c,l),r=!0),(n===void 0||n?.message===!1||o?.message===void 0)&&(a.message=M.compileBlockMessage(c,l),r=!0),(n===void 0||n?.keyboard===!1||o?.keyboard===void 0)&&(a.keyboard=M.compileBlockKeyboards(c,l),r=!0),(n===void 0||n?.description===!1||o?.description===void 0)&&(a.description=M.compileBlockDescription(c,l),r=!0),r&&this._map.set(e,a)}getMedia(e,t="default",n="default",s){let o=this._map.get(e)?.media?.[t],a=o?.[n]||o?.default;try{if(!a)throw new Error("Media function not found, please check your template");return a(s)}catch{return{}}}getMessage(e,t="default",n="default",s){try{let o=this._map.get(e)?.message?.[t],a=o?.[n]||o?.default;if(!a)throw"";return a(s)}catch{return""}}getDescription(e,t="default",n="default",s="default",i){try{let a=this._map.get(e)?.description?.[t]?.[s],r=a?.[n]||a?.default;if(!r)throw"";return r(i)}catch{return""}}getDescriptionLanguage(e,t="default",n="default"){try{let i=this._map.get(e)?.description?.[t]?.[n];return i?Object.keys(i):[]}catch{return[]}}getDescriptionScopes(e,t="default"){try{let s=this._map.get(e)?.description?.[t];return s?Object.keys(s):[]}catch{return[]}}getKeyboard(e,t="default",n="default",s="inline",i){try{let a=this._map.get(e)?.keyboard?.[t],r=a?.[n]?.[s]||a?.default?.[s];if(!r)throw[];return r(i)}catch{return[]}}async write(e,t){if(this._getExtension(e)!=".html")return null;for(let n=0;n<this._path.length;n++){let s=(0,w.join)(this._path[n],e);if((0,C.existsSync)(s))return(0,C.writeFileSync)(s,t,"utf8"),this._loadFile(e),!0}return null}has(e){return this._map.has(e)}async destroy(){if(this._watcher)for(let e of this._watcher)await e.close();this._map.clear()}};var L=require("grammy");var E=class{constructor(e){this.maxSize=e;if(!Number.isFinite(e)||e<=0)throw new Error("WebhookQueue maxSize must be a positive number")}static{p(this,"WebhookQueue")}queue=[];waitEnqueue=[];waitDequeue=[];getStats(){return{length:this.queue.length,maxSize:this.maxSize,waitingEnqueue:this.waitEnqueue.length,waitingDequeue:this.waitDequeue.length}}get length(){return this.queue.length}async enqueue(e){if(this.queue.length>=this.maxSize&&await new Promise(t=>this.waitEnqueue.push(t)),this.waitDequeue.length>0){this.waitDequeue.shift()(e);return}this.queue.push(e)}async dequeue(){if(this.queue.length>0){let e=this.queue.shift();return this.waitEnqueue.shift()?.(),e}return await new Promise(e=>this.waitDequeue.push(e))}};var Ie=(0,v.dirname)((()=>{try{return __filename}catch{return(0,me.fileURLToPath)(f)}})()),xe=JSON.parse((0,le.readFileSync)((0,v.join)(Ie,"../../package.json"),"utf-8")).version,J=class{static{p(this,"Gramstax")}templateManager;cacheKeyboard;cacheSession;pages;optionsPage={shortCallbackData:!1};log;bot;botConfig;webhookQueue;webhookQueueInstance;webhookServer;handlerBotUpdate;constructor(e){if(!e?.token||e?.token?.length==0)throw new Error("Token is not valid or empty");if(typeof e.optionsPage?.shortCallbackData=="boolean"&&(this.optionsPage.shortCallbackData=e.optionsPage.shortCallbackData),this.log=e.log===!0?U:e.log?e.log:void 0,this.log?.info?.(`Gramstax v${xe}`),this.cacheSession=e.cacheSession||new W("memory"),this.cacheKeyboard=e.cacheKeyboard||new Map,this.botConfig=e.botConfig,this.webhookQueue=e.webhookQueue,this.templateManager=e.templateManager||new $({path:[(0,v.join)(process.cwd(),"src","pages")]}),this.bot=this.createBot(e.token),this.bot.catch(this._onCatch),this._registerOnCallbackQueryData(),this._registerOnMessageText(),this._registerOnMessagePhoto(),this._registerOnMessageVideo(),this._registerOnMessageAudio(),this._registerOnMessageDocument(),this._registerOnMessageAnimation(),this._registerOnMessageVoice(),this._registerOnMessageVideoNote(),this._registerOnMessageSticker(),this._registerOnMessageLocation(),this._registerOnMessageContact(),this.handlerBotUpdate=this.bot.handleUpdate,this.pages=this._pageLoads(),process.once("SIGINT",()=>this.bot.stop()),process.once("SIGTERM",()=>this.bot.stop()),this.hookBeforeStart(),e.deploy.startsWith("polling"))this._runPolling();else if(e.deploy.startsWith("webhook:"))this._runWebhook(e.deploy.split("webhook:")[1]);else if(e.deploy.startsWith("serverless:"))this._runServerless(e.deploy.split("serverless:")[1]);else if(!e.deploy.startsWith("test"))throw new Error("Params deploy is not valid, expected: polling, webhook:<public-url>, serverless:<your-adapter>")}_onCatch(e){if(this.log?.errorMake)this.log?.errorMake(e,"Bot","catch");else{let t=JSON.stringify(e,null,2);this.log?.error?.(`[Bot.catch]: ${t}`)}}hookBeforeStart(){}hookAfterStart(){}async _onStart(e,t,n){await this.executeSyncBlocksDescription(this.pages);let{username:s}=e;this.log?.success?.(`Telegram bot polling started: ${s} ${t=="webhook"||t=="serverless"?`(${n})`:""}`),this.hookAfterStart()}createBot(e){return new L.Bot(e,this.botConfig)}createCtx(e){return new K({ct:e,cacheSession:this.cacheSession,cacheKeyboard:this.cacheKeyboard,templateManager:this.templateManager,temp:{isAnswer:!1,session:{},data:{}}})}_runPolling(){this.bot.start({drop_pending_updates:!0,onStart:p(e=>{this._onStart(e,"polling",null)},"onStart")})}async _runWebhook(e){let{serve:t}=await import("bun"),n=(0,L.webhookCallback)(this.bot,"bun"),s=this.webhookQueue,i=s?.enabled===!0;this.handlerBotUpdate=i?this.bot.handleUpdate.bind(this.bot):n;let o=i?new E(s?.maxQueueSize??5e3):void 0,a=s?.workerCount??8,r=s?.perChatConcurrency??1,c=s?.blockWhenFull!==!1,l=new Map,d=new Map;this.webhookQueueInstance=o;let h=p(y=>y?.message?.chat?.id??y?.edited_message?.chat?.id??y?.channel_post?.chat?.id??y?.edited_channel_post?.chat?.id??y?.callback_query?.message?.chat?.id??y?.callback_query?.from?.id??y?.inline_query?.from?.id??y?.chosen_inline_result?.from?.id,"getChatId"),m=p(async y=>{if(!i||r<=0||y===void 0||y===null)return()=>{};let S=String(y),b=l.get(S)||0;if(b<r)return l.set(S,b+1),()=>this._releaseWebhookChat(S,l,d);await new Promise(ge=>{let ne=d.get(S)||[];ne.push(ge),d.set(S,ne)});let R=(l.get(S)||0)+1;return l.set(S,R),()=>this._releaseWebhookChat(S,l,d)},"acquireChat");if(i&&o){await this.bot.init();for(let y=0;y<a;y++)this._startWebhookWorker(o,m,h)}let g=new URL(e).pathname,_=this.log,T="/stats_queue";this.webhookServer?.stop();let I=t({async fetch(y){let{pathname:S}=new URL(y.url);if(y.method=="POST"&&S==g){if(!i||!o)return n(y);if(!c&&o.length>=(s?.maxQueueSize??5e3))return new Response("Queue full",{status:429});try{let b=await y.json();return await o.enqueue(b),new Response("OK",{status:200})}catch(b){return _?.error?.(`Webhook queue error: ${String(b)}`),new Response("Bad Request",{status:400})}}if(y.method=="GET"&&S==T){let b=o?.getStats()||{length:0,maxSize:s?.maxQueueSize??5e3,waitingEnqueue:0,waitingDequeue:0};return new Response(JSON.stringify({enabled:i,path:T,timestamp:new Date().toISOString(),maxQueueSize:s?.maxQueueSize??5e3,workerCount:a,perChatConcurrency:r,blockWhenFull:c,queue:b,activeChats:l.size}),{status:200,headers:{"Content-Type":"application/json"}})}if(y.method=="GET"&&S=="/"){let b=new Date().toISOString();return new Response(JSON.stringify({status:"OK",timestamp:b}),{status:200,headers:{"Content-Type":"application/json"}})}return new Response("Not found",{status:404})}});this.webhookServer=I;let k=p(()=>{this.webhookServer?.stop(),this.webhookServer=void 0},"stopServer");process.once("SIGINT",k),process.once("SIGTERM",k),(await this.bot.api.getWebhookInfo()).url!=e&&await this.bot.api.setWebhook(e);let D=await this.bot.api.getMe();await this._onStart(D,"webhook",e)}_startWebhookWorker(e,t,n){p(async()=>{for(;;){let i=await e.dequeue(),o=await t(n(i));try{await this.bot.handleUpdate(i)}catch(a){this.log?.error?.(`Webhook worker error: ${String(a)}`)}finally{o()}}},"run")()}_releaseWebhookChat(e,t,n){let s=t.get(e)||0,i=Math.max(0,s-1);i===0?t.delete(e):t.set(e,i);let o=n.get(e);o&&o.length>0&&(o.shift()(),o.length===0&&n.delete(e))}getWebhookQueueStats(){if(!this.webhookQueue?.enabled||!this.webhookQueueInstance)return null;let e=this.webhookQueueInstance.getStats(),t=this.webhookQueue.maxQueueSize??5e3,n=this.webhookQueue.workerCount??8,s=this.webhookQueue.perChatConcurrency??1,i=this.webhookQueue.blockWhenFull!==!1;return{enabled:!0,maxQueueSize:t,workerCount:n,perChatConcurrency:s,blockWhenFull:i,...e}}async _runServerless(e){this.handlerBotUpdate=(0,L.webhookCallback)(this.bot,e);let t=await this.bot.api.getMe();await this._onStart(t,"serverless",e)}_pageBuildData(e,t){e?.data===void 0&&(e.data=e.buildData());let{name:n}=(0,v.parse)(t);e.data.name||(e.data.name=n),e.data.intentText||(e.data.intentText=e.data.name),e.data.intentCommandText||(e.data.intentCommandText=e.data.name),e.data.intentCallbackData||(e.data.intentCallbackData=e.data.name)}_pageSorts(e,t,n){let s=e.data.name,i=e.prototype,o="handle",a="Args",r="Command",c="Caption",l="Free",d=t.routeDynamic,h=t.routeDynamicSpesific;t.all[s]=e;for(let m=0;m<t.lenListRouteStaticSession;m++){let g=t.listRouteStaticSession[m];if(typeof i[g]!="function")continue;let _=t.routeStatic[g],T=t.routeStaticIntent[g],I=t.routeStaticSession[g],k={name:s,routeName:g},A=_||T;if(A!==void 0){let D=g.includes(r),y=g.endsWith("CallbackData"),S=g.endsWith("Text"),b;if(D){let R=e.data.intentCommandText;b=R?`/${R}`:void 0}else if(y){let R=e.data.intentCallbackData;this.optionsPage.shortCallbackData===!0&&(R=String(n),e.data.intentCallbackData=R),b=R}else S?b=e.data.intentText:b=e.data.name;b&&(A[b]=k)}if(I!==void 0){let y=`methodSession${g.replace("handle","")}`,S=i[y]?.(s);I[S]=k}if(g.startsWith("handleFree")){let D=g.replace(o,"").replace(a,"").replace(r,"").replace(c,"").replace(l,"").toLowerCase();h[D].push(k)}}i.handleFree&&d.push(s)}async executeSyncBlocksDescription(e){let t=new Map,n=e.routeStatic.handleCommandText;for(let[,s]of Object.entries(n)){let i=s.name,o=this.templateManager.getDescriptionScopes(i);for(let a of o){t.has(a)||t.set(a,new Set);let r=this.templateManager.getDescriptionLanguage(i,"default",a);for(let c of r)t.get(a).add(c)}}for(let[s,i]of t)for(let o of i){let a=[];for(let[,l]of Object.entries(n)){let d=l.name,h=this.templateManager.getDescription(d,"default",o,s);h&&a.push({command:d,description:h})}if(a.length===0)continue;let r={type:s},c=o==="default"?void 0:o;try{let l=await this.bot.api.getMyCommands({scope:r,language_code:c}),d=JSON.stringify(l.map(m=>({command:m.command,description:m.description})).sort((m,g)=>m.command.localeCompare(g.command))),h=JSON.stringify(a.sort((m,g)=>m.command.localeCompare(g.command)));d!==h&&(await this.bot.api.setMyCommands(a,{scope:r,language_code:c}),this.log?.info?.(`Synced descriptions for scope: ${s},${c?` lang: ${c},`:""} total (${a.length})`))}catch(l){this.log?.error?.(`Failed to sync descriptions for scope: ${s},${c?` lang: ${c},`:""} error: ${String(l)}`)}}}_pageLoads(){this.log?.info?.("Load pages..");let e=["handleCallbackData","handleText","handleCommandText","handleCaptionPhoto","handleCommandCaptionPhoto","handleCaptionVideo","handleCommandCaptionVideo","handleCaptionAudio","handleCommandCaptionAudio","handleCaptionDocument","handleCommandCaptionDocument","handleCaptionAnimation","handleCommandCaptionAnimation","handleCaptionVoice","handleCommandCaptionVoice"],t=["handleArgsCallbackData","handleArgsText","handleCommandArgsText","handleCaptionArgsPhoto","handleCommandCaptionArgsPhoto","handleCaptionArgsVideo","handleCommandCaptionArgsVideo","handleCaptionArgsAudio","handleCommandCaptionArgsAudio","handleCaptionArgsDocument","handleCommandCaptionArgsDocument","handleCaptionArgsAnimation","handleCommandCaptionArgsAnimation","handleCaptionArgsVoice","handleCommandCaptionArgsAnimation"],n=[...e,...t,"handleFreeText","handleFreePhoto","handleFreeVideo","handleFreeAudio","handleFreeDocument","handleFreeAnimation","handleFreeVoice","handleFreeVideoNote","handleFreeSticker","handleFreeLocation","handleFreeContact"],s=p((a,r)=>Object.fromEntries(a.map(c=>[c,r()])),"makeObject"),i=p(()=>[],"initDynamicSpesific"),o={all:{},routeDynamic:[],routeDynamicSpesific:{text:i(),photo:i(),video:i(),audio:i(),document:i(),animation:i(),voice:i(),videonote:i(),sticker:i(),location:i(),contact:i()},routeStatic:s(e,()=>({})),routeStaticIntent:s(t,()=>({})),routeStaticSession:s(n,()=>({})),listRouteStatic:e,listRouteStaticIntent:t,listRouteStaticSession:n,lenListRouteStatic:e.length,lenListRouteStaticIntent:t.length,lenListRouteStaticSession:n.length};return x.getFileManySync(void 0).forEach(({path:a,page:r},c)=>{this._pageBuildData(r,a),this._pageSorts(r,o,c),r.template=void 0}),this.log?.info?.(`Finish load pages with total (${Object.keys(o.all).length})`),o}async _pageRoutes(e,t){let n,s;if(n===void 0){let o=await e.getSession();if(o){let a=o.method,r=this.pages.routeStaticSession,c=e.callbackData,l=e.msgText,d=e.msgCaption,h=c||l||d,m=t==="callbackdata",g=m?"colon":"space",_=h&&e.haveArgs(h,g)?e.getIntent(h,g,1):void 0,T=!m&&h?e.getIntent(h,"space",2):void 0;for(let I=0;I<this.pages.lenListRouteStaticSession;I++){let k=this.pages.listRouteStaticSession[I];if(k.toLowerCase().endsWith(t)){if(h){if(this.pages.routeStatic[k]?.[h])continue;let A=this.pages.routeStaticIntent[k];if(A&&(_&&A[_]||T&&A[T]))continue}s=r[k][a]}if(s)break}s!==void 0&&(n=this.pages.all[s.name])}}if(n===void 0){let o=e.callbackData,a=e.msgText,r=e.msgCaption,c=this.pages.routeStatic;for(let l=0;l<this.pages.lenListRouteStatic;l++){let d=this.pages.listRouteStatic[l];if(d.toLowerCase().endsWith(t)&&(s=c[d][o||a||r]),s)break}s!==void 0&&(n=this.pages.all[s.name])}if(n===void 0){let o=this.pages.routeStaticIntent,a=t==="callbackdata",r=a?"colon":"space",c=a?e.callbackData:e.msgText||e.msgCaption,l=e.haveArgs(c,r);if(c&&l)for(let d=0;d<this.pages.lenListRouteStaticIntent;d++){let h=this.pages.listRouteStaticIntent[d];if(!h.toLowerCase().endsWith(t))continue;let m=o[h];if(s=m[e.getIntent(c,r,1)],!s&&!a&&(s=m[e.getIntent(c,"space",2)]),s)break}s!==void 0&&(n=this.pages.all[s.name])}if(n!==void 0&&s!==void 0){if(!n.prototype[s.routeName])return;let a=await new n(e)[s.routeName]?.();return e.temp.isAnswer===!0?a:null}let i=this.pages.routeDynamicSpesific[t]||[];for(let o=0;o<i.length;o++){let a=i[o];if(a===void 0)continue;let r=this.pages.all[a.name];r!==void 0&&typeof r.prototype[a.routeName]=="function"&&await new r(e)[a.routeName]()}for(let o=0;o<this.pages.routeDynamic.length;o++){let a=this.pages.routeDynamic[o];if(a===void 0)continue;let r=this.pages.all[a];r!==void 0&&typeof r.prototype.handleFree=="function"&&await new r(e).handleFree()}if(e.temp.isAnswer===!1)return null}async hookBeforeRoute(e,t){return!!(e||t)}async hookErrorPage(e,t,n,s){}async hookErrorInputNotFoundPage(e){}async _onMessage(e,t){let n=this.createCtx(e);try{if(await this.hookBeforeRoute(n,t)===!1)return;await this._pageRoutes(n,t)===null&&await this.hookErrorInputNotFoundPage(n)}catch(s){await this.hookErrorPage(n,t,s,!1)}}async _onCallbackQueryData(e){let t=this.createCtx(e);try{if(await this.hookBeforeRoute(t,"onCallbackQueryData")===!1)return;await this._pageRoutes(t,"callbackdata")}catch(n){await this.hookErrorPage(t,"onCallbackQueryData",n,!0)}}async _onMessageText(e){await this._onMessage(e,"text")}async _onMessagePhoto(e){await this._onMessage(e,"photo")}async _onMessageVideo(e){await this._onMessage(e,"video")}async _onMessageAudio(e){await this._onMessage(e,"audio")}async _onMessageDocument(e){await this._onMessage(e,"document")}async _onMessageAnimation(e){await this._onMessage(e,"animation")}async _onMessageVoice(e){await this._onMessage(e,"voice")}async _onMessageVideoNote(e){await this._onMessage(e,"videonote")}async _onMessageSticker(e){await this._onMessage(e,"sticker")}async _onMessageLocation(e){await this._onMessage(e,"location")}async _onMessageContact(e){await this._onMessage(e,"contact")}_registerOnCallbackQueryData(){this.bot.on("callback_query:data",this._onCallbackQueryData.bind(this))}_registerOnMessageText(){this.bot.on("message:text",this._onMessageText.bind(this))}_registerOnMessagePhoto(){this.bot.on("message:photo",this._onMessagePhoto.bind(this))}_registerOnMessageVideo(){this.bot.on("message:video",this._onMessageVideo.bind(this))}_registerOnMessageAudio(){this.bot.on("message:audio",this._onMessageAudio.bind(this))}_registerOnMessageDocument(){this.bot.on("message:document",this._onMessageDocument.bind(this))}_registerOnMessageAnimation(){this.bot.on("message:animation",this._onMessageAnimation.bind(this))}_registerOnMessageVoice(){this.bot.on("message:voice",this._onMessageVoice.bind(this))}_registerOnMessageVideoNote(){this.bot.on("message:video_note",this._onMessageVideoNote.bind(this))}_registerOnMessageSticker(){this.bot.on("message:sticker",this._onMessageSticker.bind(this))}_registerOnMessageLocation(){this.bot.on("message:location",this._onMessageLocation.bind(this))}_registerOnMessageContact(){this.bot.on("message:contact",this._onMessageContact.bind(this))}};var X=class{static{p(this,"BlockKeyboard")}static label;static _build(e,t,n,s){if(!this.label)throw new Error("Label not found, make sure set this.label from class extends LabelKeyboard");n||(n="inline");let i=this.label[e];if(!i)throw new Error(`Object value ${e} not found`);let o=p((a,r)=>`<keyboard type="${n}" lang="${r}">${s?this.label._reverse(a):a}</keyboard>`,"pro");return t?o(i[t],t):Object.keys(i).map(a=>o(i[a],a)).join(" ")}};var Y=class{static{p(this,"LabelKeyboard")}static _reverse(e){return e.split(/(?<!\\), */).reverse().join(", ")}static _reverseObj(e){return Object.keys(e).reduce((t,n)=>(t[n]=this._reverse(e[n]),t),{})}};var H=require("worker_threads");var P=class{constructor(e,t){this.send=e;this.register=t}static{p(this,"WorkerThreadRpc")}map=new Map;async make(e){let t=this.map,n=this.send,{id:s,method:i,params:o,result:a,error:r}=e;if(i!==void 0)try{let c=this.register[i];if(typeof c!="function")throw new Error(`Method ${i} not found or not function`);let l=await c.apply(this.register,o);n({id:s,result:l})}catch(c){n({id:s,error:c instanceof Error?{message:c.message,stack:c.stack,name:c.name}:c})}else if(a!==void 0){let c=t.get(s);c&&(c.resolve(a),t.delete(s))}else if(r!==void 0){let c=t.get(s);c&&(c.reject(r),t.delete(s))}}makeId(){return Math.random()}makeRequest(e,t,n=!0,s){let i=this.makeId(),o={id:i,method:e,params:t,...s};return n?new Promise((a,r)=>{this.map.set(i,{resolve:a,reject:r}),this.send(o)}):this.send(o)}};var N=class{constructor(e,t,n){this.path=e;this.argv=t;this.register=n;this.init(),n||(n=this),this.rpc=new P(this.send.bind(this),n)}static{p(this,"WorkerThreadLaunch")}static isMainThread=H.isMainThread;_readyResolve;_readyPromise=new Promise(e=>this._readyResolve=e);pid=process.pid;thread={};threadId={};rpc={};ready(){return this._readyPromise}readyResolve(){this._readyResolve?.()}init(){this.thread=new H.Worker(this.path,{argv:this.argv.length==0&&this.argv[0]===void 0?void 0:this.argv}),this.threadId=this.thread.threadId,this.thread.on("message",e=>this.handleOnMessage(e)),this.thread.on("exit",()=>this.kill()),process.once("SIGINT",()=>this.kill()),process.once("SIGTERM",()=>this.kill())}async handleOnMessage(e){this.rpc.make(e)}kill(){this.thread.terminate()}send(e){this.thread.postMessage(e)}async request(e,t,n=!0,s){return this.rpc.makeRequest(e,t,n,s)}};var Z=class u{static{p(this,"WorkerThreadExport")}static launchGatewayClient(e){let t=new Proxy({},{get(s,i){if(!(typeof i!="string"||i==="then"))return async(o,...a)=>{let r=o.gatewayClients.get(e);return r||(r=await o.createGatewayClient(e)),r.request(i,a)}}}),n=p(function(s){return new Proxy({},{get(i,o){if(!(typeof o!="string"||o==="then"))return async(...a)=>{let r=s.gatewayClients.get(e);return r||(r=await s.createGatewayClient(e)),r.request(o,a)}}})},"ctor");return Object.setPrototypeOf(n,t),n}static init(e){let{WTInit:t,WTLaunch:n=N,path:s,wrap:i}=e,o=`for-${s}`;if(process.argv[2]===o)return new t,{launchGatewayClient:p(d=>u.launchGatewayClient(d||t.gatewayServerPath),"launchGatewayClient")};let a,r=new Proxy({},{get(d,h){if(h!=="then")return h==="sendRequest"||h==="request"||h==="kill"||h==="send"?(...m)=>{if(!a)throw new Error(`Thread at ${s} not launched yet.`);return a[h](...m)}:(...m)=>{if(!a)throw new Error(`Thread at ${s} not launched yet.`);return a.request(h,m)}}}),l={...i?i(r):{},launchWorker:p(async(d=[])=>(a=new n(s,[o,...d]),await a.ready(),a),"launchWorker"),launchGatewayClient:p(d=>u.launchGatewayClient(d||t.gatewayServerPath),"launchGatewayClient")};return new Proxy(l,{get(d,h){if(h!=="then")return h==="launchGatewayClient"?d.launchGatewayClient:h==="launchWorker"?d.launchWorker:h in d?d[h]:typeof h=="string"?(...m)=>{if(!a)throw new Error(`Thread at ${s} not launched yet.`);return a.request(h,m)}:d[h]}})}};var pe=require("net-ipc");var j=class{static{p(this,"WorkerThreadGatewayClient")}client=new pe.Client;rpc;constructor(){this.rpc=new P(e=>this.client.send(e),{}),this.client.on("message",e=>{this.rpc.make(e)})}async connect(e){this.client.options.path=e;let t=new Promise(n=>{this.client.once("ready",()=>n(this))});return await this.client.connect(),t}async request(e,t,n=!0,s){return this.rpc.makeRequest(e,t,n,s)}};var ue=require("net-ipc");var q=class{static{p(this,"WorkerThreadGatewayServer")}server=new ue.Server;rpc=new Map;register={};constructor(){this.server.on("connect",e=>{let t=new P(n=>e.send(n),this.register);this.rpc.set(e.id,t)}),this.server.on("disconnect",e=>{this.rpc.delete(e.id)}),this.server.on("message",(e,t)=>{let n=this.rpc.get(t.id);n&&n.make(e)}),this.server.on("error",e=>{console.error(e)})}async start(e,t={}){this.register=t,this.server.options.path=e;let n=new Promise(s=>{this.server.once("ready",()=>s(this))});return await this.server.start(),n}};var B=require("worker_threads");var ee=class{static{p(this,"WorkerThreadInit")}argv=process.argv;id=B.threadId;pid=process.pid;rpc={};parentPort=B.parentPort;gatewayServer;gatewayClients=new Map;gatewayClientLatest;static gatewayServerPath;gatewayServerPath=this.constructor.gatewayServerPath;get gatewayClient(){return this.gatewayClientLatest}static isMainThread=B.isMainThread;constructor(){this.init(),this.rpc=new P(this.send.bind(this),this),this.send({method:"readyResolve"})}init(){this.parentPort?.on("message",e=>this.handleOnMessage(e))}handleOnMessage(e){this.rpc.make(e)}send(e){this.parentPort?.postMessage(e)}request(e,t,n=!0,s){return this.rpc.makeRequest(e,t,n,s)}async createGatewayServer(e,t){return e||(e=this),t||(t=this.constructor.gatewayServerPath),this.gatewayServer=new q,await this.gatewayServer.start(t,e),this.constructor.gatewayServerPath=t,!0}async createGatewayClient(e){let t=new j;return await t.connect(e),this.gatewayClients.set(e,t),this.gatewayClientLatest=t,t}};var te=class{static{p(this,"WorkerThreadPool")}thread=new Map;threadCount=0;constructor(e){this.addMany(e)}add(e){this.thread.set(e.threadId,e),this.threadCount+=1}addMany(e){e.forEach(t=>this.add(t))}getInstance(e){return this.thread.get(e)}kill(e){let t=this.thread.get(e);return t?.kill(),this.thread.delete(e),this.threadCount-=1,t?.threadId}killAll(){this.thread.values().forEach(({threadId:e})=>this.kill(e))}async broadcastRequest(e,t){return await Promise.all(Object.values(this.thread).map(n=>n.request(e,t,!0)))}async request(e,t,n,s=!0,i){return await this.thread.get(e)?.request(t,n,s,i)}};var se=class{static{p(this,"MockTelegramServer")}token;hostname;port;handlers;defaultHandler;apiRoot="";server;constructor(e){this.token=e.token,this.hostname=e.hostname??"127.0.0.1",this.port=e.port??0,this.handlers=e.handlers??{},this.defaultHandler=e.defaultHandler}async start(){if(this.server)return this.apiRoot;let e=Bun.serve({port:this.port,hostname:this.hostname,fetch:p(async t=>this._handleRequest(t),"fetch")});return this.server=e,this.apiRoot=`http://${this.hostname}:${e.port??this.port}`,process.once("SIGINT",()=>this.stop()),process.once("SIGTERM",()=>this.stop()),this.apiRoot}async stop(){this.server?.stop(),this.server=void 0}_json(e){return new Response(JSON.stringify(e),{status:200,headers:{"Content-Type":"application/json"}})}_defaultResponse(e){return e==="getMe"?{ok:!0,result:{id:123456789,is_bot:!0,first_name:"Mock",username:"mock_gramstax_bot"}}:e==="getUpdates"?{ok:!0,result:[]}:e==="getMyCommands"?{ok:!0,result:[]}:e==="setMyCommands"?{ok:!0,result:!0}:e==="setWebhook"?{ok:!0,result:!0}:e==="getWebhookInfo"?{ok:!0,result:{url:""}}:{ok:!0,result:!0}}async _handleRequest(e){let{pathname:t}=new URL(e.url),n=`/bot${this.token}/`;if(!t.startsWith(n))return new Response("Not found",{status:404});let s=t.slice(n.length),i=this.handlers[s]??this.defaultHandler,o=i?await i({method:s,request:e}):this._defaultResponse(s);return this._json(o)}};0&&(module.exports={BlockKeyboard,CacheExternal,Ctx,Gramstax,LabelKeyboard,LoggingHelper,MockTelegramServer,PageManager,TemplateEngine,TemplateManager,WebhookQueue,WorkerThreadExport,WorkerThreadGatewayClient,WorkerThreadGatewayServer,WorkerThreadInit,WorkerThreadLaunch,WorkerThreadPool,WorkerThreadRpc,log});
@@ -612,7 +612,7 @@ declare class Gramstax<ICtx extends Ctx = Ctx> {
612
612
  name: string;
613
613
  routeName: string;
614
614
  }[];
615
- videoNote: {
615
+ videonote: {
616
616
  name: string;
617
617
  routeName: string;
618
618
  }[];
@@ -612,7 +612,7 @@ declare class Gramstax<ICtx extends Ctx = Ctx> {
612
612
  name: string;
613
613
  routeName: string;
614
614
  }[];
615
- videoNote: {
615
+ videonote: {
616
616
  name: string;
617
617
  routeName: string;
618
618
  }[];
package/dist/src/index.js CHANGED
@@ -4,4 +4,4 @@ var de=Object.defineProperty;var p=(g,e)=>de(g,"name",{value:e,configurable:!0})
4
4
  `):l.map(m=>d(m.innerContent)).join(`
5
5
  `)}return a}static _processImportBlocks(e){let t=/([ \t]*)<import(?:\s+([^>]*))?\/?>/gi,s=[];return{processed:e.replace(t,(i,o,a)=>{let r={},c=/(\w+)="([^"]*)"/g;if(a)for(let m of a.matchAll(c))r[m[1]]=m[2];let l=r.src;if(!l)return"";let d;r.block&&(r.block==="all"?d="all":r.block.includes(",")?d=r.block.split(",").map(m=>m.trim()).filter(m=>m):d=r.block);let h={src:l,blocks:d,base:r.base||"default",lang:r.lang,section:r.section||"all",indent:o||""};return s.push(h),`${o}__IMPORT_${s.length-1}__`}),imports:s}}static processImportBlocks(e,t,s=0,n){if(s>10)return"";let{processed:i,imports:o}=this._processImportBlocks(e),a=i;for(let r=0;r<o.length;r++){let c=o[r],l=`${c.src}|${c.base}|${c.lang||""}|${c.section}|${Array.isArray(c.blocks)?c.blocks.join(","):c.blocks||""}`,d;if(n&&n.has(l))d=n.get(l);else{let m=t(c.src);d=m?this._extractBlock(m,c.blocks,c.base,c.section,c.lang):"",d&&d.includes("<import")&&(d=this.processImportBlocks(d,t,s+1,n)),n&&n.set(l,d)}let h=d.split(`
6
6
  `).map((m,u)=>u===0?m:c.indent+m).join(`
7
- `);a=a.replace(`__IMPORT_${r}__`,h)}return a}};var W=class{static{p(this,"TemplateManager")}_map=new Map;_engine=A;_watcher=[];_pageManager=_;_supportedExtensions=new Set([".html",".ts",".js"]);_path;_isWatchEnabled;constructor(e){let{path:t,enableWatch:s=!1}=e;this._path=t,this._isWatchEnabled=s,this._validatePath(),this._initializeWatcher(e.watchOptions),this._loadAllFiles()}_validatePath(){try{if(!this._path||!Array.isArray(this._path))throw new Error("Path must be set as string array");for(let e=0;e<this._path.length;e++){let t=this._path[e];if(!D(t))throw new Error(`Template base path is not exists: ${t}`);if(!O(t).isDirectory())throw new Error(`Template base path is not a directory: ${t}`)}return!0}catch(e){throw new Error(`Failed to validate Template base path: ${String(e)}`)}}_initializeWatcher(e){if(this._isWatchEnabled){if(this._watcher.length>0)throw new Error("Watcher already enabled");for(let t=0;t<this._path.length;t++){let s=this._path[t],n=Te(s,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},...e});this._watcher[t]=n,n.on("change",this._handleFileChange.bind(this)),n.on("add",this._handleFileAdd.bind(this)),n.on("unlink",this._handleFileDelete.bind(this)),n.on("error",this._handleWatchError.bind(this))}}}_handleFileChange(e){let t=Q(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileAdd(e){let t=Q(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileDelete(e){let t=Q(e),s=this._getKey(t);this._map.has(s)&&this._map.delete(s)}_handleWatchError(e){}_loadAllFiles(){let e=new Map,t=[];for(let n=0;n<this._path.length;n++){let i=this._path[n],a=fe(i,"utf8").filter(r=>this._isValidFile(r));for(let r of a){let c=R(i,r),l=this._getExtension(r),d=this._getKey(r);if(l===".html")e.set(d,V(c,"utf8"));else if(l===".ts"||l===".js"){let h=_.getFileSync(c);h?.template!==void 0&&(e.set(d,h.template),t.push(h))}}}let s=new Map;for(let[n,i]of e.entries())this._compile(n,i,void 0,s,e);e.clear(),s.clear();for(let n of t)n.template=void 0}_loadFile(e){for(let t=0;t<this._path.length;t++){let s=this._path[t],n=R(s,e),i=this._getExtension(e),o=this._getKey(e);if(i==".html"){let a=V(n,"utf8");this._compile(o,a)}else if(i==".ts"||i==".js"){let a=_.getFileSync(n);a?.template!==void 0&&(this._compile(o,a.template),a.template=void 0)}else throw new Error(`File ${e} is not support`)}}_getExtension(e){return Z(e).toLowerCase()}_readTemplateFile(e){for(let t of this._path){let s=Z(e).toLowerCase();if(s){let a=R(t,e);if(D(a)&&O(a).isFile()){if(s===".html")return V(a,"utf8");if(s===".ts"||s===".js")try{return _.getFileSync(a)?.template??null}catch{return null}}continue}let n=R(t,`${e}.ts`),i=R(t,`${e}.js`);if(D(n)&&O(n).isFile())try{return _.getFileSync(n)?.template??null}catch{}else if(D(i)&&O(i).isFile())try{return _.getFileSync(n)?.template??null}catch{}let o=R(t,`${e}.html`);if(D(o)&&O(o).isFile())return V(o,"utf8")}return null}_isValidFile(e){return this._supportedExtensions.has(this._getExtension(e))}_getKey(e){return e.replace(/\.[^/.]+$/,"")}_compile(e,t,s,n,i){let o=this._map.get(e),a=o||{},r=!1,c=A.processImportBlocks(t,d=>i&&i.has(d)?i.get(d):this._readTemplateFile(d),0,n),l=A._processBaseBlocks(c);(s===void 0||s?.media===!1||o?.media===void 0)&&(a.media=A.compileBlockMedia(c,l),r=!0),(s===void 0||s?.message===!1||o?.message===void 0)&&(a.message=A.compileBlockMessage(c,l),r=!0),(s===void 0||s?.keyboard===!1||o?.keyboard===void 0)&&(a.keyboard=A.compileBlockKeyboards(c,l),r=!0),(s===void 0||s?.description===!1||o?.description===void 0)&&(a.description=A.compileBlockDescription(c,l),r=!0),r&&this._map.set(e,a)}getMedia(e,t="default",s="default",n){let o=this._map.get(e)?.media?.[t],a=o?.[s]||o?.default;try{if(!a)throw new Error("Media function not found, please check your template");return a(n)}catch{return{}}}getMessage(e,t="default",s="default",n){try{let o=this._map.get(e)?.message?.[t],a=o?.[s]||o?.default;if(!a)throw"";return a(n)}catch{return""}}getDescription(e,t="default",s="default",n="default",i){try{let a=this._map.get(e)?.description?.[t]?.[n],r=a?.[s]||a?.default;if(!r)throw"";return r(i)}catch{return""}}getDescriptionLanguage(e,t="default",s="default"){try{let i=this._map.get(e)?.description?.[t]?.[s];return i?Object.keys(i):[]}catch{return[]}}getDescriptionScopes(e,t="default"){try{let n=this._map.get(e)?.description?.[t];return n?Object.keys(n):[]}catch{return[]}}getKeyboard(e,t="default",s="default",n="inline",i){try{let a=this._map.get(e)?.keyboard?.[t],r=a?.[s]?.[n]||a?.default?.[n];if(!r)throw[];return r(i)}catch{return[]}}async write(e,t){if(this._getExtension(e)!=".html")return null;for(let s=0;s<this._path.length;s++){let n=R(this._path[s],e);if(D(n))return Ce(n,t,"utf8"),this._loadFile(e),!0}return null}has(e){return this._map.has(e)}async destroy(){if(this._watcher)for(let e of this._watcher)await e.close();this._map.clear()}};import{Bot as Ie,webhookCallback as ee}from"grammy";var K=class{constructor(e){this.maxSize=e;if(!Number.isFinite(e)||e<=0)throw new Error("WebhookQueue maxSize must be a positive number")}static{p(this,"WebhookQueue")}queue=[];waitEnqueue=[];waitDequeue=[];getStats(){return{length:this.queue.length,maxSize:this.maxSize,waitingEnqueue:this.waitEnqueue.length,waitingDequeue:this.waitDequeue.length}}get length(){return this.queue.length}async enqueue(e){if(this.queue.length>=this.maxSize&&await new Promise(t=>this.waitEnqueue.push(t)),this.waitDequeue.length>0){this.waitDequeue.shift()(e);return}this.queue.push(e)}async dequeue(){if(this.queue.length>0){let e=this.queue.shift();return this.waitEnqueue.shift()?.(),e}return await new Promise(e=>this.waitDequeue.push(e))}};var xe=ke((()=>{try{return f}catch{return Se(import.meta.url)}})()),_e=JSON.parse(be(se(xe,"../../package.json"),"utf-8")).version,te=class{static{p(this,"Gramstax")}templateManager;cacheKeyboard;cacheSession;pages;optionsPage={shortCallbackData:!1};log;bot;botConfig;webhookQueue;webhookQueueInstance;webhookServer;handlerBotUpdate;constructor(e){if(!e?.token||e?.token?.length==0)throw new Error("Token is not valid or empty");if(typeof e.optionsPage?.shortCallbackData=="boolean"&&(this.optionsPage.shortCallbackData=e.optionsPage.shortCallbackData),this.log=e.log===!0?H:e.log?e.log:void 0,this.log?.info?.(`Gramstax v${_e}`),this.cacheSession=e.cacheSession||new F("memory"),this.cacheKeyboard=e.cacheKeyboard||new Map,this.botConfig=e.botConfig,this.webhookQueue=e.webhookQueue,this.templateManager=e.templateManager||new W({path:[se(process.cwd(),"src","pages")]}),this.bot=this.createBot(e.token),this.bot.catch(this._onCatch),this._registerOnCallbackQueryData(),this._registerOnMessageText(),this._registerOnMessagePhoto(),this._registerOnMessageVideo(),this._registerOnMessageAudio(),this._registerOnMessageDocument(),this._registerOnMessageAnimation(),this._registerOnMessageVoice(),this._registerOnMessageVideoNote(),this._registerOnMessageSticker(),this._registerOnMessageLocation(),this._registerOnMessageContact(),this.handlerBotUpdate=this.bot.handleUpdate,this.pages=this._pageLoads(),process.once("SIGINT",()=>this.bot.stop()),process.once("SIGTERM",()=>this.bot.stop()),this.hookBeforeStart(),e.deploy.startsWith("polling"))this._runPolling();else if(e.deploy.startsWith("webhook:"))this._runWebhook(e.deploy.split("webhook:")[1]);else if(e.deploy.startsWith("serverless:"))this._runServerless(e.deploy.split("serverless:")[1]);else if(!e.deploy.startsWith("test"))throw new Error("Params deploy is not valid, expected: polling, webhook:<public-url>, serverless:<your-adapter>")}_onCatch(e){if(this.log?.errorMake)this.log?.errorMake(e,"Bot","catch");else{let t=JSON.stringify(e,null,2);this.log?.error?.(`[Bot.catch]: ${t}`)}}hookBeforeStart(){}hookAfterStart(){}async _onStart(e,t,s){await this.executeSyncBlocksDescription(this.pages);let{username:n}=e;this.log?.success?.(`Telegram bot polling started: ${n} ${t=="webhook"||t=="serverless"?`(${s})`:""}`),this.hookAfterStart()}createBot(e){return new Ie(e,this.botConfig)}createCtx(e){return new B({ct:e,cacheSession:this.cacheSession,cacheKeyboard:this.cacheKeyboard,templateManager:this.templateManager,temp:{isAnswer:!1,session:{},data:{}}})}_runPolling(){this.bot.start({drop_pending_updates:!0,onStart:p(e=>{this._onStart(e,"polling",null)},"onStart")})}async _runWebhook(e){let{serve:t}=await import("bun"),s=ee(this.bot,"bun"),n=this.webhookQueue,i=n?.enabled===!0;this.handlerBotUpdate=i?this.bot.handleUpdate.bind(this.bot):s;let o=i?new K(n?.maxQueueSize??5e3):void 0,a=n?.workerCount??8,r=n?.perChatConcurrency??1,c=n?.blockWhenFull!==!1,l=new Map,d=new Map;this.webhookQueueInstance=o;let h=p(y=>y?.message?.chat?.id??y?.edited_message?.chat?.id??y?.channel_post?.chat?.id??y?.edited_channel_post?.chat?.id??y?.callback_query?.message?.chat?.id??y?.callback_query?.from?.id??y?.inline_query?.from?.id??y?.chosen_inline_result?.from?.id,"getChatId"),m=p(async y=>{if(!i||r<=0||y===void 0||y===null)return()=>{};let S=String(y),b=l.get(S)||0;if(b<r)return l.set(S,b+1),()=>this._releaseWebhookChat(S,l,d);await new Promise(he=>{let G=d.get(S)||[];G.push(he),d.set(S,G)});let P=(l.get(S)||0)+1;return l.set(S,P),()=>this._releaseWebhookChat(S,l,d)},"acquireChat");if(i&&o){await this.bot.init();for(let y=0;y<a;y++)this._startWebhookWorker(o,m,h)}let u=new URL(e).pathname,I=this.log,T="/stats_queue";this.webhookServer?.stop();let w=t({async fetch(y){let{pathname:S}=new URL(y.url);if(y.method=="POST"&&S==u){if(!i||!o)return s(y);if(!c&&o.length>=(n?.maxQueueSize??5e3))return new Response("Queue full",{status:429});try{let b=await y.json();return await o.enqueue(b),new Response("OK",{status:200})}catch(b){return I?.error?.(`Webhook queue error: ${String(b)}`),new Response("Bad Request",{status:400})}}if(y.method=="GET"&&S==T){let b=o?.getStats()||{length:0,maxSize:n?.maxQueueSize??5e3,waitingEnqueue:0,waitingDequeue:0};return new Response(JSON.stringify({enabled:i,path:T,timestamp:new Date().toISOString(),maxQueueSize:n?.maxQueueSize??5e3,workerCount:a,perChatConcurrency:r,blockWhenFull:c,queue:b,activeChats:l.size}),{status:200,headers:{"Content-Type":"application/json"}})}if(y.method=="GET"&&S=="/"){let b=new Date().toISOString();return new Response(JSON.stringify({status:"OK",timestamp:b}),{status:200,headers:{"Content-Type":"application/json"}})}return new Response("Not found",{status:404})}});this.webhookServer=w;let k=p(()=>{this.webhookServer?.stop(),this.webhookServer=void 0},"stopServer");process.once("SIGINT",k),process.once("SIGTERM",k),(await this.bot.api.getWebhookInfo()).url!=e&&await this.bot.api.setWebhook(e);let v=await this.bot.api.getMe();await this._onStart(v,"webhook",e)}_startWebhookWorker(e,t,s){p(async()=>{for(;;){let i=await e.dequeue(),o=await t(s(i));try{await this.bot.handleUpdate(i)}catch(a){this.log?.error?.(`Webhook worker error: ${String(a)}`)}finally{o()}}},"run")()}_releaseWebhookChat(e,t,s){let n=t.get(e)||0,i=Math.max(0,n-1);i===0?t.delete(e):t.set(e,i);let o=s.get(e);o&&o.length>0&&(o.shift()(),o.length===0&&s.delete(e))}getWebhookQueueStats(){if(!this.webhookQueue?.enabled||!this.webhookQueueInstance)return null;let e=this.webhookQueueInstance.getStats(),t=this.webhookQueue.maxQueueSize??5e3,s=this.webhookQueue.workerCount??8,n=this.webhookQueue.perChatConcurrency??1,i=this.webhookQueue.blockWhenFull!==!1;return{enabled:!0,maxQueueSize:t,workerCount:s,perChatConcurrency:n,blockWhenFull:i,...e}}async _runServerless(e){this.handlerBotUpdate=ee(this.bot,e);let t=await this.bot.api.getMe();await this._onStart(t,"serverless",e)}_pageBuildData(e,t){e?.data===void 0&&(e.data=e.buildData());let{name:s}=we(t);e.data.name||(e.data.name=s),e.data.intentText||(e.data.intentText=e.data.name),e.data.intentCommandText||(e.data.intentCommandText=e.data.name),e.data.intentCallbackData||(e.data.intentCallbackData=e.data.name)}_pageSorts(e,t,s){let n=e.data.name,i=e.prototype,o="handle",a="Args",r="Command",c="Caption",l="Free",d=t.routeDynamic,h=t.routeDynamicSpesific;t.all[n]=e;for(let m=0;m<t.lenListRouteStaticSession;m++){let u=t.listRouteStaticSession[m];if(typeof i[u]!="function")continue;let I=t.routeStatic[u],T=t.routeStaticIntent[u],w=t.routeStaticSession[u],k={name:n,routeName:u},x=I||T;if(x!==void 0){let v=u.includes(r),y=u.endsWith("CallbackData"),S=u.endsWith("Text"),b;if(v){let P=e.data.intentCommandText;b=P?`/${P}`:void 0}else if(y){let P=e.data.intentCallbackData;this.optionsPage.shortCallbackData===!0&&(P=String(s),e.data.intentCallbackData=P),b=P}else S?b=e.data.intentText:b=e.data.name;b&&(x[b]=k)}if(w!==void 0){let y=`methodSession${u.replace("handle","")}`,S=i[y]?.(n);w[S]=k}if(u.startsWith("handleFree")){let v=u.replace(o,"").replace(a,"").replace(r,"").replace(c,"").replace(l,"").toLowerCase();h[v].push(k)}}i.handleFree&&d.push(n)}async executeSyncBlocksDescription(e){let t=new Map,s=e.routeStatic.handleCommandText;for(let[,n]of Object.entries(s)){let i=n.name,o=this.templateManager.getDescriptionScopes(i);for(let a of o){t.has(a)||t.set(a,new Set);let r=this.templateManager.getDescriptionLanguage(i,"default",a);for(let c of r)t.get(a).add(c)}}for(let[n,i]of t)for(let o of i){let a=[];for(let[,l]of Object.entries(s)){let d=l.name,h=this.templateManager.getDescription(d,"default",o,n);h&&a.push({command:d,description:h})}if(a.length===0)continue;let r={type:n},c=o==="default"?void 0:o;try{let l=await this.bot.api.getMyCommands({scope:r,language_code:c}),d=JSON.stringify(l.map(m=>({command:m.command,description:m.description})).sort((m,u)=>m.command.localeCompare(u.command))),h=JSON.stringify(a.sort((m,u)=>m.command.localeCompare(u.command)));d!==h&&(await this.bot.api.setMyCommands(a,{scope:r,language_code:c}),this.log?.info?.(`Synced descriptions for scope: ${n},${c?` lang: ${c},`:""} total (${a.length})`))}catch(l){this.log?.error?.(`Failed to sync descriptions for scope: ${n},${c?` lang: ${c},`:""} error: ${String(l)}`)}}}_pageLoads(){this.log?.info?.("Load pages..");let e=["handleCallbackData","handleText","handleCommandText","handleCaptionPhoto","handleCommandCaptionPhoto","handleCaptionVideo","handleCommandCaptionVideo","handleCaptionAudio","handleCommandCaptionAudio","handleCaptionDocument","handleCommandCaptionDocument","handleCaptionAnimation","handleCommandCaptionAnimation","handleCaptionVoice","handleCommandCaptionVoice"],t=["handleArgsCallbackData","handleArgsText","handleCommandArgsText","handleCaptionArgsPhoto","handleCommandCaptionArgsPhoto","handleCaptionArgsVideo","handleCommandCaptionArgsVideo","handleCaptionArgsAudio","handleCommandCaptionArgsAudio","handleCaptionArgsDocument","handleCommandCaptionArgsDocument","handleCaptionArgsAnimation","handleCommandCaptionArgsAnimation","handleCaptionArgsVoice","handleCommandCaptionArgsAnimation"],s=[...e,...t,"handleFreeText","handleFreePhoto","handleFreeVideo","handleFreeAudio","handleFreeDocument","handleFreeAnimation","handleFreeVoice","handleFreeVideoNote","handleFreeSticker","handleFreeLocation","handleFreeContact"],n=p((a,r)=>Object.fromEntries(a.map(c=>[c,r()])),"makeObject"),i=p(()=>[],"initDynamicSpesific"),o={all:{},routeDynamic:[],routeDynamicSpesific:{text:i(),photo:i(),video:i(),audio:i(),document:i(),animation:i(),voice:i(),videoNote:i(),sticker:i(),location:i(),contact:i()},routeStatic:n(e,()=>({})),routeStaticIntent:n(t,()=>({})),routeStaticSession:n(s,()=>({})),listRouteStatic:e,listRouteStaticIntent:t,listRouteStaticSession:s,lenListRouteStatic:e.length,lenListRouteStaticIntent:t.length,lenListRouteStaticSession:s.length};return _.getFileManySync(void 0).forEach(({path:a,page:r},c)=>{this._pageBuildData(r,a),this._pageSorts(r,o,c),r.template=void 0}),this.log?.info?.(`Finish load pages with total (${Object.keys(o.all).length})`),o}async _pageRoutes(e,t){let s,n;if(s===void 0){let o=await e.getSession();if(o){let a=o.method,r=this.pages.routeStaticSession,c=e.callbackData,l=e.msgText,d=e.msgCaption,h=c||l||d,m=t==="callbackdata",u=m?"colon":"space",I=h&&e.haveArgs(h,u)?e.getIntent(h,u,1):void 0,T=!m&&h?e.getIntent(h,"space",2):void 0;for(let w=0;w<this.pages.lenListRouteStaticSession;w++){let k=this.pages.listRouteStaticSession[w];if(k.toLowerCase().endsWith(t)){if(h){if(this.pages.routeStatic[k]?.[h])continue;let x=this.pages.routeStaticIntent[k];if(x&&(I&&x[I]||T&&x[T]))continue}n=r[k][a]}if(n)break}n!==void 0&&(s=this.pages.all[n.name])}}if(s===void 0){let o=e.callbackData,a=e.msgText,r=e.msgCaption,c=this.pages.routeStatic;for(let l=0;l<this.pages.lenListRouteStatic;l++){let d=this.pages.listRouteStatic[l];if(d.toLowerCase().endsWith(t)&&(n=c[d][o||a||r]),n)break}n!==void 0&&(s=this.pages.all[n.name])}if(s===void 0){let o=this.pages.routeStaticIntent,a=t==="callbackdata",r=a?"colon":"space",c=a?e.callbackData:e.msgText||e.msgCaption,l=e.haveArgs(c,r);if(c&&l)for(let d=0;d<this.pages.lenListRouteStaticIntent;d++){let h=this.pages.listRouteStaticIntent[d];if(!h.toLowerCase().endsWith(t))continue;let m=o[h];if(n=m[e.getIntent(c,r,1)],!n&&!a&&(n=m[e.getIntent(c,"space",2)]),n)break}n!==void 0&&(s=this.pages.all[n.name])}if(s!==void 0&&n!==void 0){if(!s.prototype[n.routeName])return;let a=await new s(e)[n.routeName]?.();return e.temp.isAnswer===!0?a:null}let i=this.pages.routeDynamicSpesific[t]||[];for(let o=0;o<i.length;o++){let a=i[o];if(a===void 0)continue;let r=this.pages.all[a.name];r!==void 0&&typeof r.prototype[a.routeName]=="function"&&await new r(e)[a.routeName]()}for(let o=0;o<this.pages.routeDynamic.length;o++){let a=this.pages.routeDynamic[o];if(a===void 0)continue;let r=this.pages.all[a];r!==void 0&&typeof r.prototype.handleFree=="function"&&await new r(e).handleFree()}if(e.temp.isAnswer===!1)return null}async hookBeforeRoute(e,t){return!!(e||t)}async hookErrorPage(e,t,s,n){}async hookErrorInputNotFoundPage(e){}async _onMessage(e,t){let s=this.createCtx(e);try{if(await this.hookBeforeRoute(s,t)===!1)return;await this._pageRoutes(s,t)===null&&await this.hookErrorInputNotFoundPage(s)}catch(n){await this.hookErrorPage(s,t,n,!1)}}async _onCallbackQueryData(e){let t=this.createCtx(e);try{if(await this.hookBeforeRoute(t,"onCallbackQueryData")===!1)return;await this._pageRoutes(t,"callbackdata")}catch(s){await this.hookErrorPage(t,"onCallbackQueryData",s,!0)}}async _onMessageText(e){await this._onMessage(e,"text")}async _onMessagePhoto(e){await this._onMessage(e,"photo")}async _onMessageVideo(e){await this._onMessage(e,"video")}async _onMessageAudio(e){await this._onMessage(e,"audio")}async _onMessageDocument(e){await this._onMessage(e,"document")}async _onMessageAnimation(e){await this._onMessage(e,"animation")}async _onMessageVoice(e){await this._onMessage(e,"voice")}async _onMessageVideoNote(e){await this._onMessage(e,"videoNote")}async _onMessageSticker(e){await this._onMessage(e,"sticker")}async _onMessageLocation(e){await this._onMessage(e,"location")}async _onMessageContact(e){await this._onMessage(e,"contact")}_registerOnCallbackQueryData(){this.bot.on("callback_query:data",this._onCallbackQueryData.bind(this))}_registerOnMessageText(){this.bot.on("message:text",this._onMessageText.bind(this))}_registerOnMessagePhoto(){this.bot.on("message:photo",this._onMessagePhoto.bind(this))}_registerOnMessageVideo(){this.bot.on("message:video",this._onMessageVideo.bind(this))}_registerOnMessageAudio(){this.bot.on("message:audio",this._onMessageAudio.bind(this))}_registerOnMessageDocument(){this.bot.on("message:document",this._onMessageDocument.bind(this))}_registerOnMessageAnimation(){this.bot.on("message:animation",this._onMessageAnimation.bind(this))}_registerOnMessageVoice(){this.bot.on("message:voice",this._onMessageVoice.bind(this))}_registerOnMessageVideoNote(){this.bot.on("message:video_note",this._onMessageVideoNote.bind(this))}_registerOnMessageSticker(){this.bot.on("message:sticker",this._onMessageSticker.bind(this))}_registerOnMessageLocation(){this.bot.on("message:location",this._onMessageLocation.bind(this))}_registerOnMessageContact(){this.bot.on("message:contact",this._onMessageContact.bind(this))}};var ne=class{static{p(this,"BlockKeyboard")}static label;static _build(e,t,s,n){if(!this.label)throw new Error("Label not found, make sure set this.label from class extends LabelKeyboard");s||(s="inline");let i=this.label[e];if(!i)throw new Error(`Object value ${e} not found`);let o=p((a,r)=>`<keyboard type="${s}" lang="${r}">${n?this.label._reverse(a):a}</keyboard>`,"pro");return t?o(i[t],t):Object.keys(i).map(a=>o(i[a],a)).join(" ")}};var ie=class{static{p(this,"LabelKeyboard")}static _reverse(e){return e.split(/(?<!\\), */).reverse().join(", ")}static _reverseObj(e){return Object.keys(e).reduce((t,s)=>(t[s]=this._reverse(e[s]),t),{})}};import{isMainThread as Ae,Worker as Me}from"worker_threads";var M=class{constructor(e,t){this.send=e;this.register=t}static{p(this,"WorkerThreadRpc")}map=new Map;async make(e){let t=this.map,s=this.send,{id:n,method:i,params:o,result:a,error:r}=e;if(i!==void 0)try{let c=this.register[i];if(typeof c!="function")throw new Error(`Method ${i} not found or not function`);let l=await c.apply(this.register,o);s({id:n,result:l})}catch(c){s({id:n,error:c instanceof Error?{message:c.message,stack:c.stack,name:c.name}:c})}else if(a!==void 0){let c=t.get(n);c&&(c.resolve(a),t.delete(n))}else if(r!==void 0){let c=t.get(n);c&&(c.reject(r),t.delete(n))}}makeId(){return Math.random()}makeRequest(e,t,s=!0,n){let i=this.makeId(),o={id:i,method:e,params:t,...n};return s?new Promise((a,r)=>{this.map.set(i,{resolve:a,reject:r}),this.send(o)}):this.send(o)}};var $=class{constructor(e,t,s){this.path=e;this.argv=t;this.register=s;this.init(),s||(s=this),this.rpc=new M(this.send.bind(this),s)}static{p(this,"WorkerThreadLaunch")}static isMainThread=Ae;_readyResolve;_readyPromise=new Promise(e=>this._readyResolve=e);pid=process.pid;thread={};threadId={};rpc={};ready(){return this._readyPromise}readyResolve(){this._readyResolve?.()}init(){this.thread=new Me(this.path,{argv:this.argv.length==0&&this.argv[0]===void 0?void 0:this.argv}),this.threadId=this.thread.threadId,this.thread.on("message",e=>this.handleOnMessage(e)),this.thread.on("exit",()=>this.kill()),process.once("SIGINT",()=>this.kill()),process.once("SIGTERM",()=>this.kill())}async handleOnMessage(e){this.rpc.make(e)}kill(){this.thread.terminate()}send(e){this.thread.postMessage(e)}async request(e,t,s=!0,n){return this.rpc.makeRequest(e,t,s,n)}};var oe=class g{static{p(this,"WorkerThreadExport")}static launchGatewayClient(e){let t=new Proxy({},{get(n,i){if(!(typeof i!="string"||i==="then"))return async(o,...a)=>{let r=o.gatewayClients.get(e);return r||(r=await o.createGatewayClient(e)),r.request(i,a)}}}),s=p(function(n){return new Proxy({},{get(i,o){if(!(typeof o!="string"||o==="then"))return async(...a)=>{let r=n.gatewayClients.get(e);return r||(r=await n.createGatewayClient(e)),r.request(o,a)}}})},"ctor");return Object.setPrototypeOf(s,t),s}static init(e){let{WTInit:t,WTLaunch:s=$,path:n,wrap:i}=e,o=`for-${n}`;if(process.argv[2]===o)return new t,{launchGatewayClient:p(d=>g.launchGatewayClient(d||t.gatewayServerPath),"launchGatewayClient")};let a,r=new Proxy({},{get(d,h){if(h!=="then")return h==="sendRequest"||h==="request"||h==="kill"||h==="send"?(...m)=>{if(!a)throw new Error(`Thread at ${n} not launched yet.`);return a[h](...m)}:(...m)=>{if(!a)throw new Error(`Thread at ${n} not launched yet.`);return a.request(h,m)}}}),l={...i?i(r):{},launchWorker:p(async(d=[])=>(a=new s(n,[o,...d]),await a.ready(),a),"launchWorker"),launchGatewayClient:p(d=>g.launchGatewayClient(d||t.gatewayServerPath),"launchGatewayClient")};return new Proxy(l,{get(d,h){if(h!=="then")return h==="launchGatewayClient"?d.launchGatewayClient:h==="launchWorker"?d.launchWorker:h in d?d[h]:typeof h=="string"?(...m)=>{if(!a)throw new Error(`Thread at ${n} not launched yet.`);return a.request(h,m)}:d[h]}})}};import{Client as Pe}from"net-ipc";var E=class{static{p(this,"WorkerThreadGatewayClient")}client=new Pe;rpc;constructor(){this.rpc=new M(e=>this.client.send(e),{}),this.client.on("message",e=>{this.rpc.make(e)})}async connect(e){this.client.options.path=e;let t=new Promise(s=>{this.client.once("ready",()=>s(this))});return await this.client.connect(),t}async request(e,t,s=!0,n){return this.rpc.makeRequest(e,t,s,n)}};import{Server as Re}from"net-ipc";var L=class{static{p(this,"WorkerThreadGatewayServer")}server=new Re;rpc=new Map;register={};constructor(){this.server.on("connect",e=>{let t=new M(s=>e.send(s),this.register);this.rpc.set(e.id,t)}),this.server.on("disconnect",e=>{this.rpc.delete(e.id)}),this.server.on("message",(e,t)=>{let s=this.rpc.get(t.id);s&&s.make(e)}),this.server.on("error",e=>{console.error(e)})}async start(e,t={}){this.register=t,this.server.options.path=e;let s=new Promise(n=>{this.server.once("ready",()=>n(this))});return await this.server.start(),s}};import{parentPort as ve,threadId as De,isMainThread as Oe}from"worker_threads";var ae=class{static{p(this,"WorkerThreadInit")}argv=process.argv;id=De;pid=process.pid;rpc={};parentPort=ve;gatewayServer;gatewayClients=new Map;gatewayClientLatest;static gatewayServerPath;gatewayServerPath=this.constructor.gatewayServerPath;get gatewayClient(){return this.gatewayClientLatest}static isMainThread=Oe;constructor(){this.init(),this.rpc=new M(this.send.bind(this),this),this.send({method:"readyResolve"})}init(){this.parentPort?.on("message",e=>this.handleOnMessage(e))}handleOnMessage(e){this.rpc.make(e)}send(e){this.parentPort?.postMessage(e)}request(e,t,s=!0,n){return this.rpc.makeRequest(e,t,s,n)}async createGatewayServer(e,t){return e||(e=this),t||(t=this.constructor.gatewayServerPath),this.gatewayServer=new L,await this.gatewayServer.start(t,e),this.constructor.gatewayServerPath=t,!0}async createGatewayClient(e){let t=new E;return await t.connect(e),this.gatewayClients.set(e,t),this.gatewayClientLatest=t,t}};var re=class{static{p(this,"WorkerThreadPool")}thread=new Map;threadCount=0;constructor(e){this.addMany(e)}add(e){this.thread.set(e.threadId,e),this.threadCount+=1}addMany(e){e.forEach(t=>this.add(t))}getInstance(e){return this.thread.get(e)}kill(e){let t=this.thread.get(e);return t?.kill(),this.thread.delete(e),this.threadCount-=1,t?.threadId}killAll(){this.thread.values().forEach(({threadId:e})=>this.kill(e))}async broadcastRequest(e,t){return await Promise.all(Object.values(this.thread).map(s=>s.request(e,t,!0)))}async request(e,t,s,n=!0,i){return await this.thread.get(e)?.request(t,s,n,i)}};var ce=class{static{p(this,"MockTelegramServer")}token;hostname;port;handlers;defaultHandler;apiRoot="";server;constructor(e){this.token=e.token,this.hostname=e.hostname??"127.0.0.1",this.port=e.port??0,this.handlers=e.handlers??{},this.defaultHandler=e.defaultHandler}async start(){if(this.server)return this.apiRoot;let e=Bun.serve({port:this.port,hostname:this.hostname,fetch:p(async t=>this._handleRequest(t),"fetch")});return this.server=e,this.apiRoot=`http://${this.hostname}:${e.port??this.port}`,this.apiRoot}async stop(){this.server?.stop(),this.server=void 0}_json(e){return new Response(JSON.stringify(e),{status:200,headers:{"Content-Type":"application/json"}})}_defaultResponse(e){return e==="getMe"?{ok:!0,result:{id:123456789,is_bot:!0,first_name:"Mock",username:"mock_gramstax_bot"}}:e==="getUpdates"?{ok:!0,result:[]}:e==="getMyCommands"?{ok:!0,result:[]}:e==="setMyCommands"?{ok:!0,result:!0}:e==="setWebhook"?{ok:!0,result:!0}:e==="getWebhookInfo"?{ok:!0,result:{url:""}}:{ok:!0,result:!0}}async _handleRequest(e){let{pathname:t}=new URL(e.url),s=`/bot${this.token}/`;if(!t.startsWith(s))return new Response("Not found",{status:404});let n=t.slice(s.length),i=this.handlers[n]??this.defaultHandler,o=i?await i({method:n,request:e}):this._defaultResponse(n);return this._json(o)}};export{ne as BlockKeyboard,F as CacheExternal,B as Ctx,te as Gramstax,ie as LabelKeyboard,j as LoggingHelper,ce as MockTelegramServer,_ as PageManager,A as TemplateEngine,W as TemplateManager,K as WebhookQueue,oe as WorkerThreadExport,E as WorkerThreadGatewayClient,L as WorkerThreadGatewayServer,ae as WorkerThreadInit,$ as WorkerThreadLaunch,re as WorkerThreadPool,M as WorkerThreadRpc,H as log};
7
+ `);a=a.replace(`__IMPORT_${r}__`,h)}return a}};var W=class{static{p(this,"TemplateManager")}_map=new Map;_engine=A;_watcher=[];_pageManager=_;_supportedExtensions=new Set([".html",".ts",".js"]);_path;_isWatchEnabled;constructor(e){let{path:t,enableWatch:s=!1}=e;this._path=t,this._isWatchEnabled=s,this._validatePath(),this._initializeWatcher(e.watchOptions),this._loadAllFiles()}_validatePath(){try{if(!this._path||!Array.isArray(this._path))throw new Error("Path must be set as string array");for(let e=0;e<this._path.length;e++){let t=this._path[e];if(!D(t))throw new Error(`Template base path is not exists: ${t}`);if(!O(t).isDirectory())throw new Error(`Template base path is not a directory: ${t}`)}return!0}catch(e){throw new Error(`Failed to validate Template base path: ${String(e)}`)}}_initializeWatcher(e){if(this._isWatchEnabled){if(this._watcher.length>0)throw new Error("Watcher already enabled");for(let t=0;t<this._path.length;t++){let s=this._path[t],n=Te(s,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},...e});this._watcher[t]=n,n.on("change",this._handleFileChange.bind(this)),n.on("add",this._handleFileAdd.bind(this)),n.on("unlink",this._handleFileDelete.bind(this)),n.on("error",this._handleWatchError.bind(this))}}}_handleFileChange(e){let t=Q(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileAdd(e){let t=Q(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileDelete(e){let t=Q(e),s=this._getKey(t);this._map.has(s)&&this._map.delete(s)}_handleWatchError(e){}_loadAllFiles(){let e=new Map,t=[];for(let n=0;n<this._path.length;n++){let i=this._path[n],a=fe(i,"utf8").filter(r=>this._isValidFile(r));for(let r of a){let c=R(i,r),l=this._getExtension(r),d=this._getKey(r);if(l===".html")e.set(d,V(c,"utf8"));else if(l===".ts"||l===".js"){let h=_.getFileSync(c);h?.template!==void 0&&(e.set(d,h.template),t.push(h))}}}let s=new Map;for(let[n,i]of e.entries())this._compile(n,i,void 0,s,e);e.clear(),s.clear();for(let n of t)n.template=void 0}_loadFile(e){for(let t=0;t<this._path.length;t++){let s=this._path[t],n=R(s,e),i=this._getExtension(e),o=this._getKey(e);if(i==".html"){let a=V(n,"utf8");this._compile(o,a)}else if(i==".ts"||i==".js"){let a=_.getFileSync(n);a?.template!==void 0&&(this._compile(o,a.template),a.template=void 0)}else throw new Error(`File ${e} is not support`)}}_getExtension(e){return Z(e).toLowerCase()}_readTemplateFile(e){for(let t of this._path){let s=Z(e).toLowerCase();if(s){let a=R(t,e);if(D(a)&&O(a).isFile()){if(s===".html")return V(a,"utf8");if(s===".ts"||s===".js")try{return _.getFileSync(a)?.template??null}catch{return null}}continue}let n=R(t,`${e}.ts`),i=R(t,`${e}.js`);if(D(n)&&O(n).isFile())try{return _.getFileSync(n)?.template??null}catch{}else if(D(i)&&O(i).isFile())try{return _.getFileSync(n)?.template??null}catch{}let o=R(t,`${e}.html`);if(D(o)&&O(o).isFile())return V(o,"utf8")}return null}_isValidFile(e){return this._supportedExtensions.has(this._getExtension(e))}_getKey(e){return e.replace(/\.[^/.]+$/,"")}_compile(e,t,s,n,i){let o=this._map.get(e),a=o||{},r=!1,c=A.processImportBlocks(t,d=>i&&i.has(d)?i.get(d):this._readTemplateFile(d),0,n),l=A._processBaseBlocks(c);(s===void 0||s?.media===!1||o?.media===void 0)&&(a.media=A.compileBlockMedia(c,l),r=!0),(s===void 0||s?.message===!1||o?.message===void 0)&&(a.message=A.compileBlockMessage(c,l),r=!0),(s===void 0||s?.keyboard===!1||o?.keyboard===void 0)&&(a.keyboard=A.compileBlockKeyboards(c,l),r=!0),(s===void 0||s?.description===!1||o?.description===void 0)&&(a.description=A.compileBlockDescription(c,l),r=!0),r&&this._map.set(e,a)}getMedia(e,t="default",s="default",n){let o=this._map.get(e)?.media?.[t],a=o?.[s]||o?.default;try{if(!a)throw new Error("Media function not found, please check your template");return a(n)}catch{return{}}}getMessage(e,t="default",s="default",n){try{let o=this._map.get(e)?.message?.[t],a=o?.[s]||o?.default;if(!a)throw"";return a(n)}catch{return""}}getDescription(e,t="default",s="default",n="default",i){try{let a=this._map.get(e)?.description?.[t]?.[n],r=a?.[s]||a?.default;if(!r)throw"";return r(i)}catch{return""}}getDescriptionLanguage(e,t="default",s="default"){try{let i=this._map.get(e)?.description?.[t]?.[s];return i?Object.keys(i):[]}catch{return[]}}getDescriptionScopes(e,t="default"){try{let n=this._map.get(e)?.description?.[t];return n?Object.keys(n):[]}catch{return[]}}getKeyboard(e,t="default",s="default",n="inline",i){try{let a=this._map.get(e)?.keyboard?.[t],r=a?.[s]?.[n]||a?.default?.[n];if(!r)throw[];return r(i)}catch{return[]}}async write(e,t){if(this._getExtension(e)!=".html")return null;for(let s=0;s<this._path.length;s++){let n=R(this._path[s],e);if(D(n))return Ce(n,t,"utf8"),this._loadFile(e),!0}return null}has(e){return this._map.has(e)}async destroy(){if(this._watcher)for(let e of this._watcher)await e.close();this._map.clear()}};import{Bot as Ie,webhookCallback as ee}from"grammy";var K=class{constructor(e){this.maxSize=e;if(!Number.isFinite(e)||e<=0)throw new Error("WebhookQueue maxSize must be a positive number")}static{p(this,"WebhookQueue")}queue=[];waitEnqueue=[];waitDequeue=[];getStats(){return{length:this.queue.length,maxSize:this.maxSize,waitingEnqueue:this.waitEnqueue.length,waitingDequeue:this.waitDequeue.length}}get length(){return this.queue.length}async enqueue(e){if(this.queue.length>=this.maxSize&&await new Promise(t=>this.waitEnqueue.push(t)),this.waitDequeue.length>0){this.waitDequeue.shift()(e);return}this.queue.push(e)}async dequeue(){if(this.queue.length>0){let e=this.queue.shift();return this.waitEnqueue.shift()?.(),e}return await new Promise(e=>this.waitDequeue.push(e))}};var xe=ke((()=>{try{return f}catch{return Se(import.meta.url)}})()),_e=JSON.parse(be(se(xe,"../../package.json"),"utf-8")).version,te=class{static{p(this,"Gramstax")}templateManager;cacheKeyboard;cacheSession;pages;optionsPage={shortCallbackData:!1};log;bot;botConfig;webhookQueue;webhookQueueInstance;webhookServer;handlerBotUpdate;constructor(e){if(!e?.token||e?.token?.length==0)throw new Error("Token is not valid or empty");if(typeof e.optionsPage?.shortCallbackData=="boolean"&&(this.optionsPage.shortCallbackData=e.optionsPage.shortCallbackData),this.log=e.log===!0?H:e.log?e.log:void 0,this.log?.info?.(`Gramstax v${_e}`),this.cacheSession=e.cacheSession||new F("memory"),this.cacheKeyboard=e.cacheKeyboard||new Map,this.botConfig=e.botConfig,this.webhookQueue=e.webhookQueue,this.templateManager=e.templateManager||new W({path:[se(process.cwd(),"src","pages")]}),this.bot=this.createBot(e.token),this.bot.catch(this._onCatch),this._registerOnCallbackQueryData(),this._registerOnMessageText(),this._registerOnMessagePhoto(),this._registerOnMessageVideo(),this._registerOnMessageAudio(),this._registerOnMessageDocument(),this._registerOnMessageAnimation(),this._registerOnMessageVoice(),this._registerOnMessageVideoNote(),this._registerOnMessageSticker(),this._registerOnMessageLocation(),this._registerOnMessageContact(),this.handlerBotUpdate=this.bot.handleUpdate,this.pages=this._pageLoads(),process.once("SIGINT",()=>this.bot.stop()),process.once("SIGTERM",()=>this.bot.stop()),this.hookBeforeStart(),e.deploy.startsWith("polling"))this._runPolling();else if(e.deploy.startsWith("webhook:"))this._runWebhook(e.deploy.split("webhook:")[1]);else if(e.deploy.startsWith("serverless:"))this._runServerless(e.deploy.split("serverless:")[1]);else if(!e.deploy.startsWith("test"))throw new Error("Params deploy is not valid, expected: polling, webhook:<public-url>, serverless:<your-adapter>")}_onCatch(e){if(this.log?.errorMake)this.log?.errorMake(e,"Bot","catch");else{let t=JSON.stringify(e,null,2);this.log?.error?.(`[Bot.catch]: ${t}`)}}hookBeforeStart(){}hookAfterStart(){}async _onStart(e,t,s){await this.executeSyncBlocksDescription(this.pages);let{username:n}=e;this.log?.success?.(`Telegram bot polling started: ${n} ${t=="webhook"||t=="serverless"?`(${s})`:""}`),this.hookAfterStart()}createBot(e){return new Ie(e,this.botConfig)}createCtx(e){return new B({ct:e,cacheSession:this.cacheSession,cacheKeyboard:this.cacheKeyboard,templateManager:this.templateManager,temp:{isAnswer:!1,session:{},data:{}}})}_runPolling(){this.bot.start({drop_pending_updates:!0,onStart:p(e=>{this._onStart(e,"polling",null)},"onStart")})}async _runWebhook(e){let{serve:t}=await import("bun"),s=ee(this.bot,"bun"),n=this.webhookQueue,i=n?.enabled===!0;this.handlerBotUpdate=i?this.bot.handleUpdate.bind(this.bot):s;let o=i?new K(n?.maxQueueSize??5e3):void 0,a=n?.workerCount??8,r=n?.perChatConcurrency??1,c=n?.blockWhenFull!==!1,l=new Map,d=new Map;this.webhookQueueInstance=o;let h=p(y=>y?.message?.chat?.id??y?.edited_message?.chat?.id??y?.channel_post?.chat?.id??y?.edited_channel_post?.chat?.id??y?.callback_query?.message?.chat?.id??y?.callback_query?.from?.id??y?.inline_query?.from?.id??y?.chosen_inline_result?.from?.id,"getChatId"),m=p(async y=>{if(!i||r<=0||y===void 0||y===null)return()=>{};let S=String(y),b=l.get(S)||0;if(b<r)return l.set(S,b+1),()=>this._releaseWebhookChat(S,l,d);await new Promise(he=>{let G=d.get(S)||[];G.push(he),d.set(S,G)});let P=(l.get(S)||0)+1;return l.set(S,P),()=>this._releaseWebhookChat(S,l,d)},"acquireChat");if(i&&o){await this.bot.init();for(let y=0;y<a;y++)this._startWebhookWorker(o,m,h)}let u=new URL(e).pathname,I=this.log,T="/stats_queue";this.webhookServer?.stop();let w=t({async fetch(y){let{pathname:S}=new URL(y.url);if(y.method=="POST"&&S==u){if(!i||!o)return s(y);if(!c&&o.length>=(n?.maxQueueSize??5e3))return new Response("Queue full",{status:429});try{let b=await y.json();return await o.enqueue(b),new Response("OK",{status:200})}catch(b){return I?.error?.(`Webhook queue error: ${String(b)}`),new Response("Bad Request",{status:400})}}if(y.method=="GET"&&S==T){let b=o?.getStats()||{length:0,maxSize:n?.maxQueueSize??5e3,waitingEnqueue:0,waitingDequeue:0};return new Response(JSON.stringify({enabled:i,path:T,timestamp:new Date().toISOString(),maxQueueSize:n?.maxQueueSize??5e3,workerCount:a,perChatConcurrency:r,blockWhenFull:c,queue:b,activeChats:l.size}),{status:200,headers:{"Content-Type":"application/json"}})}if(y.method=="GET"&&S=="/"){let b=new Date().toISOString();return new Response(JSON.stringify({status:"OK",timestamp:b}),{status:200,headers:{"Content-Type":"application/json"}})}return new Response("Not found",{status:404})}});this.webhookServer=w;let k=p(()=>{this.webhookServer?.stop(),this.webhookServer=void 0},"stopServer");process.once("SIGINT",k),process.once("SIGTERM",k),(await this.bot.api.getWebhookInfo()).url!=e&&await this.bot.api.setWebhook(e);let v=await this.bot.api.getMe();await this._onStart(v,"webhook",e)}_startWebhookWorker(e,t,s){p(async()=>{for(;;){let i=await e.dequeue(),o=await t(s(i));try{await this.bot.handleUpdate(i)}catch(a){this.log?.error?.(`Webhook worker error: ${String(a)}`)}finally{o()}}},"run")()}_releaseWebhookChat(e,t,s){let n=t.get(e)||0,i=Math.max(0,n-1);i===0?t.delete(e):t.set(e,i);let o=s.get(e);o&&o.length>0&&(o.shift()(),o.length===0&&s.delete(e))}getWebhookQueueStats(){if(!this.webhookQueue?.enabled||!this.webhookQueueInstance)return null;let e=this.webhookQueueInstance.getStats(),t=this.webhookQueue.maxQueueSize??5e3,s=this.webhookQueue.workerCount??8,n=this.webhookQueue.perChatConcurrency??1,i=this.webhookQueue.blockWhenFull!==!1;return{enabled:!0,maxQueueSize:t,workerCount:s,perChatConcurrency:n,blockWhenFull:i,...e}}async _runServerless(e){this.handlerBotUpdate=ee(this.bot,e);let t=await this.bot.api.getMe();await this._onStart(t,"serverless",e)}_pageBuildData(e,t){e?.data===void 0&&(e.data=e.buildData());let{name:s}=we(t);e.data.name||(e.data.name=s),e.data.intentText||(e.data.intentText=e.data.name),e.data.intentCommandText||(e.data.intentCommandText=e.data.name),e.data.intentCallbackData||(e.data.intentCallbackData=e.data.name)}_pageSorts(e,t,s){let n=e.data.name,i=e.prototype,o="handle",a="Args",r="Command",c="Caption",l="Free",d=t.routeDynamic,h=t.routeDynamicSpesific;t.all[n]=e;for(let m=0;m<t.lenListRouteStaticSession;m++){let u=t.listRouteStaticSession[m];if(typeof i[u]!="function")continue;let I=t.routeStatic[u],T=t.routeStaticIntent[u],w=t.routeStaticSession[u],k={name:n,routeName:u},x=I||T;if(x!==void 0){let v=u.includes(r),y=u.endsWith("CallbackData"),S=u.endsWith("Text"),b;if(v){let P=e.data.intentCommandText;b=P?`/${P}`:void 0}else if(y){let P=e.data.intentCallbackData;this.optionsPage.shortCallbackData===!0&&(P=String(s),e.data.intentCallbackData=P),b=P}else S?b=e.data.intentText:b=e.data.name;b&&(x[b]=k)}if(w!==void 0){let y=`methodSession${u.replace("handle","")}`,S=i[y]?.(n);w[S]=k}if(u.startsWith("handleFree")){let v=u.replace(o,"").replace(a,"").replace(r,"").replace(c,"").replace(l,"").toLowerCase();h[v].push(k)}}i.handleFree&&d.push(n)}async executeSyncBlocksDescription(e){let t=new Map,s=e.routeStatic.handleCommandText;for(let[,n]of Object.entries(s)){let i=n.name,o=this.templateManager.getDescriptionScopes(i);for(let a of o){t.has(a)||t.set(a,new Set);let r=this.templateManager.getDescriptionLanguage(i,"default",a);for(let c of r)t.get(a).add(c)}}for(let[n,i]of t)for(let o of i){let a=[];for(let[,l]of Object.entries(s)){let d=l.name,h=this.templateManager.getDescription(d,"default",o,n);h&&a.push({command:d,description:h})}if(a.length===0)continue;let r={type:n},c=o==="default"?void 0:o;try{let l=await this.bot.api.getMyCommands({scope:r,language_code:c}),d=JSON.stringify(l.map(m=>({command:m.command,description:m.description})).sort((m,u)=>m.command.localeCompare(u.command))),h=JSON.stringify(a.sort((m,u)=>m.command.localeCompare(u.command)));d!==h&&(await this.bot.api.setMyCommands(a,{scope:r,language_code:c}),this.log?.info?.(`Synced descriptions for scope: ${n},${c?` lang: ${c},`:""} total (${a.length})`))}catch(l){this.log?.error?.(`Failed to sync descriptions for scope: ${n},${c?` lang: ${c},`:""} error: ${String(l)}`)}}}_pageLoads(){this.log?.info?.("Load pages..");let e=["handleCallbackData","handleText","handleCommandText","handleCaptionPhoto","handleCommandCaptionPhoto","handleCaptionVideo","handleCommandCaptionVideo","handleCaptionAudio","handleCommandCaptionAudio","handleCaptionDocument","handleCommandCaptionDocument","handleCaptionAnimation","handleCommandCaptionAnimation","handleCaptionVoice","handleCommandCaptionVoice"],t=["handleArgsCallbackData","handleArgsText","handleCommandArgsText","handleCaptionArgsPhoto","handleCommandCaptionArgsPhoto","handleCaptionArgsVideo","handleCommandCaptionArgsVideo","handleCaptionArgsAudio","handleCommandCaptionArgsAudio","handleCaptionArgsDocument","handleCommandCaptionArgsDocument","handleCaptionArgsAnimation","handleCommandCaptionArgsAnimation","handleCaptionArgsVoice","handleCommandCaptionArgsAnimation"],s=[...e,...t,"handleFreeText","handleFreePhoto","handleFreeVideo","handleFreeAudio","handleFreeDocument","handleFreeAnimation","handleFreeVoice","handleFreeVideoNote","handleFreeSticker","handleFreeLocation","handleFreeContact"],n=p((a,r)=>Object.fromEntries(a.map(c=>[c,r()])),"makeObject"),i=p(()=>[],"initDynamicSpesific"),o={all:{},routeDynamic:[],routeDynamicSpesific:{text:i(),photo:i(),video:i(),audio:i(),document:i(),animation:i(),voice:i(),videonote:i(),sticker:i(),location:i(),contact:i()},routeStatic:n(e,()=>({})),routeStaticIntent:n(t,()=>({})),routeStaticSession:n(s,()=>({})),listRouteStatic:e,listRouteStaticIntent:t,listRouteStaticSession:s,lenListRouteStatic:e.length,lenListRouteStaticIntent:t.length,lenListRouteStaticSession:s.length};return _.getFileManySync(void 0).forEach(({path:a,page:r},c)=>{this._pageBuildData(r,a),this._pageSorts(r,o,c),r.template=void 0}),this.log?.info?.(`Finish load pages with total (${Object.keys(o.all).length})`),o}async _pageRoutes(e,t){let s,n;if(s===void 0){let o=await e.getSession();if(o){let a=o.method,r=this.pages.routeStaticSession,c=e.callbackData,l=e.msgText,d=e.msgCaption,h=c||l||d,m=t==="callbackdata",u=m?"colon":"space",I=h&&e.haveArgs(h,u)?e.getIntent(h,u,1):void 0,T=!m&&h?e.getIntent(h,"space",2):void 0;for(let w=0;w<this.pages.lenListRouteStaticSession;w++){let k=this.pages.listRouteStaticSession[w];if(k.toLowerCase().endsWith(t)){if(h){if(this.pages.routeStatic[k]?.[h])continue;let x=this.pages.routeStaticIntent[k];if(x&&(I&&x[I]||T&&x[T]))continue}n=r[k][a]}if(n)break}n!==void 0&&(s=this.pages.all[n.name])}}if(s===void 0){let o=e.callbackData,a=e.msgText,r=e.msgCaption,c=this.pages.routeStatic;for(let l=0;l<this.pages.lenListRouteStatic;l++){let d=this.pages.listRouteStatic[l];if(d.toLowerCase().endsWith(t)&&(n=c[d][o||a||r]),n)break}n!==void 0&&(s=this.pages.all[n.name])}if(s===void 0){let o=this.pages.routeStaticIntent,a=t==="callbackdata",r=a?"colon":"space",c=a?e.callbackData:e.msgText||e.msgCaption,l=e.haveArgs(c,r);if(c&&l)for(let d=0;d<this.pages.lenListRouteStaticIntent;d++){let h=this.pages.listRouteStaticIntent[d];if(!h.toLowerCase().endsWith(t))continue;let m=o[h];if(n=m[e.getIntent(c,r,1)],!n&&!a&&(n=m[e.getIntent(c,"space",2)]),n)break}n!==void 0&&(s=this.pages.all[n.name])}if(s!==void 0&&n!==void 0){if(!s.prototype[n.routeName])return;let a=await new s(e)[n.routeName]?.();return e.temp.isAnswer===!0?a:null}let i=this.pages.routeDynamicSpesific[t]||[];for(let o=0;o<i.length;o++){let a=i[o];if(a===void 0)continue;let r=this.pages.all[a.name];r!==void 0&&typeof r.prototype[a.routeName]=="function"&&await new r(e)[a.routeName]()}for(let o=0;o<this.pages.routeDynamic.length;o++){let a=this.pages.routeDynamic[o];if(a===void 0)continue;let r=this.pages.all[a];r!==void 0&&typeof r.prototype.handleFree=="function"&&await new r(e).handleFree()}if(e.temp.isAnswer===!1)return null}async hookBeforeRoute(e,t){return!!(e||t)}async hookErrorPage(e,t,s,n){}async hookErrorInputNotFoundPage(e){}async _onMessage(e,t){let s=this.createCtx(e);try{if(await this.hookBeforeRoute(s,t)===!1)return;await this._pageRoutes(s,t)===null&&await this.hookErrorInputNotFoundPage(s)}catch(n){await this.hookErrorPage(s,t,n,!1)}}async _onCallbackQueryData(e){let t=this.createCtx(e);try{if(await this.hookBeforeRoute(t,"onCallbackQueryData")===!1)return;await this._pageRoutes(t,"callbackdata")}catch(s){await this.hookErrorPage(t,"onCallbackQueryData",s,!0)}}async _onMessageText(e){await this._onMessage(e,"text")}async _onMessagePhoto(e){await this._onMessage(e,"photo")}async _onMessageVideo(e){await this._onMessage(e,"video")}async _onMessageAudio(e){await this._onMessage(e,"audio")}async _onMessageDocument(e){await this._onMessage(e,"document")}async _onMessageAnimation(e){await this._onMessage(e,"animation")}async _onMessageVoice(e){await this._onMessage(e,"voice")}async _onMessageVideoNote(e){await this._onMessage(e,"videonote")}async _onMessageSticker(e){await this._onMessage(e,"sticker")}async _onMessageLocation(e){await this._onMessage(e,"location")}async _onMessageContact(e){await this._onMessage(e,"contact")}_registerOnCallbackQueryData(){this.bot.on("callback_query:data",this._onCallbackQueryData.bind(this))}_registerOnMessageText(){this.bot.on("message:text",this._onMessageText.bind(this))}_registerOnMessagePhoto(){this.bot.on("message:photo",this._onMessagePhoto.bind(this))}_registerOnMessageVideo(){this.bot.on("message:video",this._onMessageVideo.bind(this))}_registerOnMessageAudio(){this.bot.on("message:audio",this._onMessageAudio.bind(this))}_registerOnMessageDocument(){this.bot.on("message:document",this._onMessageDocument.bind(this))}_registerOnMessageAnimation(){this.bot.on("message:animation",this._onMessageAnimation.bind(this))}_registerOnMessageVoice(){this.bot.on("message:voice",this._onMessageVoice.bind(this))}_registerOnMessageVideoNote(){this.bot.on("message:video_note",this._onMessageVideoNote.bind(this))}_registerOnMessageSticker(){this.bot.on("message:sticker",this._onMessageSticker.bind(this))}_registerOnMessageLocation(){this.bot.on("message:location",this._onMessageLocation.bind(this))}_registerOnMessageContact(){this.bot.on("message:contact",this._onMessageContact.bind(this))}};var ne=class{static{p(this,"BlockKeyboard")}static label;static _build(e,t,s,n){if(!this.label)throw new Error("Label not found, make sure set this.label from class extends LabelKeyboard");s||(s="inline");let i=this.label[e];if(!i)throw new Error(`Object value ${e} not found`);let o=p((a,r)=>`<keyboard type="${s}" lang="${r}">${n?this.label._reverse(a):a}</keyboard>`,"pro");return t?o(i[t],t):Object.keys(i).map(a=>o(i[a],a)).join(" ")}};var ie=class{static{p(this,"LabelKeyboard")}static _reverse(e){return e.split(/(?<!\\), */).reverse().join(", ")}static _reverseObj(e){return Object.keys(e).reduce((t,s)=>(t[s]=this._reverse(e[s]),t),{})}};import{isMainThread as Ae,Worker as Me}from"worker_threads";var M=class{constructor(e,t){this.send=e;this.register=t}static{p(this,"WorkerThreadRpc")}map=new Map;async make(e){let t=this.map,s=this.send,{id:n,method:i,params:o,result:a,error:r}=e;if(i!==void 0)try{let c=this.register[i];if(typeof c!="function")throw new Error(`Method ${i} not found or not function`);let l=await c.apply(this.register,o);s({id:n,result:l})}catch(c){s({id:n,error:c instanceof Error?{message:c.message,stack:c.stack,name:c.name}:c})}else if(a!==void 0){let c=t.get(n);c&&(c.resolve(a),t.delete(n))}else if(r!==void 0){let c=t.get(n);c&&(c.reject(r),t.delete(n))}}makeId(){return Math.random()}makeRequest(e,t,s=!0,n){let i=this.makeId(),o={id:i,method:e,params:t,...n};return s?new Promise((a,r)=>{this.map.set(i,{resolve:a,reject:r}),this.send(o)}):this.send(o)}};var $=class{constructor(e,t,s){this.path=e;this.argv=t;this.register=s;this.init(),s||(s=this),this.rpc=new M(this.send.bind(this),s)}static{p(this,"WorkerThreadLaunch")}static isMainThread=Ae;_readyResolve;_readyPromise=new Promise(e=>this._readyResolve=e);pid=process.pid;thread={};threadId={};rpc={};ready(){return this._readyPromise}readyResolve(){this._readyResolve?.()}init(){this.thread=new Me(this.path,{argv:this.argv.length==0&&this.argv[0]===void 0?void 0:this.argv}),this.threadId=this.thread.threadId,this.thread.on("message",e=>this.handleOnMessage(e)),this.thread.on("exit",()=>this.kill()),process.once("SIGINT",()=>this.kill()),process.once("SIGTERM",()=>this.kill())}async handleOnMessage(e){this.rpc.make(e)}kill(){this.thread.terminate()}send(e){this.thread.postMessage(e)}async request(e,t,s=!0,n){return this.rpc.makeRequest(e,t,s,n)}};var oe=class g{static{p(this,"WorkerThreadExport")}static launchGatewayClient(e){let t=new Proxy({},{get(n,i){if(!(typeof i!="string"||i==="then"))return async(o,...a)=>{let r=o.gatewayClients.get(e);return r||(r=await o.createGatewayClient(e)),r.request(i,a)}}}),s=p(function(n){return new Proxy({},{get(i,o){if(!(typeof o!="string"||o==="then"))return async(...a)=>{let r=n.gatewayClients.get(e);return r||(r=await n.createGatewayClient(e)),r.request(o,a)}}})},"ctor");return Object.setPrototypeOf(s,t),s}static init(e){let{WTInit:t,WTLaunch:s=$,path:n,wrap:i}=e,o=`for-${n}`;if(process.argv[2]===o)return new t,{launchGatewayClient:p(d=>g.launchGatewayClient(d||t.gatewayServerPath),"launchGatewayClient")};let a,r=new Proxy({},{get(d,h){if(h!=="then")return h==="sendRequest"||h==="request"||h==="kill"||h==="send"?(...m)=>{if(!a)throw new Error(`Thread at ${n} not launched yet.`);return a[h](...m)}:(...m)=>{if(!a)throw new Error(`Thread at ${n} not launched yet.`);return a.request(h,m)}}}),l={...i?i(r):{},launchWorker:p(async(d=[])=>(a=new s(n,[o,...d]),await a.ready(),a),"launchWorker"),launchGatewayClient:p(d=>g.launchGatewayClient(d||t.gatewayServerPath),"launchGatewayClient")};return new Proxy(l,{get(d,h){if(h!=="then")return h==="launchGatewayClient"?d.launchGatewayClient:h==="launchWorker"?d.launchWorker:h in d?d[h]:typeof h=="string"?(...m)=>{if(!a)throw new Error(`Thread at ${n} not launched yet.`);return a.request(h,m)}:d[h]}})}};import{Client as Pe}from"net-ipc";var E=class{static{p(this,"WorkerThreadGatewayClient")}client=new Pe;rpc;constructor(){this.rpc=new M(e=>this.client.send(e),{}),this.client.on("message",e=>{this.rpc.make(e)})}async connect(e){this.client.options.path=e;let t=new Promise(s=>{this.client.once("ready",()=>s(this))});return await this.client.connect(),t}async request(e,t,s=!0,n){return this.rpc.makeRequest(e,t,s,n)}};import{Server as Re}from"net-ipc";var L=class{static{p(this,"WorkerThreadGatewayServer")}server=new Re;rpc=new Map;register={};constructor(){this.server.on("connect",e=>{let t=new M(s=>e.send(s),this.register);this.rpc.set(e.id,t)}),this.server.on("disconnect",e=>{this.rpc.delete(e.id)}),this.server.on("message",(e,t)=>{let s=this.rpc.get(t.id);s&&s.make(e)}),this.server.on("error",e=>{console.error(e)})}async start(e,t={}){this.register=t,this.server.options.path=e;let s=new Promise(n=>{this.server.once("ready",()=>n(this))});return await this.server.start(),s}};import{parentPort as ve,threadId as De,isMainThread as Oe}from"worker_threads";var ae=class{static{p(this,"WorkerThreadInit")}argv=process.argv;id=De;pid=process.pid;rpc={};parentPort=ve;gatewayServer;gatewayClients=new Map;gatewayClientLatest;static gatewayServerPath;gatewayServerPath=this.constructor.gatewayServerPath;get gatewayClient(){return this.gatewayClientLatest}static isMainThread=Oe;constructor(){this.init(),this.rpc=new M(this.send.bind(this),this),this.send({method:"readyResolve"})}init(){this.parentPort?.on("message",e=>this.handleOnMessage(e))}handleOnMessage(e){this.rpc.make(e)}send(e){this.parentPort?.postMessage(e)}request(e,t,s=!0,n){return this.rpc.makeRequest(e,t,s,n)}async createGatewayServer(e,t){return e||(e=this),t||(t=this.constructor.gatewayServerPath),this.gatewayServer=new L,await this.gatewayServer.start(t,e),this.constructor.gatewayServerPath=t,!0}async createGatewayClient(e){let t=new E;return await t.connect(e),this.gatewayClients.set(e,t),this.gatewayClientLatest=t,t}};var re=class{static{p(this,"WorkerThreadPool")}thread=new Map;threadCount=0;constructor(e){this.addMany(e)}add(e){this.thread.set(e.threadId,e),this.threadCount+=1}addMany(e){e.forEach(t=>this.add(t))}getInstance(e){return this.thread.get(e)}kill(e){let t=this.thread.get(e);return t?.kill(),this.thread.delete(e),this.threadCount-=1,t?.threadId}killAll(){this.thread.values().forEach(({threadId:e})=>this.kill(e))}async broadcastRequest(e,t){return await Promise.all(Object.values(this.thread).map(s=>s.request(e,t,!0)))}async request(e,t,s,n=!0,i){return await this.thread.get(e)?.request(t,s,n,i)}};var ce=class{static{p(this,"MockTelegramServer")}token;hostname;port;handlers;defaultHandler;apiRoot="";server;constructor(e){this.token=e.token,this.hostname=e.hostname??"127.0.0.1",this.port=e.port??0,this.handlers=e.handlers??{},this.defaultHandler=e.defaultHandler}async start(){if(this.server)return this.apiRoot;let e=Bun.serve({port:this.port,hostname:this.hostname,fetch:p(async t=>this._handleRequest(t),"fetch")});return this.server=e,this.apiRoot=`http://${this.hostname}:${e.port??this.port}`,process.once("SIGINT",()=>this.stop()),process.once("SIGTERM",()=>this.stop()),this.apiRoot}async stop(){this.server?.stop(),this.server=void 0}_json(e){return new Response(JSON.stringify(e),{status:200,headers:{"Content-Type":"application/json"}})}_defaultResponse(e){return e==="getMe"?{ok:!0,result:{id:123456789,is_bot:!0,first_name:"Mock",username:"mock_gramstax_bot"}}:e==="getUpdates"?{ok:!0,result:[]}:e==="getMyCommands"?{ok:!0,result:[]}:e==="setMyCommands"?{ok:!0,result:!0}:e==="setWebhook"?{ok:!0,result:!0}:e==="getWebhookInfo"?{ok:!0,result:{url:""}}:{ok:!0,result:!0}}async _handleRequest(e){let{pathname:t}=new URL(e.url),s=`/bot${this.token}/`;if(!t.startsWith(s))return new Response("Not found",{status:404});let n=t.slice(s.length),i=this.handlers[n]??this.defaultHandler,o=i?await i({method:n,request:e}):this._defaultResponse(n);return this._json(o)}};export{ne as BlockKeyboard,F as CacheExternal,B as Ctx,te as Gramstax,ie as LabelKeyboard,j as LoggingHelper,ce as MockTelegramServer,_ as PageManager,A as TemplateEngine,W as TemplateManager,K as WebhookQueue,oe as WorkerThreadExport,E as WorkerThreadGatewayClient,L as WorkerThreadGatewayServer,ae as WorkerThreadInit,$ as WorkerThreadLaunch,re as WorkerThreadPool,M as WorkerThreadRpc,H as log};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gramstax",
3
- "version": "0.8.7",
3
+ "version": "0.8.9",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public",