gramstax 0.8.22 → 0.8.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/index.cjs +1 -1
- package/dist/src/index.js +1 -1
- package/package.json +1 -1
package/dist/src/index.cjs
CHANGED
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
`):h.map(d=>l(d.innerContent)).join(`
|
|
5
5
|
`)}return o}static _processImportBlocks(e){let t=/([ \t]*)<import(?:\s+([^>]*))?\/?>/gi,s=[];return{processed:e.replace(t,(i,a,o)=>{let r={},c=/(\w+)="([^"]*)"/g;if(o)for(let d of o.matchAll(c))r[d[1]]=d[2];let h=r.src;if(!h)return"";let l;r.block&&(r.block==="all"?l="all":r.block.includes(",")?l=r.block.split(",").map(d=>d.trim()).filter(d=>d):l=r.block);let u={src:h,blocks:l,base:r.base||"default",lang:r.lang,section:r.section||"all",indent:a||""};return s.push(u),`${a}__IMPORT_${s.length-1}__`}),imports:s}}static processImportBlocks(e,t,s=0,n){if(s>10)return"";let{processed:i,imports:a}=this._processImportBlocks(e),o=i;for(let r=0;r<a.length;r++){let c=a[r],h=`${c.src}|${c.base}|${c.lang||""}|${c.section}|${Array.isArray(c.blocks)?c.blocks.join(","):c.blocks||""}`,l;if(n&&n.has(h))l=n.get(h);else{let d=t(c.src);l=d?this._extractBlock(d,c.blocks,c.base,c.section,c.lang):"",l&&l.includes("<import")&&(l=this.processImportBlocks(l,t,s+1,n)),n&&n.set(h,l)}let u=l.split(`
|
|
6
6
|
`).map((d,p)=>p===0?d:c.indent+d).join(`
|
|
7
|
-
`);o=o.replace(`__IMPORT_${r}__`,u)}return o}static validateNamesBlock(e){let t=[],s=new Set(y.ALLOWED_BLOCKS.map(a=>a.replace(/^<\/?/,"").replace(/\s.*?>$/,"").replace(/\/?>$/,"").toLowerCase())),n=new Set(["b","i","u","s","code","pre","a","blockquote"]),i=/<\/?\s*([a-z][\w-]*)(?:\s[^<>]*)?\/?\s*>/gi;for(let a of e.matchAll(i)){let o=a[1]?.toLowerCase();if(!o||n.has(o)||s.has(o))continue;let r=(e.slice(0,a.index).match(/\n/g)||[]).length+1;t.push({line:r,message:`Unsupported template block: <${o}>`})}return{valid:t.length===0,errors:t}}static validateScopes(e){let t=[],s=new Set(y.ALLOWED_SCOPE),n=/\{([^\s{}\w])([\s\S]*?)\1\}/g;for(let i of e.matchAll(n)){let a=`{${i[1]}${i[1]}}`;if(i[1]&&s.has(a))continue;let o=(e.slice(0,i.index).match(/\n/g)||[]).length+1,r=i[1]??"?";t.push({line:o,message:`Unsupported template scope: {${r} ${r}}`})}return{valid:t.length===0,errors:t}}static validatePositionsBlock(e){let t=[],s=[],n=new Set(["b","i","u","s","code","pre","a","blockquote"]),i={base:new Set(["__root__"]),message:new Set(["base"]),keyboard:new Set(["base"]),media:new Set(["base","media-group"]),"media-group":new Set(["base"]),description:new Set(["base"]),switch:new Set(["message","keyboard","media","description"]),case:new Set(["switch"]),default:new Set(["switch"]),map:new Set(["message","keyboard","media","description"]),div:new Set(["base","message","description","keyboard","case","default","map"]),script:new Set(["base","message","description","keyboard","case","default","map","div"]),import:new Set(["base"]),space:new Set(["base","message","description","keyboard","case","default","switch","map","div"])},a=/<(\/?)(\w[\w-]*)([^>]*)>/g,o;for(;(o=a.exec(e))!==null;){let r=o[0],c=o[1],h=o[2].toLowerCase(),l=c==="/",u=!l&&r.endsWith("/>");if(n.has(h)||!i[h])continue;let d=(e.slice(0,o.index).match(/\n/g)||[]).length+1;if(l)if(s.length===0)t.push({line:d,message:`Unexpected closing tag </${h}>: no matching opening tag`});else{let p=s[s.length-1];p.block!==h?t.push({line:d,message:`Mismatched closing tag: expected </${p.block}> but found </${h}>`}):s.pop()}else if(u){let p=s.length>0?s[s.length-1].block:"__root__";i[h].has(p)||t.push({line:d,message:`Block <${h}> is not allowed inside <${p}>`})}else{let p=s.length>0?s[s.length-1].block:"__root__";i[h].has(p)||t.push({line:d,message:`Block <${h}> is not allowed inside <${p}>`}),s.push({block:h,line:d})}}for(let r of s)t.push({line:r.line,message:`Unclosed block <${r.block}>: missing closing tag </${r.block}>`});if(t.length===0){let r=[],c=/<base\b[^>]*>[\s\S]*?<\/base>/g,h;for(;(h=c.exec(e))!==null;)r.push({start:h.index,end:h.index+h[0].length});if(r.length===0&&e.trim())t.push({line:1,message:"Missing <base> block: template content must be wrapped in <base>...</base>"});else{let l=0;for(let u of r){if(u.start>l&&e.slice(l,u.start).trim()){let p=(e.slice(0,l).match(/\n/g)||[]).length+1;t.push({line:p,message:"Content found outside <base> block: move content inside a <base>...</base>"});break}l=u.end}if(t.length===0&&l<e.length&&e.slice(l).trim()){let u=(e.slice(0,l).match(/\n/g)||[]).length+1;t.push({line:u,message:"Content found outside <base> block: move content inside a <base>...</base>"})}}}return{valid:t.length===0,errors:t}}static validateFormatBlock(e){let t=[],s=new Set(["space","import"]),n=new Set(["base","message","keyboard","media","media-group","description","script","switch","case","default","map","div"]),i=/<(\/?)(\w[\w-]*)([^>]*)>/g,a;for(;(a=i.exec(e))!==null;){let o=a[0],r=a[1],c=a[2].toLowerCase(),h=r==="/",l=!h&&o.endsWith("/>");if(h)continue;let u=(e.slice(0,a.index).match(/\n/g)||[]).length+1;l?n.has(c)&&t.push({line:u,message:`Block <${c}> must not be self-closing: use <${c}>...</${c}> instead`}):s.has(c)&&t.push({line:u,message:`Block <${c}> must be self-closing: use <${c} /> instead`})}return{valid:t.length===0,errors:t}}static _validateBlockAttributes(e,t,s,n,i){let a=[],o=new RegExp(`<${t}(?![\\w-])([^>]*?)>`,"g"),r;for(;(r=o.exec(e))!==null;){let c=r[1].trim();if(!c)continue;let h=(e.slice(0,r.index).match(/\n/g)||[]).length+1,l=/([\w-]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+))/g,u;for(;(u=l.exec(c))!==null;){let d=u[1].toLowerCase();if(!s.has(d)){let p=s.size===0?"no attributes are allowed":`only ${n} is allowed`;a.push({line:h,message:`Unknown attribute "${u[1]}" on <${t}>: ${p}`});continue}if(i?.[d]){let p=u[2]??u[3]??u[4]??"",g=i[d](p);g&&a.push({line:h,message:g})}}}return a}static validateBlockBaseAttributes(e){let t=this._validateBlockAttributes(e,"base",new Set(["id"]),'"id"',{id:m(s=>s?null:'Attribute "id" on <base> must not be empty',"id")});return{valid:t.length===0,errors:t}}static validateBlockMessageAttributes(e){let t=this._validateBlockAttributes(e,"message",new Set(["lang"]),'"lang"');return{valid:t.length===0,errors:t}}static validateBlockKeyboardAttributes(e){let t=this._validateBlockAttributes(e,"keyboard",new Set(["lang","type"]),'"lang" and "type"',{type:m(s=>s==="inline"||s==="bottom"?null:`Attribute "type" on <keyboard> must be "inline" or "bottom", got "${s}"`,"type")});return{valid:t.length===0,errors:t}}static validateBlockMediaAttributes(e){let t=new Set(["photo","video","audio","document","animation","voice","video_note","sticker","location","contact"]),s=this._validateBlockAttributes(e,"media",new Set(["lang","type","src","shared","latitude","longitude","phone","first_name","last_name","vcard"]),'"lang", "type", "src", "shared", "latitude", "longitude", "phone", "first_name", "last_name", and "vcard"',{type:m(n=>t.has(n)?null:`Attribute "type" on <media> must be one of: ${[...t].join(", ")}, got "${n}"`,"type"),shared:m(n=>n==="true"||n==="false"?null:`Attribute "shared" on <media> must be "true" or "false", got "${n}"`,"shared")});return{valid:s.length===0,errors:s}}static validateBlockMediaGroupAttributes(e){let t=this._validateBlockAttributes(e,"media-group",new Set(["lang"]),'"lang"');return t.push(...this._validateMediaGroupItems(e)),{valid:t.length===0,errors:t}}static _validateMediaGroupItems(e){let t=[],s=/<media-group(?:\s+[^>]*)?>([\s\S]*?)<\/media-group>/gi,n=/<media(?:\s+([^>]*))?>([\s\S]*?)<\/media>/gi,i=new Set(["photo","video","audio","document"]);for(let a of e.matchAll(s)){let o=(e.slice(0,a.index).match(/\n/g)||[]).length+1,r=a[1]||"",c=[],h=0;for(let u of r.matchAll(n)){h+=1;let d=o+(r.slice(0,u.index).match(/\n/g)||[]).length,p=u[1]||"",g=p.match(/\btype\s*=\s*"([^"]*)"/)?.[1],f=p.match(/\bsrc\s*=\s*"([^"]*)"/)?.[1];if(!g||!i.has(g)){t.push({line:d,message:'Attribute "type" on <media> inside <media-group> must be one of: photo, video, audio, document'});continue}f||t.push({line:d,message:'Attribute "src" on <media> inside <media-group> is required'}),c.push(g)}h===0&&t.push({line:o,message:"<media-group> must contain at least one <media> item"}),h>this.MAX_MEDIA_GROUP_ITEMS&&t.push({line:o,message:`<media-group> must contain at most ${this.MAX_MEDIA_GROUP_ITEMS} <media> items`});let l=new Set(c);l.has("audio")&&l.size>1&&t.push({line:o,message:"<media-group> with audio items can only contain audio items"}),l.has("document")&&l.size>1&&t.push({line:o,message:"<media-group> with document items can only contain document items"})}return t}static validateBlockDescriptionAttributes(e){let t=this._validateBlockAttributes(e,"description",new Set(["lang","scope"]),'"lang" and "scope"');return{valid:t.length===0,errors:t}}static validateBlockScriptAttributes(e){let t=this._validateBlockAttributes(e,"script",new Set,"");return{valid:t.length===0,errors:t}}static validateBlockSwitchAttributes(e){let t=this._validateBlockAttributes(e,"switch",new Set(["value"]),'"value"');return{valid:t.length===0,errors:t}}static validateBlockCaseAttributes(e){let t=this._validateBlockAttributes(e,"case",new Set(["is"]),'"is"');return{valid:t.length===0,errors:t}}static validateBlockDefaultAttributes(e){let t=this._validateBlockAttributes(e,"default",new Set,"");return{valid:t.length===0,errors:t}}static validateBlockMapAttributes(e){let t=this._validateBlockAttributes(e,"map",new Set(["src","join"]),'"src" and "join"');return{valid:t.length===0,errors:t}}static validateBlockDivAttributes(e){let t=this._validateBlockAttributes(e,"div",new Set,"");return{valid:t.length===0,errors:t}}static validateBlockImportAttributes(e){let t=this._validateBlockAttributes(e,"import",new Set(["src","block","base","lang","section"]),'"src", "block", "base", "lang", and "section"');return{valid:t.length===0,errors:t}}static validateBlockSpaceAttributes(e){let t=this._validateBlockAttributes(e,"space",new Set,"");return{valid:t.length===0,errors:t}}static validateTemplate(e){let t=this.validateNamesBlock(e),s=this.validateScopes(e),n=this.validateFormatBlock(e),i=this.validatePositionsBlock(e),a=this.validateBlockBaseAttributes(e),o=this.validateBlockMessageAttributes(e),r=this.validateBlockKeyboardAttributes(e),c=this.validateBlockMediaAttributes(e),h=this.validateBlockMediaGroupAttributes(e),l=this.validateBlockDescriptionAttributes(e),u=this.validateBlockScriptAttributes(e),d=this.validateBlockSwitchAttributes(e),p=this.validateBlockCaseAttributes(e),g=this.validateBlockDefaultAttributes(e),f=this.validateBlockMapAttributes(e),T=this.validateBlockDivAttributes(e),w=this.validateBlockImportAttributes(e),R=this.validateBlockSpaceAttributes(e),D=[...t.errors,...s.errors,...n.errors,...i.errors,...a.errors,...o.errors,...r.errors,...c.errors,...h.errors,...l.errors,...u.errors,...d.errors,...p.errors,...g.errors,...f.errors,...T.errors,...w.errors,...R.errors];return{valid:D.length===0,errors:D}}};var U=class{static{m(this,"TemplateManager")}_map=new Map;_engine=A;_watcher=[];_pageManager=x;_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(!(0,S.existsSync)(t))throw new Error(`Template base path is not exists: ${t}`);if(!(0,S.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 s=this._path[t],n=(0,me.watch)(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=(0,C.basename)(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileAdd(e){let t=(0,C.basename)(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileDelete(e){let t=(0,C.basename)(e),s=this._getKey(t);this._map.has(s)&&this._map.delete(s)}_handleWatchError(e){}_loadAllFiles(){let e=new Map,t=new Map,s=[];for(let i=0;i<this._path.length;i++){let a=this._path[i],r=(0,S.readdirSync)(a,"utf8").filter(c=>this._isValidFile(c));for(let c of r){let h=(0,C.join)(a,c),l=this._getExtension(c),u=this._getKey(c);if(l===".html")e.set(u,(0,S.readFileSync)(h,"utf8")),t.set(u,c);else if(l===".ts"||l===".js"){let d=x.getFileSync(h);d?.template!==void 0&&(e.set(u,d.template),t.set(u,c),s.push(d))}}}let n=new Map;for(let[i,a]of e.entries())this._compile(i,a,void 0,n,e,t.get(i));e.clear(),n.clear();for(let i of s)i.template=void 0}_loadFile(e){for(let t=0;t<this._path.length;t++){let s=this._path[t],n=(0,C.join)(s,e),i=this._getExtension(e),a=this._getKey(e);if(i==".html"){let o=(0,S.readFileSync)(n,"utf8");this._compile(a,o,void 0,void 0,void 0,e)}else if(i==".ts"||i==".js"){let o=x.getFileSync(n);o?.template!==void 0&&(this._compile(a,o.template,void 0,void 0,void 0,e),o.template=void 0)}else throw new Error(`File ${e} is not support`)}}_getExtension(e){return(0,C.extname)(e).toLowerCase()}_readTemplateFile(e){for(let t of this._path){let s=(0,C.extname)(e).toLowerCase();if(s){let o=(0,C.join)(t,e);if((0,S.existsSync)(o)&&(0,S.statSync)(o).isFile()){if(s===".html")return(0,S.readFileSync)(o,"utf8");if(s===".ts"||s===".js")try{return x.getFileSync(o)?.template??null}catch{return null}}continue}let n=(0,C.join)(t,`${e}.ts`),i=(0,C.join)(t,`${e}.js`);if((0,S.existsSync)(n)&&(0,S.statSync)(n).isFile())try{return x.getFileSync(n)?.template??null}catch{}else if((0,S.existsSync)(i)&&(0,S.statSync)(i).isFile())try{return x.getFileSync(n)?.template??null}catch{}let a=(0,C.join)(t,`${e}.html`);if((0,S.existsSync)(a)&&(0,S.statSync)(a).isFile())return(0,S.readFileSync)(a,"utf8")}return null}_isValidFile(e){return this._supportedExtensions.has(this._getExtension(e))}_getBaseAtLine(e,t){let s=/<base\b([^>]*?)>/gi,n=/<\/base>/gi,i=t,a,o;for(;(a=s.exec(e))!==null&&!((e.slice(0,a.index).match(/\n/g)||[]).length+1>i);){let h=a[1].match(/\sid\s*=\s*(["']?)([^"'\s>]+)\1/i),l=h?.[2]??null,u=!!h;for(n.lastIndex||(n.lastIndex=s.lastIndex);(o=n.exec(e))!==null;){if((e.slice(0,o.index).match(/\n/g)||[]).length+1>i)return{baseId:l,hasId:u};s.lastIndex=n.lastIndex;break}}return null}_validateTemplate(e,t,s=e){let n=A.validateTemplate(t);if(!n.valid&&n.errors.length>0){let i=n.errors[0],a=this._getBaseAtLine(t,i.line),o=a?.hasId?` on base "${a.baseId}"`:"",r=`${s}, line ${i.line}`;throw new Error(`Template${o} (${r}): ${i.message}`)}}_getKey(e){return e.replace(/\.[^/.]+$/,"")}_compile(e,t,s,n,i,a=e){let o=this._map.get(e),r=o||{},c=!1;this._validateTemplate(e,t,a);let h=A.processImportBlocks(t,u=>i&&i.has(u)?i.get(u):this._readTemplateFile(u),0,n);this._validateTemplate(e,h,a);let l=A._processBaseBlocks(h);(s===void 0||s?.media===!1||o?.media===void 0)&&(r.media=A.compileBlockMedia(h,l),c=!0),(s===void 0||s?.message===!1||o?.message===void 0)&&(r.message=A.compileBlockMessage(h,l),c=!0),(s===void 0||s?.keyboard===!1||o?.keyboard===void 0)&&(r.keyboard=A.compileBlockKeyboards(h,l),c=!0),(s===void 0||s?.description===!1||o?.description===void 0)&&(r.description=A.compileBlockDescription(h,l),c=!0),c&&this._map.set(e,r)}getMedia(e,t="default",s="default",n){let a=this._map.get(e)?.media?.[t],o=a?.[s]||a?.default;try{if(!o)throw new Error("Media function not found, please check your template");return o(n)}catch{return{}}}getMessage(e,t="default",s="default",n){try{let a=this._map.get(e)?.message?.[t],o=a?.[s]||a?.default;if(!o)throw"";return o(n)}catch{return""}}getDescription(e,t="default",s="default",n="default",i){try{let o=this._map.get(e)?.description?.[t]?.[n],r=o?.[s]||o?.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 o=this._map.get(e)?.keyboard?.[t],r=o?.[s]?.[n]||o?.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=(0,C.join)(this._path[s],e);if((0,S.existsSync)(n))return(0,S.writeFileSync)(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()}};var j=require("grammy");var N=class{constructor(e){this.maxSize=e;if(!Number.isFinite(e)||e<=0)throw new Error("WebhookQueue maxSize must be a positive number")}maxSize;static{m(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=(0,B.dirname)((()=>{try{return __filename}catch{return(0,ye.fileURLToPath)(k)}})()),Ae=JSON.parse((0,ge.readFileSync)((0,B.join)(xe,"../../package.json"),"utf-8")).version,ee=class{static{m(this,"Gramstax")}templateManager;cacheKeyboard;cacheSession;pages;optionsPage={shortCallbackData:!1};log;bot;botConfig;webhookQueue;webhookQueueInstance;webhookServer;handlerBotUpdate;deployType;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?V:e.log?e.log:void 0,this.log?.info?.(`Gramstax v${Ae}`),this.cacheSession=e.cacheSession||new K("memory"),this.cacheKeyboard=e.cacheKeyboard||new Map,this.botConfig=e.botConfig,this.webhookQueue=e.webhookQueue,this.templateManager=e.templateManager||new U({path:[(0,B.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.stop()),process.once("SIGTERM",()=>this.stop()),this.hookBeforeStart(),e.deploy.startsWith("polling"))this.deployType="polling",this._runPolling();else if(e.deploy.startsWith("webhook:"))this.deployType="webhook",this._runWebhook(e.deploy.split("webhook:")[1]);else if(e.deploy.startsWith("serverless:"))this.deployType="serverless",this._runServerless(e.deploy.split("serverless:")[1]);else if(e.deploy.startsWith("test"))this.deployType="test";else throw new Error("Params deploy is not valid, expected: polling, webhook:<public-url>, serverless:<your-adapter>")}async stop(){await this.bot.stop(),this.deployType==="webhook"&&(await this.webhookServer?.stop(),this.webhookServer=void 0)}_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 deploy ${t} started: ${n} ${t=="webhook"||t=="serverless"?`(${s})`:""}`),this.hookAfterStart()}createBot(e){return new j.Bot(e,this.botConfig)}createCtx(e){return new q({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:m(e=>{this._onStart(e,"polling",null)},"onStart")})}async _runWebhook(e){let{serve:t}=await import("bun"),s=(0,j.webhookCallback)(this.bot,"bun"),n=this.webhookQueue,i=n?.enabled===!0;this.handlerBotUpdate=i?this.bot.handleUpdate.bind(this.bot):s;let a=i?new N(n?.maxQueueSize??5e3):void 0,o=n?.workerCount??8,r=n?.perChatConcurrency??1,c=n?.blockWhenFull!==!1,h=new Map,l=new Map;this.webhookQueueInstance=a;let u=m(b=>b?.message?.chat?.id??b?.edited_message?.chat?.id??b?.channel_post?.chat?.id??b?.edited_channel_post?.chat?.id??b?.callback_query?.message?.chat?.id??b?.callback_query?.from?.id??b?.inline_query?.from?.id??b?.chosen_inline_result?.from?.id,"getChatId"),d=m(async b=>{if(!i||r<=0||b===void 0||b===null)return()=>{};let _=String(b),I=h.get(_)||0;if(I<r)return h.set(_,I+1),()=>this._releaseWebhookChat(_,h,l);await new Promise(O=>{let re=l.get(_)||[];re.push(O),l.set(_,re)});let P=(h.get(_)||0)+1;return h.set(_,P),()=>this._releaseWebhookChat(_,h,l)},"acquireChat");if(i&&a){await this.bot.init();for(let b=0;b<o;b++)this._startWebhookWorker(a,d,u)}let p=new URL(e),g=p.pathname,f=parseInt(p.port)||3e3,T=this.log,w="/stats_queue";this.webhookServer?.stop();let R=t({port:f,async fetch(b){let{pathname:_}=new URL(b.url);if(b.method=="POST"&&_==g){if(!i||!a)return s(b);if(!c&&a.length>=(n?.maxQueueSize??5e3))return new Response("Queue full",{status:429});try{let I=await b.json();return await a.enqueue(I),new Response("OK",{status:200})}catch(I){return T?.error?.(`Webhook queue error: ${String(I)}`),new Response("Bad Request",{status:400})}}if(b.method=="GET"&&_==w){let I=a?.getStats()||{length:0,maxSize:n?.maxQueueSize??5e3,waitingEnqueue:0,waitingDequeue:0};return new Response(JSON.stringify({enabled:i,path:w,timestamp:new Date().toISOString(),maxQueueSize:n?.maxQueueSize??5e3,workerCount:o,perChatConcurrency:r,blockWhenFull:c,queue:I,activeChats:h.size}),{status:200,headers:{"Content-Type":"application/json"}})}if(b.method=="GET"&&_=="/"){let I=new Date().toISOString();return new Response(JSON.stringify({status:"OK",timestamp:I}),{status:200,headers:{"Content-Type":"application/json"}})}return new Response("Not found",{status:404})}});this.webhookServer=R,(await this.bot.api.getWebhookInfo()).url!=e&&await this.bot.api.setWebhook(e);let F=await this.bot.api.getMe();await this._onStart(F,"webhook",e)}_startWebhookWorker(e,t,s){m(async()=>{for(;;){let i=await e.dequeue(),a=await t(s(i));try{await this.bot.handleUpdate(i)}catch(o){this.log?.error?.(`Webhook worker error: ${String(o)}`)}finally{a()}}},"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 a=s.get(e);a&&a.length>0&&(a.shift()(),a.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=(0,j.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:s}=(0,B.parse)(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,a="handle",o="Args",r="Command",c="Caption",h="Free",l=t.routeDynamic,u=t.routeDynamicSpesific;t.all[n]=e;for(let p of["listRouteStatic","listRouteStaticIntent"]){let g=p==="listRouteStatic"?"lenListRouteStatic":"lenListRouteStaticIntent";for(let f=0;f<t[g];f++){let T=t[p][f];if(typeof i[T]!="function")continue;let w=t.routeStatic[T],R=t.routeStaticIntent[T],D={name:n,routeName:T},F=w||R;if(F!==void 0){let b=T.includes(r),_=T.endsWith("CallbackData"),I=T.endsWith("Text"),P;if(b){let O=e.data.intentCommandText;P=O?`/${O}`:void 0}else if(_){let O=e.data.intentCallbackData;this.optionsPage.shortCallbackData===!0&&(O=String(s),e.data.intentCallbackData=O),P=O}else I?P=e.data.intentText:P=e.data.name;P&&(F[P]=D)}}}for(let p=0;p<t.lenListRouteStaticSession;p++){let g=t.listRouteStaticSession[p];if(typeof i[g]!="function")continue;let f=t.routeStaticSession[g],T={name:n,routeName:g};if(f!==void 0){let w=g.replace("handle",""),D=`methodSession${w.startsWith("Session")?w.slice(7):w}`,F=i[D]?.(n);f[F]=T}}let d=["handleFreeText","handleFreePhoto","handleFreeVideo","handleFreeAudio","handleFreeDocument","handleFreeAnimation","handleFreeVoice","handleFreeVideoNote","handleFreeSticker","handleFreeLocation","handleFreeContact"];for(let p of d)if(Object.hasOwn(i,p)&&typeof i[p]=="function"){let g=p.replace(a,"").replace(o,"").replace(r,"").replace(c,"").replace(h,"").toLowerCase();u[g]?.some(T=>T.name===n)||u[g].push({name:n,routeName:p})}i.handleFree&&l.push(n)}async executeSyncBlocksDescription(e){let t=new Map,s=e.routeStatic.handleCommandText;for(let[,n]of Object.entries(s)){let i=n.name,a=this.templateManager.getDescriptionScopes(i);for(let o of a){t.has(o)||t.set(o,new Set);let r=this.templateManager.getDescriptionLanguage(i,"default",o);for(let c of r)t.get(o).add(c)}}for(let[n,i]of t)for(let a of i){let o=[];for(let[,h]of Object.entries(s)){let l=h.name,u=this.templateManager.getDescription(l,"default",a,n);u&&o.push({command:l,description:u})}if(o.length===0)continue;let r={type:n},c=a==="default"?void 0:a;try{let h=await this.bot.api.getMyCommands({scope:r,language_code:c}),l=JSON.stringify(h.map(d=>({command:d.command,description:d.description})).sort((d,p)=>d.command.localeCompare(p.command))),u=JSON.stringify(o.sort((d,p)=>d.command.localeCompare(p.command)));l!==u&&(await this.bot.api.setMyCommands(o,{scope:r,language_code:c}),this.log?.info?.(`Synced descriptions for scope: ${n},${c?` lang: ${c},`:""} total (${o.length})`))}catch(h){this.log?.error?.(`Failed to sync descriptions for scope: ${n},${c?` lang: ${c},`:""} error: ${String(h)}`)}}}_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","handleCommandCaptionArgsVoice"],s=m(r=>`handleSession${r.startsWith("handle")?r.slice(6):r}`,"toSession"),n=[...e.map(s),...t.map(s),"handleSessionFreeText","handleSessionFreePhoto","handleSessionFreeVideo","handleSessionFreeAudio","handleSessionFreeDocument","handleSessionFreeAnimation","handleSessionFreeVoice","handleSessionFreeVideoNote","handleSessionFreeSticker","handleSessionFreeLocation","handleSessionFreeContact"],i=m((r,c)=>Object.fromEntries(r.map(h=>[h,c()])),"makeObject"),a=m(()=>[],"initDynamicSpesific"),o={all:{},routeDynamic:[],routeDynamicSpesific:{text:a(),photo:a(),video:a(),audio:a(),document:a(),animation:a(),voice:a(),videonote:a(),sticker:a(),location:a(),contact:a()},routeStatic:i(e,()=>({})),routeStaticIntent:i(t,()=>({})),routeStaticSession:i(n,()=>({})),listRouteStatic:e,listRouteStaticIntent:t,listRouteStaticSession:n,lenListRouteStatic:e.length,lenListRouteStaticIntent:t.length,lenListRouteStaticSession:n.length};return x.getFileManySync(void 0).forEach(({path:r,page:c},h)=>{this._pageBuildData(c,r),this._pageSorts(c,o,h),c.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 a=await e.getSession();if(a){let o=a.method,r=this.pages.routeStaticSession;for(let c=0;c<this.pages.lenListRouteStaticSession;c++){let h=this.pages.listRouteStaticSession[c];if(h.toLowerCase().endsWith(t)&&(n=r[h][o]),n)break}n!==void 0&&(s=this.pages.all[n.name])}}if(s===void 0){let a=e.callbackData,o=e.msgText,r=e.msgCaption,c=this.pages.routeStatic;for(let h=0;h<this.pages.lenListRouteStatic;h++){let l=this.pages.listRouteStatic[h];if(l.toLowerCase().endsWith(t)&&(n=c[l][a||o||r]),n)break}n!==void 0&&(s=this.pages.all[n.name])}if(s===void 0){let a=this.pages.routeStaticIntent,o=t==="callbackdata",r=o?"colon":"space",c=o?e.callbackData:e.msgText||e.msgCaption,h=e.haveArgs(c,r);if(c&&h)for(let l=0;l<this.pages.lenListRouteStaticIntent;l++){let u=this.pages.listRouteStaticIntent[l];if(!u.toLowerCase().endsWith(t))continue;let d=a[u];if(n=d[e.getIntent(c,r,1)],!n&&!o&&(n=d[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 o=await new s(e)[n.routeName]?.();return e.temp.isAnswer===!0?o:null}let i=this.pages.routeDynamicSpesific[t]||[];for(let a=0;a<i.length;a++){let o=i[a];if(o===void 0)continue;let r=this.pages.all[o.name];r!==void 0&&typeof r.prototype[o.routeName]=="function"&&await new r(e)[o.routeName]()}for(let a=0;a<this.pages.routeDynamic.length;a++){let o=this.pages.routeDynamic[a];if(o===void 0)continue;let r=this.pages.all[o];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 te=class{static{m(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 a=m((o,r)=>`<keyboard type="${s}" lang="${r}">${n?this.label._reverse(o):o}</keyboard>`,"pro");return t?a(i[t],t):Object.keys(i).map(o=>a(i[o],o)).join(" ")}};var se=class{static{m(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),{})}};var Y=require("worker_threads");var v=class{constructor(e,t){this.send=e;this.register=t}send;register;static{m(this,"WorkerThreadRpc")}map=new Map;async make(e){let t=this.map,s=this.send,{id:n,method:i,params:a,result:o,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 h=await c.apply(this.register,a);s({id:n,result:h})}catch(c){s({id:n,error:c instanceof Error?{message:c.message,stack:c.stack,name:c.name}:c})}else if(o!==void 0){let c=t.get(n);c&&(c.resolve(o),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(),a={id:i,method:e,params:t,...n};return s?new Promise((o,r)=>{this.map.set(i,{resolve:o,reject:r}),this.send(a)}):this.send(a)}};var Q=class{constructor(e,t,s){this.path=e;this.argv=t;this.register=s;this.init(),s||(s=this),this.rpc=new v(this.send.bind(this),s)}path;argv;register;static{m(this,"WorkerThreadLaunch")}static isMainThread=Y.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 Y.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,s=!0,n){return this.rpc.makeRequest(e,t,s,n)}};var ne=class y{static{m(this,"WorkerThreadExport")}static launchGatewayClient(e){let t=new Proxy({},{get(n,i){if(!(typeof i!="string"||i==="then"))return async(a,...o)=>{let r=a.gatewayClients.get(e);return r||(r=await a.createGatewayClient(e)),r.request(i,o)}}}),s=m(function(n){return new Proxy({},{get(i,a){if(!(typeof a!="string"||a==="then"))return async(...o)=>{let r=n.gatewayClients.get(e);return r||(r=await n.createGatewayClient(e)),r.request(a,o)}}})},"ctor");return Object.setPrototypeOf(s,t),s}static init(e){let{WTInit:t,WTLaunch:s=Q,path:n,wrap:i}=e,a=`for-${n}`;if(process.argv[2]===a)return new t,{launchGatewayClient:m(l=>y.launchGatewayClient(l||t.gatewayServerPath),"launchGatewayClient")};let o,r=new Proxy({},{get(l,u){if(u!=="then")return u==="sendRequest"||u==="request"||u==="kill"||u==="send"?(...d)=>{if(!o)throw new Error(`Thread at ${n} not launched yet.`);return o[u](...d)}:(...d)=>{if(!o)throw new Error(`Thread at ${n} not launched yet.`);return o.request(u,d)}}}),h={...i?i(r):{},launchWorker:m(async(l=[])=>(o=new s(n,[a,...l]),await o.ready(),o),"launchWorker"),launchGatewayClient:m(l=>y.launchGatewayClient(l||t.gatewayServerPath),"launchGatewayClient")};return new Proxy(h,{get(l,u){if(u!=="then")return u==="launchGatewayClient"?l.launchGatewayClient:u==="launchWorker"?l.launchWorker:u in l?l[u]:typeof u=="string"?(...d)=>{if(!o)throw new Error(`Thread at ${n} not launched yet.`);return o.request(u,d)}:l[u]}})}};var fe=require("net-ipc");var H=class{static{m(this,"WorkerThreadGatewayClient")}client=new fe.Client;rpc;constructor(){this.rpc=new v(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)}};var be=require("net-ipc");var z=class{static{m(this,"WorkerThreadGatewayServer")}server=new be.Server;rpc=new Map;register={};constructor(){this.server.on("connect",e=>{let t=new v(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}};var L=require("worker_threads");var ie=class{static{m(this,"WorkerThreadInit")}argv=process.argv;id=L.threadId;pid=process.pid;rpc={};parentPort=L.parentPort;gatewayServer;gatewayClients=new Map;gatewayClientLatest;static gatewayServerPath;gatewayServerPath=this.constructor.gatewayServerPath;get gatewayClient(){return this.gatewayClientLatest}static isMainThread=L.isMainThread;constructor(){this.init(),this.rpc=new v(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 z,await this.gatewayServer.start(t,e),this.constructor.gatewayServerPath=t,!0}async createGatewayClient(e){let t=new H;return await t.connect(e),this.gatewayClients.set(e,t),this.gatewayClientLatest=t,t}};var ae=class{static{m(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 oe=class{static{m(this,"MockTelegramServer")}botToken="";hostname;port;log;handlers;defaultHandler;apiRoot="";webhookUrl="";requests=[];updates=[];server;_nextUpdateId=1;_nextMessageId=1;constructor(e={}){this.hostname=e.hostname??"127.0.0.1",this.port=e.port??0,this.log=e.log===!0?V:e.log?e.log:void 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:m(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.log?.info?.(`Mock Telegram server started: ${this.apiRoot}`),this.apiRoot}async stop(){this.server?.stop(),this.server=void 0,this.log?.info?.("Mock Telegram server stopped")}_json(e){return new Response(JSON.stringify(e),{status:200,headers:{"Content-Type":"application/json"}})}lastRequest(e){if(!e)return this.requests[this.requests.length-1];for(let t=this.requests.length-1;t>=0;t--){let s=this.requests[t];if(s?.method===e)return s}}clearRequests(){this.requests.length=0}_defaultResponse(e,t){if(e==="getMe")return{ok:!0,result:{id:123456789,is_bot:!0,first_name:"Mock",username:"mock_gramstax_bot"}};if(e==="getUpdates")return{ok:!0,result:[]};if(e==="getMyCommands")return{ok:!0,result:[]};if(e==="setMyCommands")return{ok:!0,result:!0};if(e==="setWebhook"){let s=this._bodyRecord(t),n=typeof s?.url=="string"?s.url:"";return this.webhookUrl=n,this.log?.info?.(`Mock Telegram webhook set: ${n}`),{ok:!0,result:!0}}return e==="getWebhookInfo"?{ok:!0,result:{url:this.webhookUrl}}:{ok:!0,result:!0}}async _handleRequest(e){let{pathname:t}=new URL(e.url),s=t.match(/^\/bot([^/]+)\/(.+)$/);if(!s)return new Response("Not found",{status:404});let n=s[1],i=s[2];if(!n||!i)return new Response("Not found",{status:404});this.botToken=n;let a=await this._readBody(e.clone());this.log?.debug?.(`Mock Telegram API request: ${i}`),this.requests.push({method:i,body:a,url:e.url,requestMethod:e.method,headers:Object.fromEntries(e.headers.entries())});let o=this.handlers[i]??this.defaultHandler,r=o?await o({method:i,request:e}):this._defaultResponse(i,a);return this._json(r)}_bodyRecord(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}async _readBody(e){if(e.method==="GET"||e.method==="HEAD")return;let t=e.headers.get("content-type")||"";try{if(t.includes("application/json"))return await e.json();if(t.includes("multipart/form-data")||t.includes("application/x-www-form-urlencoded")){let n=await e.formData();return Object.fromEntries(n.entries())}let s=await e.text();if(!s)return;try{return JSON.parse(s)}catch{return s}}catch{return}}_defaultUser(e){return{id:e?.id??1001,is_bot:e?.is_bot??!1,first_name:e?.first_name??"Test",...e?.last_name?{last_name:e.last_name}:{},...e?.username?{username:e.username}:{},language_code:e?.language_code??"en"}}_defaultChat(e){return{id:e?.id??1001,type:e?.type??"private",first_name:e?.first_name??"Test",...e?.last_name?{last_name:e.last_name}:{},...e?.username?{username:e.username}:{},...e?.title?{title:e.title}:{}}}_nextIds(e){return{updateId:this._nextUpdateId++,messageId:e?.message_id??this._nextMessageId++,date:e?.date??Math.floor(Date.now()/1e3)}}_buildMessageUpdate(e,t){let{updateId:s,messageId:n,date:i}=this._nextIds(t);return{update_id:s,message:{message_id:n,date:i,chat:this._defaultChat(t?.chat),from:this._defaultUser(t?.user),...e}}}async _postUpdate(e,t){if(await this._waitForWebhookUrl(t?.responseTimeoutMs??1e3),!this.webhookUrl)throw new Error("Webhook URL is not set. Call setWebhook first or assign mockServer.webhookUrl.");let s=this.requests.length;this.updates.push(e),this.log?.info?.(`Mock Telegram update sent: ${this.webhookUrl}`);let n=await fetch(this.webhookUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!n.ok)throw new Error(`Webhook request failed with status ${n.status}`);let i=await this._waitForResponses(s,t?.responseTimeoutMs??1e3);return this.log?.info?.(`Mock Telegram bot responses captured: ${i.length}`),i}async _waitForWebhookUrl(e){if(this.webhookUrl||e<=0)return this.webhookUrl;let t=Date.now();for(;Date.now()-t<e&&(await new Promise(s=>setTimeout(s,5)),!this.webhookUrl););return this.webhookUrl}async _waitForResponses(e,t){if(t<=0)return this._userResponseRequests(e);if(this._userResponseRequests(e).length>0)return this._userResponseRequests(e);let s=Date.now();for(;Date.now()-s<t&&(await new Promise(n=>setTimeout(n,5)),!(this._userResponseRequests(e).length>0)););return this._userResponseRequests(e)}_userResponseRequests(e){return this.requests.slice(e).filter(t=>this._isUserResponseMethod(t.method))}_isUserResponseMethod(e){return e.startsWith("send")||e.startsWith("edit")||e.startsWith("answer")||e.startsWith("delete")||e.startsWith("copy")||e.startsWith("forward")||e==="pinChatMessage"||e==="unpinChatMessage"||e==="setMessageReaction"}async sendText(e,t){let s=e.startsWith("/")?[{offset:0,length:e.split(" ")[0]?.length??e.length,type:"bot_command"}]:void 0;return await this._postUpdate(this._buildMessageUpdate({text:e,...s?{entities:s}:{}},t),t)}async sendPhoto(e){return await this._postUpdate(this._buildMessageUpdate({photo:[{file_id:"mock-photo-file-id",file_unique_id:"mock-photo-unique-id",width:1,height:1}],...e?.caption?{caption:e.caption}:{}},e),e)}async sendVideo(e){return await this._postUpdate(this._buildMessageUpdate({video:{file_id:"mock-video-file-id",file_unique_id:"mock-video-unique-id",width:1,height:1,duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendAudio(e){return await this._postUpdate(this._buildMessageUpdate({audio:{file_id:"mock-audio-file-id",file_unique_id:"mock-audio-unique-id",duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendDocument(e){return await this._postUpdate(this._buildMessageUpdate({document:{file_id:"mock-document-file-id",file_unique_id:"mock-document-unique-id",file_name:"mock.txt"},...e?.caption?{caption:e.caption}:{}},e),e)}async sendAnimation(e){return await this._postUpdate(this._buildMessageUpdate({animation:{file_id:"mock-animation-file-id",file_unique_id:"mock-animation-unique-id",width:1,height:1,duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendVoice(e){return await this._postUpdate(this._buildMessageUpdate({voice:{file_id:"mock-voice-file-id",file_unique_id:"mock-voice-unique-id",duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendVideoNote(e){return await this._postUpdate(this._buildMessageUpdate({video_note:{file_id:"mock-video-note-file-id",file_unique_id:"mock-video-note-unique-id",length:1,duration:1}},e),e)}async sendSticker(e){return await this._postUpdate(this._buildMessageUpdate({sticker:{file_id:"mock-sticker-file-id",file_unique_id:"mock-sticker-unique-id",type:"regular",width:1,height:1,is_animated:!1,is_video:!1}},e),e)}async sendLocation(e){return await this._postUpdate(this._buildMessageUpdate({location:{latitude:e?.latitude??0,longitude:e?.longitude??0}},e),e)}async sendContact(e){return await this._postUpdate(this._buildMessageUpdate({contact:{phone_number:e?.phone_number??"+10000000000",first_name:e?.first_name??"Test",...e?.last_name?{last_name:e.last_name}:{},...e?.user_id?{user_id:e.user_id}:{}}},e),e)}async sendCallbackQuery(e,t){let{updateId:s,messageId:n,date:i}=this._nextIds(t);return await this._postUpdate({update_id:s,callback_query:{id:t?.id??`mock-callback-${s}`,from:this._defaultUser(t?.user),message:{message_id:n,date:i,chat:this._defaultChat(t?.chat),text:t?.messageText??"Mock message"},chat_instance:"mock-chat-instance",data:e}},t)}};0&&(module.exports={BlockKeyboard,CacheExternal,Ctx,Gramstax,LabelKeyboard,LoggingHelper,MockTelegramServer,PageManager,TemplateEngine,TemplateManager,WebhookQueue,WorkerThreadExport,WorkerThreadGatewayClient,WorkerThreadGatewayServer,WorkerThreadInit,WorkerThreadLaunch,WorkerThreadPool,WorkerThreadRpc,log});
|
|
7
|
+
`);o=o.replace(`__IMPORT_${r}__`,u)}return o}static validateNamesBlock(e){let t=[],s=new Set(y.ALLOWED_BLOCKS.map(a=>a.replace(/^<\/?/,"").replace(/\s.*?>$/,"").replace(/\/?>$/,"").toLowerCase())),n=new Set(["b","i","u","s","code","pre","a","blockquote"]),i=/<\/?\s*([a-z][\w-]*)(?:\s[^<>]*)?\/?\s*>/gi;for(let a of e.matchAll(i)){let o=a[1]?.toLowerCase();if(!o||n.has(o)||s.has(o))continue;let r=(e.slice(0,a.index).match(/\n/g)||[]).length+1;t.push({line:r,message:`Unsupported template block: <${o}>`})}return{valid:t.length===0,errors:t}}static validateScopes(e){let t=[],s=new Set(y.ALLOWED_SCOPE),n=/\{([^\s{}\w])([\s\S]*?)\1\}/g;for(let i of e.matchAll(n)){let a=`{${i[1]}${i[1]}}`;if(i[1]&&s.has(a))continue;let o=(e.slice(0,i.index).match(/\n/g)||[]).length+1,r=i[1]??"?";t.push({line:o,message:`Unsupported template scope: {${r} ${r}}`})}return{valid:t.length===0,errors:t}}static validatePositionsBlock(e){let t=[],s=[],n=new Set(["b","i","u","s","code","pre","a","blockquote"]),i={base:new Set(["__root__"]),message:new Set(["base"]),keyboard:new Set(["base"]),media:new Set(["base","media-group"]),"media-group":new Set(["base"]),description:new Set(["base"]),switch:new Set(["message","keyboard","media","description"]),case:new Set(["switch"]),default:new Set(["switch"]),map:new Set(["message","keyboard","media","description"]),div:new Set(["base","message","description","keyboard","case","default","map"]),script:new Set(["base","message","description","keyboard","case","default","map","div"]),import:new Set(["base"]),space:new Set(["base","message","description","keyboard","case","default","switch","map","div"])},a=/<(\/?)(\w[\w-]*)([^>]*)>/g,o;for(;(o=a.exec(e))!==null;){let r=o[0],c=o[1],h=o[2].toLowerCase(),l=c==="/",u=!l&&r.endsWith("/>");if(n.has(h)||!i[h])continue;let d=(e.slice(0,o.index).match(/\n/g)||[]).length+1;if(l)if(s.length===0)t.push({line:d,message:`Unexpected closing tag </${h}>: no matching opening tag`});else{let p=s[s.length-1];p.block!==h?t.push({line:d,message:`Mismatched closing tag: expected </${p.block}> but found </${h}>`}):s.pop()}else if(u){let p=s.length>0?s[s.length-1].block:"__root__";i[h].has(p)||t.push({line:d,message:`Block <${h}> is not allowed inside <${p}>`})}else{let p=s.length>0?s[s.length-1].block:"__root__";i[h].has(p)||t.push({line:d,message:`Block <${h}> is not allowed inside <${p}>`}),s.push({block:h,line:d})}}for(let r of s)t.push({line:r.line,message:`Unclosed block <${r.block}>: missing closing tag </${r.block}>`});if(t.length===0){let r=[],c=/<base\b[^>]*>[\s\S]*?<\/base>/g,h;for(;(h=c.exec(e))!==null;)r.push({start:h.index,end:h.index+h[0].length});if(r.length===0&&e.trim())t.push({line:1,message:"Missing <base> block: template content must be wrapped in <base>...</base>"});else{let l=0;for(let u of r){if(u.start>l&&e.slice(l,u.start).trim()){let p=(e.slice(0,l).match(/\n/g)||[]).length+1;t.push({line:p,message:"Content found outside <base> block: move content inside a <base>...</base>"});break}l=u.end}if(t.length===0&&l<e.length&&e.slice(l).trim()){let u=(e.slice(0,l).match(/\n/g)||[]).length+1;t.push({line:u,message:"Content found outside <base> block: move content inside a <base>...</base>"})}}}return{valid:t.length===0,errors:t}}static validateFormatBlock(e){let t=[],s=new Set(["space","import"]),n=new Set(["base","message","keyboard","media","media-group","description","script","switch","case","default","map","div"]),i=/<(\/?)(\w[\w-]*)([^>]*)>/g,a;for(;(a=i.exec(e))!==null;){let o=a[0],r=a[1],c=a[2].toLowerCase(),h=r==="/",l=!h&&o.endsWith("/>");if(h)continue;let u=(e.slice(0,a.index).match(/\n/g)||[]).length+1;l?n.has(c)&&t.push({line:u,message:`Block <${c}> must not be self-closing: use <${c}>...</${c}> instead`}):s.has(c)&&t.push({line:u,message:`Block <${c}> must be self-closing: use <${c} /> instead`})}return{valid:t.length===0,errors:t}}static _validateBlockAttributes(e,t,s,n,i){let a=[],o=new RegExp(`<${t}(?![\\w-])([^>]*?)>`,"g"),r;for(;(r=o.exec(e))!==null;){let c=r[1].trim();if(!c)continue;let h=(e.slice(0,r.index).match(/\n/g)||[]).length+1,l=/([\w-]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+))/g,u;for(;(u=l.exec(c))!==null;){let d=u[1].toLowerCase();if(!s.has(d)){let p=s.size===0?"no attributes are allowed":`only ${n} is allowed`;a.push({line:h,message:`Unknown attribute "${u[1]}" on <${t}>: ${p}`});continue}if(i?.[d]){let p=u[2]??u[3]??u[4]??"",g=i[d](p);g&&a.push({line:h,message:g})}}}return a}static validateBlockBaseAttributes(e){let t=this._validateBlockAttributes(e,"base",new Set(["id"]),'"id"',{id:m(s=>s?null:'Attribute "id" on <base> must not be empty',"id")});return{valid:t.length===0,errors:t}}static validateBlockMessageAttributes(e){let t=this._validateBlockAttributes(e,"message",new Set(["lang"]),'"lang"');return{valid:t.length===0,errors:t}}static validateBlockKeyboardAttributes(e){let t=this._validateBlockAttributes(e,"keyboard",new Set(["lang","type"]),'"lang" and "type"',{type:m(s=>s==="inline"||s==="bottom"?null:`Attribute "type" on <keyboard> must be "inline" or "bottom", got "${s}"`,"type")});return{valid:t.length===0,errors:t}}static validateBlockMediaAttributes(e){let t=new Set(["photo","video","audio","document","animation","voice","video_note","sticker","location","contact"]),s=this._validateBlockAttributes(e,"media",new Set(["lang","type","src","shared","latitude","longitude","phone","first_name","last_name","vcard"]),'"lang", "type", "src", "shared", "latitude", "longitude", "phone", "first_name", "last_name", and "vcard"',{type:m(n=>t.has(n)?null:`Attribute "type" on <media> must be one of: ${[...t].join(", ")}, got "${n}"`,"type"),shared:m(n=>n==="true"||n==="false"?null:`Attribute "shared" on <media> must be "true" or "false", got "${n}"`,"shared")});return{valid:s.length===0,errors:s}}static validateBlockMediaGroupAttributes(e){let t=this._validateBlockAttributes(e,"media-group",new Set(["lang"]),'"lang"');return t.push(...this._validateMediaGroupItems(e)),{valid:t.length===0,errors:t}}static _validateMediaGroupItems(e){let t=[],s=/<media-group(?:\s+[^>]*)?>([\s\S]*?)<\/media-group>/gi,n=/<media(?:\s+([^>]*))?>([\s\S]*?)<\/media>/gi,i=new Set(["photo","video","audio","document"]);for(let a of e.matchAll(s)){let o=(e.slice(0,a.index).match(/\n/g)||[]).length+1,r=a[1]||"",c=[],h=0;for(let u of r.matchAll(n)){h+=1;let d=o+(r.slice(0,u.index).match(/\n/g)||[]).length,p=u[1]||"",g=p.match(/\btype\s*=\s*"([^"]*)"/)?.[1],f=p.match(/\bsrc\s*=\s*"([^"]*)"/)?.[1];if(!g||!i.has(g)){t.push({line:d,message:'Attribute "type" on <media> inside <media-group> must be one of: photo, video, audio, document'});continue}f||t.push({line:d,message:'Attribute "src" on <media> inside <media-group> is required'}),c.push(g)}h===0&&t.push({line:o,message:"<media-group> must contain at least one <media> item"}),h>this.MAX_MEDIA_GROUP_ITEMS&&t.push({line:o,message:`<media-group> must contain at most ${this.MAX_MEDIA_GROUP_ITEMS} <media> items`});let l=new Set(c);l.has("audio")&&l.size>1&&t.push({line:o,message:"<media-group> with audio items can only contain audio items"}),l.has("document")&&l.size>1&&t.push({line:o,message:"<media-group> with document items can only contain document items"})}return t}static validateBlockDescriptionAttributes(e){let t=this._validateBlockAttributes(e,"description",new Set(["lang","scope"]),'"lang" and "scope"');return{valid:t.length===0,errors:t}}static validateBlockScriptAttributes(e){let t=this._validateBlockAttributes(e,"script",new Set,"");return{valid:t.length===0,errors:t}}static validateBlockSwitchAttributes(e){let t=this._validateBlockAttributes(e,"switch",new Set(["value"]),'"value"');return{valid:t.length===0,errors:t}}static validateBlockCaseAttributes(e){let t=this._validateBlockAttributes(e,"case",new Set(["is"]),'"is"');return{valid:t.length===0,errors:t}}static validateBlockDefaultAttributes(e){let t=this._validateBlockAttributes(e,"default",new Set,"");return{valid:t.length===0,errors:t}}static validateBlockMapAttributes(e){let t=this._validateBlockAttributes(e,"map",new Set(["src","join"]),'"src" and "join"');return{valid:t.length===0,errors:t}}static validateBlockDivAttributes(e){let t=this._validateBlockAttributes(e,"div",new Set,"");return{valid:t.length===0,errors:t}}static validateBlockImportAttributes(e){let t=this._validateBlockAttributes(e,"import",new Set(["src","block","base","lang","section"]),'"src", "block", "base", "lang", and "section"');return{valid:t.length===0,errors:t}}static validateBlockSpaceAttributes(e){let t=this._validateBlockAttributes(e,"space",new Set,"");return{valid:t.length===0,errors:t}}static validateTemplate(e){let t=this.validateNamesBlock(e),s=this.validateScopes(e),n=this.validateFormatBlock(e),i=this.validatePositionsBlock(e),a=this.validateBlockBaseAttributes(e),o=this.validateBlockMessageAttributes(e),r=this.validateBlockKeyboardAttributes(e),c=this.validateBlockMediaAttributes(e),h=this.validateBlockMediaGroupAttributes(e),l=this.validateBlockDescriptionAttributes(e),u=this.validateBlockScriptAttributes(e),d=this.validateBlockSwitchAttributes(e),p=this.validateBlockCaseAttributes(e),g=this.validateBlockDefaultAttributes(e),f=this.validateBlockMapAttributes(e),T=this.validateBlockDivAttributes(e),w=this.validateBlockImportAttributes(e),R=this.validateBlockSpaceAttributes(e),D=[...t.errors,...s.errors,...n.errors,...i.errors,...a.errors,...o.errors,...r.errors,...c.errors,...h.errors,...l.errors,...u.errors,...d.errors,...p.errors,...g.errors,...f.errors,...T.errors,...w.errors,...R.errors];return{valid:D.length===0,errors:D}}};var U=class{static{m(this,"TemplateManager")}_map=new Map;_engine=A;_watcher=[];_pageManager=x;_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(!(0,S.existsSync)(t))throw new Error(`Template base path is not exists: ${t}`);if(!(0,S.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 s=this._path[t],n=(0,me.watch)(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=(0,C.basename)(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileAdd(e){let t=(0,C.basename)(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileDelete(e){let t=(0,C.basename)(e),s=this._getKey(t);this._map.has(s)&&this._map.delete(s)}_handleWatchError(e){}_loadAllFiles(){let e=new Map,t=new Map,s=[];for(let i=0;i<this._path.length;i++){let a=this._path[i],r=(0,S.readdirSync)(a,"utf8").filter(c=>this._isValidFile(c));for(let c of r){let h=(0,C.join)(a,c),l=this._getExtension(c),u=this._getKey(c);if(l===".html")e.set(u,(0,S.readFileSync)(h,"utf8")),t.set(u,c);else if(l===".ts"||l===".js"){let d=x.getFileSync(h);d?.template!==void 0&&(e.set(u,d.template),t.set(u,c),s.push(d))}}}let n=new Map;for(let[i,a]of e.entries())this._compile(i,a,void 0,n,e,t.get(i));e.clear(),n.clear();for(let i of s)i.template=void 0}_loadFile(e){for(let t=0;t<this._path.length;t++){let s=this._path[t],n=(0,C.join)(s,e),i=this._getExtension(e),a=this._getKey(e);if(i==".html"){let o=(0,S.readFileSync)(n,"utf8");this._compile(a,o,void 0,void 0,void 0,e)}else if(i==".ts"||i==".js"){let o=x.getFileSync(n);o?.template!==void 0&&(this._compile(a,o.template,void 0,void 0,void 0,e),o.template=void 0)}else throw new Error(`File ${e} is not support`)}}_getExtension(e){return(0,C.extname)(e).toLowerCase()}_readTemplateFile(e){for(let t of this._path){let s=(0,C.extname)(e).toLowerCase();if(s){let o=(0,C.join)(t,e);if((0,S.existsSync)(o)&&(0,S.statSync)(o).isFile()){if(s===".html")return(0,S.readFileSync)(o,"utf8");if(s===".ts"||s===".js")try{return x.getFileSync(o)?.template??null}catch{return null}}continue}let n=(0,C.join)(t,`${e}.ts`),i=(0,C.join)(t,`${e}.js`);if((0,S.existsSync)(n)&&(0,S.statSync)(n).isFile())try{return x.getFileSync(n)?.template??null}catch{}else if((0,S.existsSync)(i)&&(0,S.statSync)(i).isFile())try{return x.getFileSync(n)?.template??null}catch{}let a=(0,C.join)(t,`${e}.html`);if((0,S.existsSync)(a)&&(0,S.statSync)(a).isFile())return(0,S.readFileSync)(a,"utf8")}return null}_isValidFile(e){return this._supportedExtensions.has(this._getExtension(e))}_getBaseAtLine(e,t){let s=/<base\b([^>]*?)>/gi,n=/<\/base>/gi,i=t,a,o;for(;(a=s.exec(e))!==null&&!((e.slice(0,a.index).match(/\n/g)||[]).length+1>i);){let h=a[1].match(/\sid\s*=\s*(["']?)([^"'\s>]+)\1/i),l=h?.[2]??null,u=!!h;for(n.lastIndex||(n.lastIndex=s.lastIndex);(o=n.exec(e))!==null;){if((e.slice(0,o.index).match(/\n/g)||[]).length+1>i)return{baseId:l,hasId:u};s.lastIndex=n.lastIndex;break}}return null}_validateTemplate(e,t,s=e){let n=A.validateTemplate(t);if(!n.valid&&n.errors.length>0){let i=n.errors[0],a=this._getBaseAtLine(t,i.line),o=a?.hasId?` on base "${a.baseId}"`:"",r=`${s}, line ${i.line}`;throw new Error(`Template${o} (${r}): ${i.message}`)}}_getKey(e){return e.replace(/\.[^/.]+$/,"")}_compile(e,t,s,n,i,a=e){let o=this._map.get(e),r=o||{},c=!1;this._validateTemplate(e,t,a);let h=A.processImportBlocks(t,u=>i&&i.has(u)?i.get(u):this._readTemplateFile(u),0,n);this._validateTemplate(e,h,a);let l=A._processBaseBlocks(h);(s===void 0||s?.media===!1||o?.media===void 0)&&(r.media=A.compileBlockMedia(h,l),c=!0),(s===void 0||s?.message===!1||o?.message===void 0)&&(r.message=A.compileBlockMessage(h,l),c=!0),(s===void 0||s?.keyboard===!1||o?.keyboard===void 0)&&(r.keyboard=A.compileBlockKeyboards(h,l),c=!0),(s===void 0||s?.description===!1||o?.description===void 0)&&(r.description=A.compileBlockDescription(h,l),c=!0),c&&this._map.set(e,r)}getMedia(e,t="default",s="default",n){let a=this._map.get(e)?.media?.[t],o=a?.[s]||a?.default;try{if(!o)throw new Error("Media function not found, please check your template");return o(n)}catch{return{}}}getMessage(e,t="default",s="default",n){try{let a=this._map.get(e)?.message?.[t],o=a?.[s]||a?.default;if(!o)throw"";return o(n)}catch{return""}}getDescription(e,t="default",s="default",n="default",i){try{let o=this._map.get(e)?.description?.[t]?.[n],r=o?.[s]||o?.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 o=this._map.get(e)?.keyboard?.[t],r=o?.[s]?.[n]||o?.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=(0,C.join)(this._path[s],e);if((0,S.existsSync)(n))return(0,S.writeFileSync)(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()}};var j=require("grammy");var N=class{constructor(e){this.maxSize=e;if(!Number.isFinite(e)||e<=0)throw new Error("WebhookQueue maxSize must be a positive number")}maxSize;static{m(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=(0,B.dirname)((()=>{try{return __filename}catch{return(0,ye.fileURLToPath)(k)}})()),Ae=JSON.parse((0,ge.readFileSync)((0,B.join)(xe,"../../package.json"),"utf-8")).version,ee=class{static{m(this,"Gramstax")}templateManager;cacheKeyboard;cacheSession;pages;optionsPage={shortCallbackData:!1};log;bot;botConfig;webhookQueue;webhookQueueInstance;webhookServer;handlerBotUpdate;deployType;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?V:e.log?e.log:void 0,this.log?.info?.(`Gramstax v${Ae}`),this.cacheSession=e.cacheSession||new K("memory"),this.cacheKeyboard=e.cacheKeyboard||new Map,this.botConfig=e.botConfig,this.webhookQueue=e.webhookQueue,this.templateManager=e.templateManager||new U({path:[(0,B.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.stop()),process.once("SIGTERM",()=>this.stop()),this.hookBeforeStart(),e.deploy.startsWith("polling"))this.deployType="polling",this._runPolling();else if(e.deploy.startsWith("webhook:"))this.deployType="webhook",this._runWebhook(e.deploy.split("webhook:")[1]);else if(e.deploy.startsWith("serverless:"))this.deployType="serverless",this._runServerless(e.deploy.split("serverless:")[1]);else if(e.deploy.startsWith("test"))this.deployType="test";else throw new Error("Params deploy is not valid, expected: polling, webhook:<public-url>, serverless:<your-adapter>")}async stop(){await this.bot.stop(),this.deployType==="webhook"&&(await this.webhookServer?.stop(),this.webhookServer=void 0)}_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 deploy ${t} started: ${n} ${t=="webhook"||t=="serverless"?`(${s})`:""}`),this.hookAfterStart()}createBot(e){return new j.Bot(e,this.botConfig)}createCtx(e){return new q({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:m(e=>{this._onStart(e,"polling",null)},"onStart")})}async _runWebhook(e){let{serve:t}=await import("bun"),s=(0,j.webhookCallback)(this.bot,"bun"),n=this.webhookQueue,i=n?.enabled===!0;this.handlerBotUpdate=i?this.bot.handleUpdate.bind(this.bot):s;let a=i?new N(n?.maxQueueSize??5e3):void 0,o=n?.workerCount??8,r=n?.perChatConcurrency??1,c=n?.blockWhenFull!==!1,h=new Map,l=new Map;this.webhookQueueInstance=a;let u=m(b=>b?.message?.chat?.id??b?.edited_message?.chat?.id??b?.channel_post?.chat?.id??b?.edited_channel_post?.chat?.id??b?.callback_query?.message?.chat?.id??b?.callback_query?.from?.id??b?.inline_query?.from?.id??b?.chosen_inline_result?.from?.id,"getChatId"),d=m(async b=>{if(!i||r<=0||b===void 0||b===null)return()=>{};let _=String(b),I=h.get(_)||0;if(I<r)return h.set(_,I+1),()=>this._releaseWebhookChat(_,h,l);await new Promise(O=>{let re=l.get(_)||[];re.push(O),l.set(_,re)});let P=(h.get(_)||0)+1;return h.set(_,P),()=>this._releaseWebhookChat(_,h,l)},"acquireChat");if(i&&a){await this.bot.init();for(let b=0;b<o;b++)this._startWebhookWorker(a,d,u)}let p=new URL(e),g=p.pathname,f=parseInt(p.port)||3e3,T=this.log,w="/stats_queue";this.webhookServer?.stop();let R=t({port:f,async fetch(b){let{pathname:_}=new URL(b.url);if(b.method=="POST"&&_==g){if(!i||!a)return s(b);if(!c&&a.length>=(n?.maxQueueSize??5e3))return new Response("Queue full",{status:429});try{let I=await b.json();return await a.enqueue(I),new Response("OK",{status:200})}catch(I){return T?.error?.(`Webhook queue error: ${String(I)}`),new Response("Bad Request",{status:400})}}if(b.method=="GET"&&_==w){let I=a?.getStats()||{length:0,maxSize:n?.maxQueueSize??5e3,waitingEnqueue:0,waitingDequeue:0};return new Response(JSON.stringify({enabled:i,path:w,timestamp:new Date().toISOString(),maxQueueSize:n?.maxQueueSize??5e3,workerCount:o,perChatConcurrency:r,blockWhenFull:c,queue:I,activeChats:h.size}),{status:200,headers:{"Content-Type":"application/json"}})}if(b.method=="GET"&&_=="/"){let I=new Date().toISOString();return new Response(JSON.stringify({status:"OK",timestamp:I}),{status:200,headers:{"Content-Type":"application/json"}})}return new Response("Not found",{status:404})}});this.webhookServer=R,(await this.bot.api.getWebhookInfo()).url!=e&&await this.bot.api.setWebhook(e);let F=await this.bot.api.getMe();await this._onStart(F,"webhook",e)}_startWebhookWorker(e,t,s){m(async()=>{for(;;){let i=await e.dequeue(),a=await t(s(i));try{await this.bot.handleUpdate(i)}catch(o){this.log?.error?.(`Webhook worker error: ${String(o)}`)}finally{a()}}},"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 a=s.get(e);a&&a.length>0&&(a.shift()(),a.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=(0,j.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:s}=(0,B.parse)(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,a="handle",o="Args",r="Command",c="Caption",h="Free",l=t.routeDynamic,u=t.routeDynamicSpesific;t.all[n]=e;for(let p of["listRouteStatic","listRouteStaticIntent"]){let g=p==="listRouteStatic"?"lenListRouteStatic":"lenListRouteStaticIntent";for(let f=0;f<t[g];f++){let T=t[p][f];if(typeof i[T]!="function")continue;let w=t.routeStatic[T],R=t.routeStaticIntent[T],D={name:n,routeName:T},F=w||R;if(F!==void 0){let b=T.includes(r),_=T.endsWith("CallbackData"),I=T.endsWith("Text"),P;if(b){let O=e.data.intentCommandText;P=O?`/${O}`:void 0}else if(_){let O=e.data.intentCallbackData;this.optionsPage.shortCallbackData===!0&&(O=String(s),e.data.intentCallbackData=O),P=O}else I?P=e.data.intentText:P=e.data.name;P&&(F[P]=D)}}}for(let p=0;p<t.lenListRouteStaticSession;p++){let g=t.listRouteStaticSession[p];if(typeof i[g]!="function")continue;let f=t.routeStaticSession[g],T={name:n,routeName:g};if(f!==void 0){let w=g.replace("handle",""),D=`methodSession${w.startsWith("Session")?w.slice(7):w}`,F=i[D]?.(n);f[F]=T}}let d=["handleFreeText","handleFreePhoto","handleFreeVideo","handleFreeAudio","handleFreeDocument","handleFreeAnimation","handleFreeVoice","handleFreeVideoNote","handleFreeSticker","handleFreeLocation","handleFreeContact"];for(let p of d)if(Object.hasOwn(i,p)&&typeof i[p]=="function"){let g=p.replace(a,"").replace(o,"").replace(r,"").replace(c,"").replace(h,"").toLowerCase();u[g]?.some(T=>T.name===n)||u[g].push({name:n,routeName:p})}i.handleFree&&l.push(n)}async executeSyncBlocksDescription(e){let t=new Map,s=e?.routeStatic?.handleCommandText;if(s){for(let[,n]of Object.entries(s)){let i=n.name,a=this.templateManager.getDescriptionScopes(i);for(let o of a){t.has(o)||t.set(o,new Set);let r=this.templateManager.getDescriptionLanguage(i,"default",o);for(let c of r)t.get(o).add(c)}}for(let[n,i]of t)for(let a of i){let o=[];for(let[,h]of Object.entries(s)){let l=h.name,u=this.templateManager.getDescription(l,"default",a,n);u&&o.push({command:l,description:u})}if(o.length===0)continue;let r={type:n},c=a==="default"?void 0:a;try{let h=await this.bot.api.getMyCommands({scope:r,language_code:c}),l=JSON.stringify(h.map(d=>({command:d.command,description:d.description})).sort((d,p)=>d.command.localeCompare(p.command))),u=JSON.stringify(o.sort((d,p)=>d.command.localeCompare(p.command)));l!==u&&(await this.bot.api.setMyCommands(o,{scope:r,language_code:c}),this.log?.info?.(`Synced descriptions for scope: ${n},${c?` lang: ${c},`:""} total (${o.length})`))}catch(h){this.log?.error?.(`Failed to sync descriptions for scope: ${n},${c?` lang: ${c},`:""} error: ${String(h)}`)}}}}_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","handleCommandCaptionArgsVoice"],s=m(r=>`handleSession${r.startsWith("handle")?r.slice(6):r}`,"toSession"),n=[...e.map(s),...t.map(s),"handleSessionFreeText","handleSessionFreePhoto","handleSessionFreeVideo","handleSessionFreeAudio","handleSessionFreeDocument","handleSessionFreeAnimation","handleSessionFreeVoice","handleSessionFreeVideoNote","handleSessionFreeSticker","handleSessionFreeLocation","handleSessionFreeContact"],i=m((r,c)=>Object.fromEntries(r.map(h=>[h,c()])),"makeObject"),a=m(()=>[],"initDynamicSpesific"),o={all:{},routeDynamic:[],routeDynamicSpesific:{text:a(),photo:a(),video:a(),audio:a(),document:a(),animation:a(),voice:a(),videonote:a(),sticker:a(),location:a(),contact:a()},routeStatic:i(e,()=>({})),routeStaticIntent:i(t,()=>({})),routeStaticSession:i(n,()=>({})),listRouteStatic:e,listRouteStaticIntent:t,listRouteStaticSession:n,lenListRouteStatic:e.length,lenListRouteStaticIntent:t.length,lenListRouteStaticSession:n.length};return x.getFileManySync(void 0).forEach(({path:r,page:c},h)=>{this._pageBuildData(c,r),this._pageSorts(c,o,h),c.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 a=await e.getSession();if(a){let o=a.method,r=this.pages.routeStaticSession;for(let c=0;c<this.pages.lenListRouteStaticSession;c++){let h=this.pages.listRouteStaticSession[c];if(h.toLowerCase().endsWith(t)&&(n=r[h][o]),n)break}n!==void 0&&(s=this.pages.all[n.name])}}if(s===void 0){let a=e.callbackData,o=e.msgText,r=e.msgCaption,c=this.pages.routeStatic;for(let h=0;h<this.pages.lenListRouteStatic;h++){let l=this.pages.listRouteStatic[h];if(l.toLowerCase().endsWith(t)&&(n=c[l][a||o||r]),n)break}n!==void 0&&(s=this.pages.all[n.name])}if(s===void 0){let a=this.pages.routeStaticIntent,o=t==="callbackdata",r=o?"colon":"space",c=o?e.callbackData:e.msgText||e.msgCaption,h=e.haveArgs(c,r);if(c&&h)for(let l=0;l<this.pages.lenListRouteStaticIntent;l++){let u=this.pages.listRouteStaticIntent[l];if(!u.toLowerCase().endsWith(t))continue;let d=a[u];if(n=d[e.getIntent(c,r,1)],!n&&!o&&(n=d[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 o=await new s(e)[n.routeName]?.();return e.temp.isAnswer===!0?o:null}let i=this.pages.routeDynamicSpesific[t]||[];for(let a=0;a<i.length;a++){let o=i[a];if(o===void 0)continue;let r=this.pages.all[o.name];r!==void 0&&typeof r.prototype[o.routeName]=="function"&&await new r(e)[o.routeName]()}for(let a=0;a<this.pages.routeDynamic.length;a++){let o=this.pages.routeDynamic[a];if(o===void 0)continue;let r=this.pages.all[o];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 te=class{static{m(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 a=m((o,r)=>`<keyboard type="${s}" lang="${r}">${n?this.label._reverse(o):o}</keyboard>`,"pro");return t?a(i[t],t):Object.keys(i).map(o=>a(i[o],o)).join(" ")}};var se=class{static{m(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),{})}};var Y=require("worker_threads");var v=class{constructor(e,t){this.send=e;this.register=t}send;register;static{m(this,"WorkerThreadRpc")}map=new Map;async make(e){let t=this.map,s=this.send,{id:n,method:i,params:a,result:o,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 h=await c.apply(this.register,a);s({id:n,result:h})}catch(c){s({id:n,error:c instanceof Error?{message:c.message,stack:c.stack,name:c.name}:c})}else if(o!==void 0){let c=t.get(n);c&&(c.resolve(o),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(),a={id:i,method:e,params:t,...n};return s?new Promise((o,r)=>{this.map.set(i,{resolve:o,reject:r}),this.send(a)}):this.send(a)}};var Q=class{constructor(e,t,s){this.path=e;this.argv=t;this.register=s;this.init(),s||(s=this),this.rpc=new v(this.send.bind(this),s)}path;argv;register;static{m(this,"WorkerThreadLaunch")}static isMainThread=Y.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 Y.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,s=!0,n){return this.rpc.makeRequest(e,t,s,n)}};var ne=class y{static{m(this,"WorkerThreadExport")}static launchGatewayClient(e){let t=new Proxy({},{get(n,i){if(!(typeof i!="string"||i==="then"))return async(a,...o)=>{let r=a.gatewayClients.get(e);return r||(r=await a.createGatewayClient(e)),r.request(i,o)}}}),s=m(function(n){return new Proxy({},{get(i,a){if(!(typeof a!="string"||a==="then"))return async(...o)=>{let r=n.gatewayClients.get(e);return r||(r=await n.createGatewayClient(e)),r.request(a,o)}}})},"ctor");return Object.setPrototypeOf(s,t),s}static init(e){let{WTInit:t,WTLaunch:s=Q,path:n,wrap:i}=e,a=`for-${n}`;if(process.argv[2]===a)return new t,{launchGatewayClient:m(l=>y.launchGatewayClient(l||t.gatewayServerPath),"launchGatewayClient")};let o,r=new Proxy({},{get(l,u){if(u!=="then")return u==="sendRequest"||u==="request"||u==="kill"||u==="send"?(...d)=>{if(!o)throw new Error(`Thread at ${n} not launched yet.`);return o[u](...d)}:(...d)=>{if(!o)throw new Error(`Thread at ${n} not launched yet.`);return o.request(u,d)}}}),h={...i?i(r):{},launchWorker:m(async(l=[])=>(o=new s(n,[a,...l]),await o.ready(),o),"launchWorker"),launchGatewayClient:m(l=>y.launchGatewayClient(l||t.gatewayServerPath),"launchGatewayClient")};return new Proxy(h,{get(l,u){if(u!=="then")return u==="launchGatewayClient"?l.launchGatewayClient:u==="launchWorker"?l.launchWorker:u in l?l[u]:typeof u=="string"?(...d)=>{if(!o)throw new Error(`Thread at ${n} not launched yet.`);return o.request(u,d)}:l[u]}})}};var fe=require("net-ipc");var H=class{static{m(this,"WorkerThreadGatewayClient")}client=new fe.Client;rpc;constructor(){this.rpc=new v(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)}};var be=require("net-ipc");var z=class{static{m(this,"WorkerThreadGatewayServer")}server=new be.Server;rpc=new Map;register={};constructor(){this.server.on("connect",e=>{let t=new v(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}};var L=require("worker_threads");var ie=class{static{m(this,"WorkerThreadInit")}argv=process.argv;id=L.threadId;pid=process.pid;rpc={};parentPort=L.parentPort;gatewayServer;gatewayClients=new Map;gatewayClientLatest;static gatewayServerPath;gatewayServerPath=this.constructor.gatewayServerPath;get gatewayClient(){return this.gatewayClientLatest}static isMainThread=L.isMainThread;constructor(){this.init(),this.rpc=new v(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 z,await this.gatewayServer.start(t,e),this.constructor.gatewayServerPath=t,!0}async createGatewayClient(e){let t=new H;return await t.connect(e),this.gatewayClients.set(e,t),this.gatewayClientLatest=t,t}};var ae=class{static{m(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 oe=class{static{m(this,"MockTelegramServer")}botToken="";hostname;port;log;handlers;defaultHandler;apiRoot="";webhookUrl="";requests=[];updates=[];server;_nextUpdateId=1;_nextMessageId=1;constructor(e={}){this.hostname=e.hostname??"127.0.0.1",this.port=e.port??0,this.log=e.log===!0?V:e.log?e.log:void 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:m(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.log?.info?.(`Mock Telegram server started: ${this.apiRoot}`),this.apiRoot}async stop(){this.server?.stop(),this.server=void 0,this.log?.info?.("Mock Telegram server stopped")}_json(e){return new Response(JSON.stringify(e),{status:200,headers:{"Content-Type":"application/json"}})}lastRequest(e){if(!e)return this.requests[this.requests.length-1];for(let t=this.requests.length-1;t>=0;t--){let s=this.requests[t];if(s?.method===e)return s}}clearRequests(){this.requests.length=0}_defaultResponse(e,t){if(e==="getMe")return{ok:!0,result:{id:123456789,is_bot:!0,first_name:"Mock",username:"mock_gramstax_bot"}};if(e==="getUpdates")return{ok:!0,result:[]};if(e==="getMyCommands")return{ok:!0,result:[]};if(e==="setMyCommands")return{ok:!0,result:!0};if(e==="setWebhook"){let s=this._bodyRecord(t),n=typeof s?.url=="string"?s.url:"";return this.webhookUrl=n,this.log?.info?.(`Mock Telegram webhook set: ${n}`),{ok:!0,result:!0}}return e==="getWebhookInfo"?{ok:!0,result:{url:this.webhookUrl}}:{ok:!0,result:!0}}async _handleRequest(e){let{pathname:t}=new URL(e.url),s=t.match(/^\/bot([^/]+)\/(.+)$/);if(!s)return new Response("Not found",{status:404});let n=s[1],i=s[2];if(!n||!i)return new Response("Not found",{status:404});this.botToken=n;let a=await this._readBody(e.clone());this.log?.debug?.(`Mock Telegram API request: ${i}`),this.requests.push({method:i,body:a,url:e.url,requestMethod:e.method,headers:Object.fromEntries(e.headers.entries())});let o=this.handlers[i]??this.defaultHandler,r=o?await o({method:i,request:e}):this._defaultResponse(i,a);return this._json(r)}_bodyRecord(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}async _readBody(e){if(e.method==="GET"||e.method==="HEAD")return;let t=e.headers.get("content-type")||"";try{if(t.includes("application/json"))return await e.json();if(t.includes("multipart/form-data")||t.includes("application/x-www-form-urlencoded")){let n=await e.formData();return Object.fromEntries(n.entries())}let s=await e.text();if(!s)return;try{return JSON.parse(s)}catch{return s}}catch{return}}_defaultUser(e){return{id:e?.id??1001,is_bot:e?.is_bot??!1,first_name:e?.first_name??"Test",...e?.last_name?{last_name:e.last_name}:{},...e?.username?{username:e.username}:{},language_code:e?.language_code??"en"}}_defaultChat(e){return{id:e?.id??1001,type:e?.type??"private",first_name:e?.first_name??"Test",...e?.last_name?{last_name:e.last_name}:{},...e?.username?{username:e.username}:{},...e?.title?{title:e.title}:{}}}_nextIds(e){return{updateId:this._nextUpdateId++,messageId:e?.message_id??this._nextMessageId++,date:e?.date??Math.floor(Date.now()/1e3)}}_buildMessageUpdate(e,t){let{updateId:s,messageId:n,date:i}=this._nextIds(t);return{update_id:s,message:{message_id:n,date:i,chat:this._defaultChat(t?.chat),from:this._defaultUser(t?.user),...e}}}async _postUpdate(e,t){if(await this._waitForWebhookUrl(t?.responseTimeoutMs??1e3),!this.webhookUrl)throw new Error("Webhook URL is not set. Call setWebhook first or assign mockServer.webhookUrl.");let s=this.requests.length;this.updates.push(e),this.log?.info?.(`Mock Telegram update sent: ${this.webhookUrl}`);let n=await fetch(this.webhookUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!n.ok)throw new Error(`Webhook request failed with status ${n.status}`);let i=await this._waitForResponses(s,t?.responseTimeoutMs??1e3);return this.log?.info?.(`Mock Telegram bot responses captured: ${i.length}`),i}async _waitForWebhookUrl(e){if(this.webhookUrl||e<=0)return this.webhookUrl;let t=Date.now();for(;Date.now()-t<e&&(await new Promise(s=>setTimeout(s,5)),!this.webhookUrl););return this.webhookUrl}async _waitForResponses(e,t){if(t<=0)return this._userResponseRequests(e);if(this._userResponseRequests(e).length>0)return this._userResponseRequests(e);let s=Date.now();for(;Date.now()-s<t&&(await new Promise(n=>setTimeout(n,5)),!(this._userResponseRequests(e).length>0)););return this._userResponseRequests(e)}_userResponseRequests(e){return this.requests.slice(e).filter(t=>this._isUserResponseMethod(t.method))}_isUserResponseMethod(e){return e.startsWith("send")||e.startsWith("edit")||e.startsWith("answer")||e.startsWith("delete")||e.startsWith("copy")||e.startsWith("forward")||e==="pinChatMessage"||e==="unpinChatMessage"||e==="setMessageReaction"}async sendText(e,t){let s=e.startsWith("/")?[{offset:0,length:e.split(" ")[0]?.length??e.length,type:"bot_command"}]:void 0;return await this._postUpdate(this._buildMessageUpdate({text:e,...s?{entities:s}:{}},t),t)}async sendPhoto(e){return await this._postUpdate(this._buildMessageUpdate({photo:[{file_id:"mock-photo-file-id",file_unique_id:"mock-photo-unique-id",width:1,height:1}],...e?.caption?{caption:e.caption}:{}},e),e)}async sendVideo(e){return await this._postUpdate(this._buildMessageUpdate({video:{file_id:"mock-video-file-id",file_unique_id:"mock-video-unique-id",width:1,height:1,duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendAudio(e){return await this._postUpdate(this._buildMessageUpdate({audio:{file_id:"mock-audio-file-id",file_unique_id:"mock-audio-unique-id",duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendDocument(e){return await this._postUpdate(this._buildMessageUpdate({document:{file_id:"mock-document-file-id",file_unique_id:"mock-document-unique-id",file_name:"mock.txt"},...e?.caption?{caption:e.caption}:{}},e),e)}async sendAnimation(e){return await this._postUpdate(this._buildMessageUpdate({animation:{file_id:"mock-animation-file-id",file_unique_id:"mock-animation-unique-id",width:1,height:1,duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendVoice(e){return await this._postUpdate(this._buildMessageUpdate({voice:{file_id:"mock-voice-file-id",file_unique_id:"mock-voice-unique-id",duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendVideoNote(e){return await this._postUpdate(this._buildMessageUpdate({video_note:{file_id:"mock-video-note-file-id",file_unique_id:"mock-video-note-unique-id",length:1,duration:1}},e),e)}async sendSticker(e){return await this._postUpdate(this._buildMessageUpdate({sticker:{file_id:"mock-sticker-file-id",file_unique_id:"mock-sticker-unique-id",type:"regular",width:1,height:1,is_animated:!1,is_video:!1}},e),e)}async sendLocation(e){return await this._postUpdate(this._buildMessageUpdate({location:{latitude:e?.latitude??0,longitude:e?.longitude??0}},e),e)}async sendContact(e){return await this._postUpdate(this._buildMessageUpdate({contact:{phone_number:e?.phone_number??"+10000000000",first_name:e?.first_name??"Test",...e?.last_name?{last_name:e.last_name}:{},...e?.user_id?{user_id:e.user_id}:{}}},e),e)}async sendCallbackQuery(e,t){let{updateId:s,messageId:n,date:i}=this._nextIds(t);return await this._postUpdate({update_id:s,callback_query:{id:t?.id??`mock-callback-${s}`,from:this._defaultUser(t?.user),message:{message_id:n,date:i,chat:this._defaultChat(t?.chat),text:t?.messageText??"Mock message"},chat_instance:"mock-chat-instance",data:e}},t)}};0&&(module.exports={BlockKeyboard,CacheExternal,Ctx,Gramstax,LabelKeyboard,LoggingHelper,MockTelegramServer,PageManager,TemplateEngine,TemplateManager,WebhookQueue,WorkerThreadExport,WorkerThreadGatewayClient,WorkerThreadGatewayServer,WorkerThreadInit,WorkerThreadLaunch,WorkerThreadPool,WorkerThreadRpc,log});
|
package/dist/src/index.js
CHANGED
|
@@ -4,4 +4,4 @@ var ue=Object.defineProperty;var m=(y,e)=>ue(y,"name",{value:e,configurable:!0})
|
|
|
4
4
|
`):h.map(d=>l(d.innerContent)).join(`
|
|
5
5
|
`)}return o}static _processImportBlocks(e){let t=/([ \t]*)<import(?:\s+([^>]*))?\/?>/gi,s=[];return{processed:e.replace(t,(i,a,o)=>{let r={},c=/(\w+)="([^"]*)"/g;if(o)for(let d of o.matchAll(c))r[d[1]]=d[2];let h=r.src;if(!h)return"";let l;r.block&&(r.block==="all"?l="all":r.block.includes(",")?l=r.block.split(",").map(d=>d.trim()).filter(d=>d):l=r.block);let p={src:h,blocks:l,base:r.base||"default",lang:r.lang,section:r.section||"all",indent:a||""};return s.push(p),`${a}__IMPORT_${s.length-1}__`}),imports:s}}static processImportBlocks(e,t,s=0,n){if(s>10)return"";let{processed:i,imports:a}=this._processImportBlocks(e),o=i;for(let r=0;r<a.length;r++){let c=a[r],h=`${c.src}|${c.base}|${c.lang||""}|${c.section}|${Array.isArray(c.blocks)?c.blocks.join(","):c.blocks||""}`,l;if(n&&n.has(h))l=n.get(h);else{let d=t(c.src);l=d?this._extractBlock(d,c.blocks,c.base,c.section,c.lang):"",l&&l.includes("<import")&&(l=this.processImportBlocks(l,t,s+1,n)),n&&n.set(h,l)}let p=l.split(`
|
|
6
6
|
`).map((d,u)=>u===0?d:c.indent+d).join(`
|
|
7
|
-
`);o=o.replace(`__IMPORT_${r}__`,p)}return o}static validateNamesBlock(e){let t=[],s=new Set(y.ALLOWED_BLOCKS.map(a=>a.replace(/^<\/?/,"").replace(/\s.*?>$/,"").replace(/\/?>$/,"").toLowerCase())),n=new Set(["b","i","u","s","code","pre","a","blockquote"]),i=/<\/?\s*([a-z][\w-]*)(?:\s[^<>]*)?\/?\s*>/gi;for(let a of e.matchAll(i)){let o=a[1]?.toLowerCase();if(!o||n.has(o)||s.has(o))continue;let r=(e.slice(0,a.index).match(/\n/g)||[]).length+1;t.push({line:r,message:`Unsupported template block: <${o}>`})}return{valid:t.length===0,errors:t}}static validateScopes(e){let t=[],s=new Set(y.ALLOWED_SCOPE),n=/\{([^\s{}\w])([\s\S]*?)\1\}/g;for(let i of e.matchAll(n)){let a=`{${i[1]}${i[1]}}`;if(i[1]&&s.has(a))continue;let o=(e.slice(0,i.index).match(/\n/g)||[]).length+1,r=i[1]??"?";t.push({line:o,message:`Unsupported template scope: {${r} ${r}}`})}return{valid:t.length===0,errors:t}}static validatePositionsBlock(e){let t=[],s=[],n=new Set(["b","i","u","s","code","pre","a","blockquote"]),i={base:new Set(["__root__"]),message:new Set(["base"]),keyboard:new Set(["base"]),media:new Set(["base","media-group"]),"media-group":new Set(["base"]),description:new Set(["base"]),switch:new Set(["message","keyboard","media","description"]),case:new Set(["switch"]),default:new Set(["switch"]),map:new Set(["message","keyboard","media","description"]),div:new Set(["base","message","description","keyboard","case","default","map"]),script:new Set(["base","message","description","keyboard","case","default","map","div"]),import:new Set(["base"]),space:new Set(["base","message","description","keyboard","case","default","switch","map","div"])},a=/<(\/?)(\w[\w-]*)([^>]*)>/g,o;for(;(o=a.exec(e))!==null;){let r=o[0],c=o[1],h=o[2].toLowerCase(),l=c==="/",p=!l&&r.endsWith("/>");if(n.has(h)||!i[h])continue;let d=(e.slice(0,o.index).match(/\n/g)||[]).length+1;if(l)if(s.length===0)t.push({line:d,message:`Unexpected closing tag </${h}>: no matching opening tag`});else{let u=s[s.length-1];u.block!==h?t.push({line:d,message:`Mismatched closing tag: expected </${u.block}> but found </${h}>`}):s.pop()}else if(p){let u=s.length>0?s[s.length-1].block:"__root__";i[h].has(u)||t.push({line:d,message:`Block <${h}> is not allowed inside <${u}>`})}else{let u=s.length>0?s[s.length-1].block:"__root__";i[h].has(u)||t.push({line:d,message:`Block <${h}> is not allowed inside <${u}>`}),s.push({block:h,line:d})}}for(let r of s)t.push({line:r.line,message:`Unclosed block <${r.block}>: missing closing tag </${r.block}>`});if(t.length===0){let r=[],c=/<base\b[^>]*>[\s\S]*?<\/base>/g,h;for(;(h=c.exec(e))!==null;)r.push({start:h.index,end:h.index+h[0].length});if(r.length===0&&e.trim())t.push({line:1,message:"Missing <base> block: template content must be wrapped in <base>...</base>"});else{let l=0;for(let p of r){if(p.start>l&&e.slice(l,p.start).trim()){let u=(e.slice(0,l).match(/\n/g)||[]).length+1;t.push({line:u,message:"Content found outside <base> block: move content inside a <base>...</base>"});break}l=p.end}if(t.length===0&&l<e.length&&e.slice(l).trim()){let p=(e.slice(0,l).match(/\n/g)||[]).length+1;t.push({line:p,message:"Content found outside <base> block: move content inside a <base>...</base>"})}}}return{valid:t.length===0,errors:t}}static validateFormatBlock(e){let t=[],s=new Set(["space","import"]),n=new Set(["base","message","keyboard","media","media-group","description","script","switch","case","default","map","div"]),i=/<(\/?)(\w[\w-]*)([^>]*)>/g,a;for(;(a=i.exec(e))!==null;){let o=a[0],r=a[1],c=a[2].toLowerCase(),h=r==="/",l=!h&&o.endsWith("/>");if(h)continue;let p=(e.slice(0,a.index).match(/\n/g)||[]).length+1;l?n.has(c)&&t.push({line:p,message:`Block <${c}> must not be self-closing: use <${c}>...</${c}> instead`}):s.has(c)&&t.push({line:p,message:`Block <${c}> must be self-closing: use <${c} /> instead`})}return{valid:t.length===0,errors:t}}static _validateBlockAttributes(e,t,s,n,i){let a=[],o=new RegExp(`<${t}(?![\\w-])([^>]*?)>`,"g"),r;for(;(r=o.exec(e))!==null;){let c=r[1].trim();if(!c)continue;let h=(e.slice(0,r.index).match(/\n/g)||[]).length+1,l=/([\w-]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+))/g,p;for(;(p=l.exec(c))!==null;){let d=p[1].toLowerCase();if(!s.has(d)){let u=s.size===0?"no attributes are allowed":`only ${n} is allowed`;a.push({line:h,message:`Unknown attribute "${p[1]}" on <${t}>: ${u}`});continue}if(i?.[d]){let u=p[2]??p[3]??p[4]??"",g=i[d](u);g&&a.push({line:h,message:g})}}}return a}static validateBlockBaseAttributes(e){let t=this._validateBlockAttributes(e,"base",new Set(["id"]),'"id"',{id:m(s=>s?null:'Attribute "id" on <base> must not be empty',"id")});return{valid:t.length===0,errors:t}}static validateBlockMessageAttributes(e){let t=this._validateBlockAttributes(e,"message",new Set(["lang"]),'"lang"');return{valid:t.length===0,errors:t}}static validateBlockKeyboardAttributes(e){let t=this._validateBlockAttributes(e,"keyboard",new Set(["lang","type"]),'"lang" and "type"',{type:m(s=>s==="inline"||s==="bottom"?null:`Attribute "type" on <keyboard> must be "inline" or "bottom", got "${s}"`,"type")});return{valid:t.length===0,errors:t}}static validateBlockMediaAttributes(e){let t=new Set(["photo","video","audio","document","animation","voice","video_note","sticker","location","contact"]),s=this._validateBlockAttributes(e,"media",new Set(["lang","type","src","shared","latitude","longitude","phone","first_name","last_name","vcard"]),'"lang", "type", "src", "shared", "latitude", "longitude", "phone", "first_name", "last_name", and "vcard"',{type:m(n=>t.has(n)?null:`Attribute "type" on <media> must be one of: ${[...t].join(", ")}, got "${n}"`,"type"),shared:m(n=>n==="true"||n==="false"?null:`Attribute "shared" on <media> must be "true" or "false", got "${n}"`,"shared")});return{valid:s.length===0,errors:s}}static validateBlockMediaGroupAttributes(e){let t=this._validateBlockAttributes(e,"media-group",new Set(["lang"]),'"lang"');return t.push(...this._validateMediaGroupItems(e)),{valid:t.length===0,errors:t}}static _validateMediaGroupItems(e){let t=[],s=/<media-group(?:\s+[^>]*)?>([\s\S]*?)<\/media-group>/gi,n=/<media(?:\s+([^>]*))?>([\s\S]*?)<\/media>/gi,i=new Set(["photo","video","audio","document"]);for(let a of e.matchAll(s)){let o=(e.slice(0,a.index).match(/\n/g)||[]).length+1,r=a[1]||"",c=[],h=0;for(let p of r.matchAll(n)){h+=1;let d=o+(r.slice(0,p.index).match(/\n/g)||[]).length,u=p[1]||"",g=u.match(/\btype\s*=\s*"([^"]*)"/)?.[1],f=u.match(/\bsrc\s*=\s*"([^"]*)"/)?.[1];if(!g||!i.has(g)){t.push({line:d,message:'Attribute "type" on <media> inside <media-group> must be one of: photo, video, audio, document'});continue}f||t.push({line:d,message:'Attribute "src" on <media> inside <media-group> is required'}),c.push(g)}h===0&&t.push({line:o,message:"<media-group> must contain at least one <media> item"}),h>this.MAX_MEDIA_GROUP_ITEMS&&t.push({line:o,message:`<media-group> must contain at most ${this.MAX_MEDIA_GROUP_ITEMS} <media> items`});let l=new Set(c);l.has("audio")&&l.size>1&&t.push({line:o,message:"<media-group> with audio items can only contain audio items"}),l.has("document")&&l.size>1&&t.push({line:o,message:"<media-group> with document items can only contain document items"})}return t}static validateBlockDescriptionAttributes(e){let t=this._validateBlockAttributes(e,"description",new Set(["lang","scope"]),'"lang" and "scope"');return{valid:t.length===0,errors:t}}static validateBlockScriptAttributes(e){let t=this._validateBlockAttributes(e,"script",new Set,"");return{valid:t.length===0,errors:t}}static validateBlockSwitchAttributes(e){let t=this._validateBlockAttributes(e,"switch",new Set(["value"]),'"value"');return{valid:t.length===0,errors:t}}static validateBlockCaseAttributes(e){let t=this._validateBlockAttributes(e,"case",new Set(["is"]),'"is"');return{valid:t.length===0,errors:t}}static validateBlockDefaultAttributes(e){let t=this._validateBlockAttributes(e,"default",new Set,"");return{valid:t.length===0,errors:t}}static validateBlockMapAttributes(e){let t=this._validateBlockAttributes(e,"map",new Set(["src","join"]),'"src" and "join"');return{valid:t.length===0,errors:t}}static validateBlockDivAttributes(e){let t=this._validateBlockAttributes(e,"div",new Set,"");return{valid:t.length===0,errors:t}}static validateBlockImportAttributes(e){let t=this._validateBlockAttributes(e,"import",new Set(["src","block","base","lang","section"]),'"src", "block", "base", "lang", and "section"');return{valid:t.length===0,errors:t}}static validateBlockSpaceAttributes(e){let t=this._validateBlockAttributes(e,"space",new Set,"");return{valid:t.length===0,errors:t}}static validateTemplate(e){let t=this.validateNamesBlock(e),s=this.validateScopes(e),n=this.validateFormatBlock(e),i=this.validatePositionsBlock(e),a=this.validateBlockBaseAttributes(e),o=this.validateBlockMessageAttributes(e),r=this.validateBlockKeyboardAttributes(e),c=this.validateBlockMediaAttributes(e),h=this.validateBlockMediaGroupAttributes(e),l=this.validateBlockDescriptionAttributes(e),p=this.validateBlockScriptAttributes(e),d=this.validateBlockSwitchAttributes(e),u=this.validateBlockCaseAttributes(e),g=this.validateBlockDefaultAttributes(e),f=this.validateBlockMapAttributes(e),T=this.validateBlockDivAttributes(e),w=this.validateBlockImportAttributes(e),A=this.validateBlockSpaceAttributes(e),O=[...t.errors,...s.errors,...n.errors,...i.errors,...a.errors,...o.errors,...r.errors,...c.errors,...h.errors,...l.errors,...p.errors,...d.errors,...u.errors,...g.errors,...f.errors,...T.errors,...w.errors,...A.errors];return{valid:O.length===0,errors:O}}};var G=class{static{m(this,"TemplateManager")}_map=new Map;_engine=x;_watcher=[];_pageManager=M;_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(!F(t))throw new Error(`Template base path is not exists: ${t}`);if(!$(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=we(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=X(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileAdd(e){let t=X(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileDelete(e){let t=X(e),s=this._getKey(t);this._map.has(s)&&this._map.delete(s)}_handleWatchError(e){}_loadAllFiles(){let e=new Map,t=new Map,s=[];for(let i=0;i<this._path.length;i++){let a=this._path[i],r=ke(a,"utf8").filter(c=>this._isValidFile(c));for(let c of r){let h=D(a,c),l=this._getExtension(c),p=this._getKey(c);if(l===".html")e.set(p,K(h,"utf8")),t.set(p,c);else if(l===".ts"||l===".js"){let d=M.getFileSync(h);d?.template!==void 0&&(e.set(p,d.template),t.set(p,c),s.push(d))}}}let n=new Map;for(let[i,a]of e.entries())this._compile(i,a,void 0,n,e,t.get(i));e.clear(),n.clear();for(let i of s)i.template=void 0}_loadFile(e){for(let t=0;t<this._path.length;t++){let s=this._path[t],n=D(s,e),i=this._getExtension(e),a=this._getKey(e);if(i==".html"){let o=K(n,"utf8");this._compile(a,o,void 0,void 0,void 0,e)}else if(i==".ts"||i==".js"){let o=M.getFileSync(n);o?.template!==void 0&&(this._compile(a,o.template,void 0,void 0,void 0,e),o.template=void 0)}else throw new Error(`File ${e} is not support`)}}_getExtension(e){return ne(e).toLowerCase()}_readTemplateFile(e){for(let t of this._path){let s=ne(e).toLowerCase();if(s){let o=D(t,e);if(F(o)&&$(o).isFile()){if(s===".html")return K(o,"utf8");if(s===".ts"||s===".js")try{return M.getFileSync(o)?.template??null}catch{return null}}continue}let n=D(t,`${e}.ts`),i=D(t,`${e}.js`);if(F(n)&&$(n).isFile())try{return M.getFileSync(n)?.template??null}catch{}else if(F(i)&&$(i).isFile())try{return M.getFileSync(n)?.template??null}catch{}let a=D(t,`${e}.html`);if(F(a)&&$(a).isFile())return K(a,"utf8")}return null}_isValidFile(e){return this._supportedExtensions.has(this._getExtension(e))}_getBaseAtLine(e,t){let s=/<base\b([^>]*?)>/gi,n=/<\/base>/gi,i=t,a,o;for(;(a=s.exec(e))!==null&&!((e.slice(0,a.index).match(/\n/g)||[]).length+1>i);){let h=a[1].match(/\sid\s*=\s*(["']?)([^"'\s>]+)\1/i),l=h?.[2]??null,p=!!h;for(n.lastIndex||(n.lastIndex=s.lastIndex);(o=n.exec(e))!==null;){if((e.slice(0,o.index).match(/\n/g)||[]).length+1>i)return{baseId:l,hasId:p};s.lastIndex=n.lastIndex;break}}return null}_validateTemplate(e,t,s=e){let n=x.validateTemplate(t);if(!n.valid&&n.errors.length>0){let i=n.errors[0],a=this._getBaseAtLine(t,i.line),o=a?.hasId?` on base "${a.baseId}"`:"",r=`${s}, line ${i.line}`;throw new Error(`Template${o} (${r}): ${i.message}`)}}_getKey(e){return e.replace(/\.[^/.]+$/,"")}_compile(e,t,s,n,i,a=e){let o=this._map.get(e),r=o||{},c=!1;this._validateTemplate(e,t,a);let h=x.processImportBlocks(t,p=>i&&i.has(p)?i.get(p):this._readTemplateFile(p),0,n);this._validateTemplate(e,h,a);let l=x._processBaseBlocks(h);(s===void 0||s?.media===!1||o?.media===void 0)&&(r.media=x.compileBlockMedia(h,l),c=!0),(s===void 0||s?.message===!1||o?.message===void 0)&&(r.message=x.compileBlockMessage(h,l),c=!0),(s===void 0||s?.keyboard===!1||o?.keyboard===void 0)&&(r.keyboard=x.compileBlockKeyboards(h,l),c=!0),(s===void 0||s?.description===!1||o?.description===void 0)&&(r.description=x.compileBlockDescription(h,l),c=!0),c&&this._map.set(e,r)}getMedia(e,t="default",s="default",n){let a=this._map.get(e)?.media?.[t],o=a?.[s]||a?.default;try{if(!o)throw new Error("Media function not found, please check your template");return o(n)}catch{return{}}}getMessage(e,t="default",s="default",n){try{let a=this._map.get(e)?.message?.[t],o=a?.[s]||a?.default;if(!o)throw"";return o(n)}catch{return""}}getDescription(e,t="default",s="default",n="default",i){try{let o=this._map.get(e)?.description?.[t]?.[n],r=o?.[s]||o?.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 o=this._map.get(e)?.keyboard?.[t],r=o?.[s]?.[n]||o?.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=D(this._path[s],e);if(F(n))return Se(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 xe,webhookCallback as ie}from"grammy";var q=class{constructor(e){this.maxSize=e;if(!Number.isFinite(e)||e<=0)throw new Error("WebhookQueue maxSize must be a positive number")}maxSize;static{m(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 Ae=Ie((()=>{try{return k}catch{return _e(import.meta.url)}})()),ve=JSON.parse(Ce(oe(Ae,"../../package.json"),"utf-8")).version,ae=class{static{m(this,"Gramstax")}templateManager;cacheKeyboard;cacheSession;pages;optionsPage={shortCallbackData:!1};log;bot;botConfig;webhookQueue;webhookQueueInstance;webhookServer;handlerBotUpdate;deployType;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?W:e.log?e.log:void 0,this.log?.info?.(`Gramstax v${ve}`),this.cacheSession=e.cacheSession||new L("memory"),this.cacheKeyboard=e.cacheKeyboard||new Map,this.botConfig=e.botConfig,this.webhookQueue=e.webhookQueue,this.templateManager=e.templateManager||new G({path:[oe(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.stop()),process.once("SIGTERM",()=>this.stop()),this.hookBeforeStart(),e.deploy.startsWith("polling"))this.deployType="polling",this._runPolling();else if(e.deploy.startsWith("webhook:"))this.deployType="webhook",this._runWebhook(e.deploy.split("webhook:")[1]);else if(e.deploy.startsWith("serverless:"))this.deployType="serverless",this._runServerless(e.deploy.split("serverless:")[1]);else if(e.deploy.startsWith("test"))this.deployType="test";else throw new Error("Params deploy is not valid, expected: polling, webhook:<public-url>, serverless:<your-adapter>")}async stop(){await this.bot.stop(),this.deployType==="webhook"&&(await this.webhookServer?.stop(),this.webhookServer=void 0)}_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 deploy ${t} started: ${n} ${t=="webhook"||t=="serverless"?`(${s})`:""}`),this.hookAfterStart()}createBot(e){return new xe(e,this.botConfig)}createCtx(e){return new V({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:m(e=>{this._onStart(e,"polling",null)},"onStart")})}async _runWebhook(e){let{serve:t}=await import("bun"),s=ie(this.bot,"bun"),n=this.webhookQueue,i=n?.enabled===!0;this.handlerBotUpdate=i?this.bot.handleUpdate.bind(this.bot):s;let a=i?new q(n?.maxQueueSize??5e3):void 0,o=n?.workerCount??8,r=n?.perChatConcurrency??1,c=n?.blockWhenFull!==!1,h=new Map,l=new Map;this.webhookQueueInstance=a;let p=m(b=>b?.message?.chat?.id??b?.edited_message?.chat?.id??b?.channel_post?.chat?.id??b?.edited_channel_post?.chat?.id??b?.callback_query?.message?.chat?.id??b?.callback_query?.from?.id??b?.inline_query?.from?.id??b?.chosen_inline_result?.from?.id,"getChatId"),d=m(async b=>{if(!i||r<=0||b===void 0||b===null)return()=>{};let C=String(b),_=h.get(C)||0;if(_<r)return h.set(C,_+1),()=>this._releaseWebhookChat(C,h,l);await new Promise(P=>{let Y=l.get(C)||[];Y.push(P),l.set(C,Y)});let R=(h.get(C)||0)+1;return h.set(C,R),()=>this._releaseWebhookChat(C,h,l)},"acquireChat");if(i&&a){await this.bot.init();for(let b=0;b<o;b++)this._startWebhookWorker(a,d,p)}let u=new URL(e),g=u.pathname,f=parseInt(u.port)||3e3,T=this.log,w="/stats_queue";this.webhookServer?.stop();let A=t({port:f,async fetch(b){let{pathname:C}=new URL(b.url);if(b.method=="POST"&&C==g){if(!i||!a)return s(b);if(!c&&a.length>=(n?.maxQueueSize??5e3))return new Response("Queue full",{status:429});try{let _=await b.json();return await a.enqueue(_),new Response("OK",{status:200})}catch(_){return T?.error?.(`Webhook queue error: ${String(_)}`),new Response("Bad Request",{status:400})}}if(b.method=="GET"&&C==w){let _=a?.getStats()||{length:0,maxSize:n?.maxQueueSize??5e3,waitingEnqueue:0,waitingDequeue:0};return new Response(JSON.stringify({enabled:i,path:w,timestamp:new Date().toISOString(),maxQueueSize:n?.maxQueueSize??5e3,workerCount:o,perChatConcurrency:r,blockWhenFull:c,queue:_,activeChats:h.size}),{status:200,headers:{"Content-Type":"application/json"}})}if(b.method=="GET"&&C=="/"){let _=new Date().toISOString();return new Response(JSON.stringify({status:"OK",timestamp:_}),{status:200,headers:{"Content-Type":"application/json"}})}return new Response("Not found",{status:404})}});this.webhookServer=A,(await this.bot.api.getWebhookInfo()).url!=e&&await this.bot.api.setWebhook(e);let B=await this.bot.api.getMe();await this._onStart(B,"webhook",e)}_startWebhookWorker(e,t,s){m(async()=>{for(;;){let i=await e.dequeue(),a=await t(s(i));try{await this.bot.handleUpdate(i)}catch(o){this.log?.error?.(`Webhook worker error: ${String(o)}`)}finally{a()}}},"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 a=s.get(e);a&&a.length>0&&(a.shift()(),a.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=ie(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}=Me(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,a="handle",o="Args",r="Command",c="Caption",h="Free",l=t.routeDynamic,p=t.routeDynamicSpesific;t.all[n]=e;for(let u of["listRouteStatic","listRouteStaticIntent"]){let g=u==="listRouteStatic"?"lenListRouteStatic":"lenListRouteStaticIntent";for(let f=0;f<t[g];f++){let T=t[u][f];if(typeof i[T]!="function")continue;let w=t.routeStatic[T],A=t.routeStaticIntent[T],O={name:n,routeName:T},B=w||A;if(B!==void 0){let b=T.includes(r),C=T.endsWith("CallbackData"),_=T.endsWith("Text"),R;if(b){let P=e.data.intentCommandText;R=P?`/${P}`:void 0}else if(C){let P=e.data.intentCallbackData;this.optionsPage.shortCallbackData===!0&&(P=String(s),e.data.intentCallbackData=P),R=P}else _?R=e.data.intentText:R=e.data.name;R&&(B[R]=O)}}}for(let u=0;u<t.lenListRouteStaticSession;u++){let g=t.listRouteStaticSession[u];if(typeof i[g]!="function")continue;let f=t.routeStaticSession[g],T={name:n,routeName:g};if(f!==void 0){let w=g.replace("handle",""),O=`methodSession${w.startsWith("Session")?w.slice(7):w}`,B=i[O]?.(n);f[B]=T}}let d=["handleFreeText","handleFreePhoto","handleFreeVideo","handleFreeAudio","handleFreeDocument","handleFreeAnimation","handleFreeVoice","handleFreeVideoNote","handleFreeSticker","handleFreeLocation","handleFreeContact"];for(let u of d)if(Object.hasOwn(i,u)&&typeof i[u]=="function"){let g=u.replace(a,"").replace(o,"").replace(r,"").replace(c,"").replace(h,"").toLowerCase();p[g]?.some(T=>T.name===n)||p[g].push({name:n,routeName:u})}i.handleFree&&l.push(n)}async executeSyncBlocksDescription(e){let t=new Map,s=e.routeStatic.handleCommandText;for(let[,n]of Object.entries(s)){let i=n.name,a=this.templateManager.getDescriptionScopes(i);for(let o of a){t.has(o)||t.set(o,new Set);let r=this.templateManager.getDescriptionLanguage(i,"default",o);for(let c of r)t.get(o).add(c)}}for(let[n,i]of t)for(let a of i){let o=[];for(let[,h]of Object.entries(s)){let l=h.name,p=this.templateManager.getDescription(l,"default",a,n);p&&o.push({command:l,description:p})}if(o.length===0)continue;let r={type:n},c=a==="default"?void 0:a;try{let h=await this.bot.api.getMyCommands({scope:r,language_code:c}),l=JSON.stringify(h.map(d=>({command:d.command,description:d.description})).sort((d,u)=>d.command.localeCompare(u.command))),p=JSON.stringify(o.sort((d,u)=>d.command.localeCompare(u.command)));l!==p&&(await this.bot.api.setMyCommands(o,{scope:r,language_code:c}),this.log?.info?.(`Synced descriptions for scope: ${n},${c?` lang: ${c},`:""} total (${o.length})`))}catch(h){this.log?.error?.(`Failed to sync descriptions for scope: ${n},${c?` lang: ${c},`:""} error: ${String(h)}`)}}}_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","handleCommandCaptionArgsVoice"],s=m(r=>`handleSession${r.startsWith("handle")?r.slice(6):r}`,"toSession"),n=[...e.map(s),...t.map(s),"handleSessionFreeText","handleSessionFreePhoto","handleSessionFreeVideo","handleSessionFreeAudio","handleSessionFreeDocument","handleSessionFreeAnimation","handleSessionFreeVoice","handleSessionFreeVideoNote","handleSessionFreeSticker","handleSessionFreeLocation","handleSessionFreeContact"],i=m((r,c)=>Object.fromEntries(r.map(h=>[h,c()])),"makeObject"),a=m(()=>[],"initDynamicSpesific"),o={all:{},routeDynamic:[],routeDynamicSpesific:{text:a(),photo:a(),video:a(),audio:a(),document:a(),animation:a(),voice:a(),videonote:a(),sticker:a(),location:a(),contact:a()},routeStatic:i(e,()=>({})),routeStaticIntent:i(t,()=>({})),routeStaticSession:i(n,()=>({})),listRouteStatic:e,listRouteStaticIntent:t,listRouteStaticSession:n,lenListRouteStatic:e.length,lenListRouteStaticIntent:t.length,lenListRouteStaticSession:n.length};return M.getFileManySync(void 0).forEach(({path:r,page:c},h)=>{this._pageBuildData(c,r),this._pageSorts(c,o,h),c.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 a=await e.getSession();if(a){let o=a.method,r=this.pages.routeStaticSession;for(let c=0;c<this.pages.lenListRouteStaticSession;c++){let h=this.pages.listRouteStaticSession[c];if(h.toLowerCase().endsWith(t)&&(n=r[h][o]),n)break}n!==void 0&&(s=this.pages.all[n.name])}}if(s===void 0){let a=e.callbackData,o=e.msgText,r=e.msgCaption,c=this.pages.routeStatic;for(let h=0;h<this.pages.lenListRouteStatic;h++){let l=this.pages.listRouteStatic[h];if(l.toLowerCase().endsWith(t)&&(n=c[l][a||o||r]),n)break}n!==void 0&&(s=this.pages.all[n.name])}if(s===void 0){let a=this.pages.routeStaticIntent,o=t==="callbackdata",r=o?"colon":"space",c=o?e.callbackData:e.msgText||e.msgCaption,h=e.haveArgs(c,r);if(c&&h)for(let l=0;l<this.pages.lenListRouteStaticIntent;l++){let p=this.pages.listRouteStaticIntent[l];if(!p.toLowerCase().endsWith(t))continue;let d=a[p];if(n=d[e.getIntent(c,r,1)],!n&&!o&&(n=d[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 o=await new s(e)[n.routeName]?.();return e.temp.isAnswer===!0?o:null}let i=this.pages.routeDynamicSpesific[t]||[];for(let a=0;a<i.length;a++){let o=i[a];if(o===void 0)continue;let r=this.pages.all[o.name];r!==void 0&&typeof r.prototype[o.routeName]=="function"&&await new r(e)[o.routeName]()}for(let a=0;a<this.pages.routeDynamic.length;a++){let o=this.pages.routeDynamic[a];if(o===void 0)continue;let r=this.pages.all[o];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 re=class{static{m(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 a=m((o,r)=>`<keyboard type="${s}" lang="${r}">${n?this.label._reverse(o):o}</keyboard>`,"pro");return t?a(i[t],t):Object.keys(i).map(o=>a(i[o],o)).join(" ")}};var ce=class{static{m(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 Re,Worker as Pe}from"worker_threads";var v=class{constructor(e,t){this.send=e;this.register=t}send;register;static{m(this,"WorkerThreadRpc")}map=new Map;async make(e){let t=this.map,s=this.send,{id:n,method:i,params:a,result:o,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 h=await c.apply(this.register,a);s({id:n,result:h})}catch(c){s({id:n,error:c instanceof Error?{message:c.message,stack:c.stack,name:c.name}:c})}else if(o!==void 0){let c=t.get(n);c&&(c.resolve(o),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(),a={id:i,method:e,params:t,...n};return s?new Promise((o,r)=>{this.map.set(i,{resolve:o,reject:r}),this.send(a)}):this.send(a)}};var U=class{constructor(e,t,s){this.path=e;this.argv=t;this.register=s;this.init(),s||(s=this),this.rpc=new v(this.send.bind(this),s)}path;argv;register;static{m(this,"WorkerThreadLaunch")}static isMainThread=Re;_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 Pe(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 le=class y{static{m(this,"WorkerThreadExport")}static launchGatewayClient(e){let t=new Proxy({},{get(n,i){if(!(typeof i!="string"||i==="then"))return async(a,...o)=>{let r=a.gatewayClients.get(e);return r||(r=await a.createGatewayClient(e)),r.request(i,o)}}}),s=m(function(n){return new Proxy({},{get(i,a){if(!(typeof a!="string"||a==="then"))return async(...o)=>{let r=n.gatewayClients.get(e);return r||(r=await n.createGatewayClient(e)),r.request(a,o)}}})},"ctor");return Object.setPrototypeOf(s,t),s}static init(e){let{WTInit:t,WTLaunch:s=U,path:n,wrap:i}=e,a=`for-${n}`;if(process.argv[2]===a)return new t,{launchGatewayClient:m(l=>y.launchGatewayClient(l||t.gatewayServerPath),"launchGatewayClient")};let o,r=new Proxy({},{get(l,p){if(p!=="then")return p==="sendRequest"||p==="request"||p==="kill"||p==="send"?(...d)=>{if(!o)throw new Error(`Thread at ${n} not launched yet.`);return o[p](...d)}:(...d)=>{if(!o)throw new Error(`Thread at ${n} not launched yet.`);return o.request(p,d)}}}),h={...i?i(r):{},launchWorker:m(async(l=[])=>(o=new s(n,[a,...l]),await o.ready(),o),"launchWorker"),launchGatewayClient:m(l=>y.launchGatewayClient(l||t.gatewayServerPath),"launchGatewayClient")};return new Proxy(h,{get(l,p){if(p!=="then")return p==="launchGatewayClient"?l.launchGatewayClient:p==="launchWorker"?l.launchWorker:p in l?l[p]:typeof p=="string"?(...d)=>{if(!o)throw new Error(`Thread at ${n} not launched yet.`);return o.request(p,d)}:l[p]}})}};import{Client as Oe}from"net-ipc";var N=class{static{m(this,"WorkerThreadGatewayClient")}client=new Oe;rpc;constructor(){this.rpc=new v(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 De}from"net-ipc";var j=class{static{m(this,"WorkerThreadGatewayServer")}server=new De;rpc=new Map;register={};constructor(){this.server.on("connect",e=>{let t=new v(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 Be,threadId as Fe,isMainThread as $e}from"worker_threads";var de=class{static{m(this,"WorkerThreadInit")}argv=process.argv;id=Fe;pid=process.pid;rpc={};parentPort=Be;gatewayServer;gatewayClients=new Map;gatewayClientLatest;static gatewayServerPath;gatewayServerPath=this.constructor.gatewayServerPath;get gatewayClient(){return this.gatewayClientLatest}static isMainThread=$e;constructor(){this.init(),this.rpc=new v(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 j,await this.gatewayServer.start(t,e),this.constructor.gatewayServerPath=t,!0}async createGatewayClient(e){let t=new N;return await t.connect(e),this.gatewayClients.set(e,t),this.gatewayClientLatest=t,t}};var he=class{static{m(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 pe=class{static{m(this,"MockTelegramServer")}botToken="";hostname;port;log;handlers;defaultHandler;apiRoot="";webhookUrl="";requests=[];updates=[];server;_nextUpdateId=1;_nextMessageId=1;constructor(e={}){this.hostname=e.hostname??"127.0.0.1",this.port=e.port??0,this.log=e.log===!0?W:e.log?e.log:void 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:m(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.log?.info?.(`Mock Telegram server started: ${this.apiRoot}`),this.apiRoot}async stop(){this.server?.stop(),this.server=void 0,this.log?.info?.("Mock Telegram server stopped")}_json(e){return new Response(JSON.stringify(e),{status:200,headers:{"Content-Type":"application/json"}})}lastRequest(e){if(!e)return this.requests[this.requests.length-1];for(let t=this.requests.length-1;t>=0;t--){let s=this.requests[t];if(s?.method===e)return s}}clearRequests(){this.requests.length=0}_defaultResponse(e,t){if(e==="getMe")return{ok:!0,result:{id:123456789,is_bot:!0,first_name:"Mock",username:"mock_gramstax_bot"}};if(e==="getUpdates")return{ok:!0,result:[]};if(e==="getMyCommands")return{ok:!0,result:[]};if(e==="setMyCommands")return{ok:!0,result:!0};if(e==="setWebhook"){let s=this._bodyRecord(t),n=typeof s?.url=="string"?s.url:"";return this.webhookUrl=n,this.log?.info?.(`Mock Telegram webhook set: ${n}`),{ok:!0,result:!0}}return e==="getWebhookInfo"?{ok:!0,result:{url:this.webhookUrl}}:{ok:!0,result:!0}}async _handleRequest(e){let{pathname:t}=new URL(e.url),s=t.match(/^\/bot([^/]+)\/(.+)$/);if(!s)return new Response("Not found",{status:404});let n=s[1],i=s[2];if(!n||!i)return new Response("Not found",{status:404});this.botToken=n;let a=await this._readBody(e.clone());this.log?.debug?.(`Mock Telegram API request: ${i}`),this.requests.push({method:i,body:a,url:e.url,requestMethod:e.method,headers:Object.fromEntries(e.headers.entries())});let o=this.handlers[i]??this.defaultHandler,r=o?await o({method:i,request:e}):this._defaultResponse(i,a);return this._json(r)}_bodyRecord(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}async _readBody(e){if(e.method==="GET"||e.method==="HEAD")return;let t=e.headers.get("content-type")||"";try{if(t.includes("application/json"))return await e.json();if(t.includes("multipart/form-data")||t.includes("application/x-www-form-urlencoded")){let n=await e.formData();return Object.fromEntries(n.entries())}let s=await e.text();if(!s)return;try{return JSON.parse(s)}catch{return s}}catch{return}}_defaultUser(e){return{id:e?.id??1001,is_bot:e?.is_bot??!1,first_name:e?.first_name??"Test",...e?.last_name?{last_name:e.last_name}:{},...e?.username?{username:e.username}:{},language_code:e?.language_code??"en"}}_defaultChat(e){return{id:e?.id??1001,type:e?.type??"private",first_name:e?.first_name??"Test",...e?.last_name?{last_name:e.last_name}:{},...e?.username?{username:e.username}:{},...e?.title?{title:e.title}:{}}}_nextIds(e){return{updateId:this._nextUpdateId++,messageId:e?.message_id??this._nextMessageId++,date:e?.date??Math.floor(Date.now()/1e3)}}_buildMessageUpdate(e,t){let{updateId:s,messageId:n,date:i}=this._nextIds(t);return{update_id:s,message:{message_id:n,date:i,chat:this._defaultChat(t?.chat),from:this._defaultUser(t?.user),...e}}}async _postUpdate(e,t){if(await this._waitForWebhookUrl(t?.responseTimeoutMs??1e3),!this.webhookUrl)throw new Error("Webhook URL is not set. Call setWebhook first or assign mockServer.webhookUrl.");let s=this.requests.length;this.updates.push(e),this.log?.info?.(`Mock Telegram update sent: ${this.webhookUrl}`);let n=await fetch(this.webhookUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!n.ok)throw new Error(`Webhook request failed with status ${n.status}`);let i=await this._waitForResponses(s,t?.responseTimeoutMs??1e3);return this.log?.info?.(`Mock Telegram bot responses captured: ${i.length}`),i}async _waitForWebhookUrl(e){if(this.webhookUrl||e<=0)return this.webhookUrl;let t=Date.now();for(;Date.now()-t<e&&(await new Promise(s=>setTimeout(s,5)),!this.webhookUrl););return this.webhookUrl}async _waitForResponses(e,t){if(t<=0)return this._userResponseRequests(e);if(this._userResponseRequests(e).length>0)return this._userResponseRequests(e);let s=Date.now();for(;Date.now()-s<t&&(await new Promise(n=>setTimeout(n,5)),!(this._userResponseRequests(e).length>0)););return this._userResponseRequests(e)}_userResponseRequests(e){return this.requests.slice(e).filter(t=>this._isUserResponseMethod(t.method))}_isUserResponseMethod(e){return e.startsWith("send")||e.startsWith("edit")||e.startsWith("answer")||e.startsWith("delete")||e.startsWith("copy")||e.startsWith("forward")||e==="pinChatMessage"||e==="unpinChatMessage"||e==="setMessageReaction"}async sendText(e,t){let s=e.startsWith("/")?[{offset:0,length:e.split(" ")[0]?.length??e.length,type:"bot_command"}]:void 0;return await this._postUpdate(this._buildMessageUpdate({text:e,...s?{entities:s}:{}},t),t)}async sendPhoto(e){return await this._postUpdate(this._buildMessageUpdate({photo:[{file_id:"mock-photo-file-id",file_unique_id:"mock-photo-unique-id",width:1,height:1}],...e?.caption?{caption:e.caption}:{}},e),e)}async sendVideo(e){return await this._postUpdate(this._buildMessageUpdate({video:{file_id:"mock-video-file-id",file_unique_id:"mock-video-unique-id",width:1,height:1,duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendAudio(e){return await this._postUpdate(this._buildMessageUpdate({audio:{file_id:"mock-audio-file-id",file_unique_id:"mock-audio-unique-id",duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendDocument(e){return await this._postUpdate(this._buildMessageUpdate({document:{file_id:"mock-document-file-id",file_unique_id:"mock-document-unique-id",file_name:"mock.txt"},...e?.caption?{caption:e.caption}:{}},e),e)}async sendAnimation(e){return await this._postUpdate(this._buildMessageUpdate({animation:{file_id:"mock-animation-file-id",file_unique_id:"mock-animation-unique-id",width:1,height:1,duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendVoice(e){return await this._postUpdate(this._buildMessageUpdate({voice:{file_id:"mock-voice-file-id",file_unique_id:"mock-voice-unique-id",duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendVideoNote(e){return await this._postUpdate(this._buildMessageUpdate({video_note:{file_id:"mock-video-note-file-id",file_unique_id:"mock-video-note-unique-id",length:1,duration:1}},e),e)}async sendSticker(e){return await this._postUpdate(this._buildMessageUpdate({sticker:{file_id:"mock-sticker-file-id",file_unique_id:"mock-sticker-unique-id",type:"regular",width:1,height:1,is_animated:!1,is_video:!1}},e),e)}async sendLocation(e){return await this._postUpdate(this._buildMessageUpdate({location:{latitude:e?.latitude??0,longitude:e?.longitude??0}},e),e)}async sendContact(e){return await this._postUpdate(this._buildMessageUpdate({contact:{phone_number:e?.phone_number??"+10000000000",first_name:e?.first_name??"Test",...e?.last_name?{last_name:e.last_name}:{},...e?.user_id?{user_id:e.user_id}:{}}},e),e)}async sendCallbackQuery(e,t){let{updateId:s,messageId:n,date:i}=this._nextIds(t);return await this._postUpdate({update_id:s,callback_query:{id:t?.id??`mock-callback-${s}`,from:this._defaultUser(t?.user),message:{message_id:n,date:i,chat:this._defaultChat(t?.chat),text:t?.messageText??"Mock message"},chat_instance:"mock-chat-instance",data:e}},t)}};export{re as BlockKeyboard,L as CacheExternal,V as Ctx,ae as Gramstax,ce as LabelKeyboard,H as LoggingHelper,pe as MockTelegramServer,M as PageManager,x as TemplateEngine,G as TemplateManager,q as WebhookQueue,le as WorkerThreadExport,N as WorkerThreadGatewayClient,j as WorkerThreadGatewayServer,de as WorkerThreadInit,U as WorkerThreadLaunch,he as WorkerThreadPool,v as WorkerThreadRpc,W as log};
|
|
7
|
+
`);o=o.replace(`__IMPORT_${r}__`,p)}return o}static validateNamesBlock(e){let t=[],s=new Set(y.ALLOWED_BLOCKS.map(a=>a.replace(/^<\/?/,"").replace(/\s.*?>$/,"").replace(/\/?>$/,"").toLowerCase())),n=new Set(["b","i","u","s","code","pre","a","blockquote"]),i=/<\/?\s*([a-z][\w-]*)(?:\s[^<>]*)?\/?\s*>/gi;for(let a of e.matchAll(i)){let o=a[1]?.toLowerCase();if(!o||n.has(o)||s.has(o))continue;let r=(e.slice(0,a.index).match(/\n/g)||[]).length+1;t.push({line:r,message:`Unsupported template block: <${o}>`})}return{valid:t.length===0,errors:t}}static validateScopes(e){let t=[],s=new Set(y.ALLOWED_SCOPE),n=/\{([^\s{}\w])([\s\S]*?)\1\}/g;for(let i of e.matchAll(n)){let a=`{${i[1]}${i[1]}}`;if(i[1]&&s.has(a))continue;let o=(e.slice(0,i.index).match(/\n/g)||[]).length+1,r=i[1]??"?";t.push({line:o,message:`Unsupported template scope: {${r} ${r}}`})}return{valid:t.length===0,errors:t}}static validatePositionsBlock(e){let t=[],s=[],n=new Set(["b","i","u","s","code","pre","a","blockquote"]),i={base:new Set(["__root__"]),message:new Set(["base"]),keyboard:new Set(["base"]),media:new Set(["base","media-group"]),"media-group":new Set(["base"]),description:new Set(["base"]),switch:new Set(["message","keyboard","media","description"]),case:new Set(["switch"]),default:new Set(["switch"]),map:new Set(["message","keyboard","media","description"]),div:new Set(["base","message","description","keyboard","case","default","map"]),script:new Set(["base","message","description","keyboard","case","default","map","div"]),import:new Set(["base"]),space:new Set(["base","message","description","keyboard","case","default","switch","map","div"])},a=/<(\/?)(\w[\w-]*)([^>]*)>/g,o;for(;(o=a.exec(e))!==null;){let r=o[0],c=o[1],h=o[2].toLowerCase(),l=c==="/",p=!l&&r.endsWith("/>");if(n.has(h)||!i[h])continue;let d=(e.slice(0,o.index).match(/\n/g)||[]).length+1;if(l)if(s.length===0)t.push({line:d,message:`Unexpected closing tag </${h}>: no matching opening tag`});else{let u=s[s.length-1];u.block!==h?t.push({line:d,message:`Mismatched closing tag: expected </${u.block}> but found </${h}>`}):s.pop()}else if(p){let u=s.length>0?s[s.length-1].block:"__root__";i[h].has(u)||t.push({line:d,message:`Block <${h}> is not allowed inside <${u}>`})}else{let u=s.length>0?s[s.length-1].block:"__root__";i[h].has(u)||t.push({line:d,message:`Block <${h}> is not allowed inside <${u}>`}),s.push({block:h,line:d})}}for(let r of s)t.push({line:r.line,message:`Unclosed block <${r.block}>: missing closing tag </${r.block}>`});if(t.length===0){let r=[],c=/<base\b[^>]*>[\s\S]*?<\/base>/g,h;for(;(h=c.exec(e))!==null;)r.push({start:h.index,end:h.index+h[0].length});if(r.length===0&&e.trim())t.push({line:1,message:"Missing <base> block: template content must be wrapped in <base>...</base>"});else{let l=0;for(let p of r){if(p.start>l&&e.slice(l,p.start).trim()){let u=(e.slice(0,l).match(/\n/g)||[]).length+1;t.push({line:u,message:"Content found outside <base> block: move content inside a <base>...</base>"});break}l=p.end}if(t.length===0&&l<e.length&&e.slice(l).trim()){let p=(e.slice(0,l).match(/\n/g)||[]).length+1;t.push({line:p,message:"Content found outside <base> block: move content inside a <base>...</base>"})}}}return{valid:t.length===0,errors:t}}static validateFormatBlock(e){let t=[],s=new Set(["space","import"]),n=new Set(["base","message","keyboard","media","media-group","description","script","switch","case","default","map","div"]),i=/<(\/?)(\w[\w-]*)([^>]*)>/g,a;for(;(a=i.exec(e))!==null;){let o=a[0],r=a[1],c=a[2].toLowerCase(),h=r==="/",l=!h&&o.endsWith("/>");if(h)continue;let p=(e.slice(0,a.index).match(/\n/g)||[]).length+1;l?n.has(c)&&t.push({line:p,message:`Block <${c}> must not be self-closing: use <${c}>...</${c}> instead`}):s.has(c)&&t.push({line:p,message:`Block <${c}> must be self-closing: use <${c} /> instead`})}return{valid:t.length===0,errors:t}}static _validateBlockAttributes(e,t,s,n,i){let a=[],o=new RegExp(`<${t}(?![\\w-])([^>]*?)>`,"g"),r;for(;(r=o.exec(e))!==null;){let c=r[1].trim();if(!c)continue;let h=(e.slice(0,r.index).match(/\n/g)||[]).length+1,l=/([\w-]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+))/g,p;for(;(p=l.exec(c))!==null;){let d=p[1].toLowerCase();if(!s.has(d)){let u=s.size===0?"no attributes are allowed":`only ${n} is allowed`;a.push({line:h,message:`Unknown attribute "${p[1]}" on <${t}>: ${u}`});continue}if(i?.[d]){let u=p[2]??p[3]??p[4]??"",g=i[d](u);g&&a.push({line:h,message:g})}}}return a}static validateBlockBaseAttributes(e){let t=this._validateBlockAttributes(e,"base",new Set(["id"]),'"id"',{id:m(s=>s?null:'Attribute "id" on <base> must not be empty',"id")});return{valid:t.length===0,errors:t}}static validateBlockMessageAttributes(e){let t=this._validateBlockAttributes(e,"message",new Set(["lang"]),'"lang"');return{valid:t.length===0,errors:t}}static validateBlockKeyboardAttributes(e){let t=this._validateBlockAttributes(e,"keyboard",new Set(["lang","type"]),'"lang" and "type"',{type:m(s=>s==="inline"||s==="bottom"?null:`Attribute "type" on <keyboard> must be "inline" or "bottom", got "${s}"`,"type")});return{valid:t.length===0,errors:t}}static validateBlockMediaAttributes(e){let t=new Set(["photo","video","audio","document","animation","voice","video_note","sticker","location","contact"]),s=this._validateBlockAttributes(e,"media",new Set(["lang","type","src","shared","latitude","longitude","phone","first_name","last_name","vcard"]),'"lang", "type", "src", "shared", "latitude", "longitude", "phone", "first_name", "last_name", and "vcard"',{type:m(n=>t.has(n)?null:`Attribute "type" on <media> must be one of: ${[...t].join(", ")}, got "${n}"`,"type"),shared:m(n=>n==="true"||n==="false"?null:`Attribute "shared" on <media> must be "true" or "false", got "${n}"`,"shared")});return{valid:s.length===0,errors:s}}static validateBlockMediaGroupAttributes(e){let t=this._validateBlockAttributes(e,"media-group",new Set(["lang"]),'"lang"');return t.push(...this._validateMediaGroupItems(e)),{valid:t.length===0,errors:t}}static _validateMediaGroupItems(e){let t=[],s=/<media-group(?:\s+[^>]*)?>([\s\S]*?)<\/media-group>/gi,n=/<media(?:\s+([^>]*))?>([\s\S]*?)<\/media>/gi,i=new Set(["photo","video","audio","document"]);for(let a of e.matchAll(s)){let o=(e.slice(0,a.index).match(/\n/g)||[]).length+1,r=a[1]||"",c=[],h=0;for(let p of r.matchAll(n)){h+=1;let d=o+(r.slice(0,p.index).match(/\n/g)||[]).length,u=p[1]||"",g=u.match(/\btype\s*=\s*"([^"]*)"/)?.[1],f=u.match(/\bsrc\s*=\s*"([^"]*)"/)?.[1];if(!g||!i.has(g)){t.push({line:d,message:'Attribute "type" on <media> inside <media-group> must be one of: photo, video, audio, document'});continue}f||t.push({line:d,message:'Attribute "src" on <media> inside <media-group> is required'}),c.push(g)}h===0&&t.push({line:o,message:"<media-group> must contain at least one <media> item"}),h>this.MAX_MEDIA_GROUP_ITEMS&&t.push({line:o,message:`<media-group> must contain at most ${this.MAX_MEDIA_GROUP_ITEMS} <media> items`});let l=new Set(c);l.has("audio")&&l.size>1&&t.push({line:o,message:"<media-group> with audio items can only contain audio items"}),l.has("document")&&l.size>1&&t.push({line:o,message:"<media-group> with document items can only contain document items"})}return t}static validateBlockDescriptionAttributes(e){let t=this._validateBlockAttributes(e,"description",new Set(["lang","scope"]),'"lang" and "scope"');return{valid:t.length===0,errors:t}}static validateBlockScriptAttributes(e){let t=this._validateBlockAttributes(e,"script",new Set,"");return{valid:t.length===0,errors:t}}static validateBlockSwitchAttributes(e){let t=this._validateBlockAttributes(e,"switch",new Set(["value"]),'"value"');return{valid:t.length===0,errors:t}}static validateBlockCaseAttributes(e){let t=this._validateBlockAttributes(e,"case",new Set(["is"]),'"is"');return{valid:t.length===0,errors:t}}static validateBlockDefaultAttributes(e){let t=this._validateBlockAttributes(e,"default",new Set,"");return{valid:t.length===0,errors:t}}static validateBlockMapAttributes(e){let t=this._validateBlockAttributes(e,"map",new Set(["src","join"]),'"src" and "join"');return{valid:t.length===0,errors:t}}static validateBlockDivAttributes(e){let t=this._validateBlockAttributes(e,"div",new Set,"");return{valid:t.length===0,errors:t}}static validateBlockImportAttributes(e){let t=this._validateBlockAttributes(e,"import",new Set(["src","block","base","lang","section"]),'"src", "block", "base", "lang", and "section"');return{valid:t.length===0,errors:t}}static validateBlockSpaceAttributes(e){let t=this._validateBlockAttributes(e,"space",new Set,"");return{valid:t.length===0,errors:t}}static validateTemplate(e){let t=this.validateNamesBlock(e),s=this.validateScopes(e),n=this.validateFormatBlock(e),i=this.validatePositionsBlock(e),a=this.validateBlockBaseAttributes(e),o=this.validateBlockMessageAttributes(e),r=this.validateBlockKeyboardAttributes(e),c=this.validateBlockMediaAttributes(e),h=this.validateBlockMediaGroupAttributes(e),l=this.validateBlockDescriptionAttributes(e),p=this.validateBlockScriptAttributes(e),d=this.validateBlockSwitchAttributes(e),u=this.validateBlockCaseAttributes(e),g=this.validateBlockDefaultAttributes(e),f=this.validateBlockMapAttributes(e),T=this.validateBlockDivAttributes(e),w=this.validateBlockImportAttributes(e),A=this.validateBlockSpaceAttributes(e),O=[...t.errors,...s.errors,...n.errors,...i.errors,...a.errors,...o.errors,...r.errors,...c.errors,...h.errors,...l.errors,...p.errors,...d.errors,...u.errors,...g.errors,...f.errors,...T.errors,...w.errors,...A.errors];return{valid:O.length===0,errors:O}}};var G=class{static{m(this,"TemplateManager")}_map=new Map;_engine=x;_watcher=[];_pageManager=M;_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(!F(t))throw new Error(`Template base path is not exists: ${t}`);if(!$(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=we(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=X(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileAdd(e){let t=X(e);this._isValidFile(t)&&this._loadFile(t)}_handleFileDelete(e){let t=X(e),s=this._getKey(t);this._map.has(s)&&this._map.delete(s)}_handleWatchError(e){}_loadAllFiles(){let e=new Map,t=new Map,s=[];for(let i=0;i<this._path.length;i++){let a=this._path[i],r=ke(a,"utf8").filter(c=>this._isValidFile(c));for(let c of r){let h=D(a,c),l=this._getExtension(c),p=this._getKey(c);if(l===".html")e.set(p,K(h,"utf8")),t.set(p,c);else if(l===".ts"||l===".js"){let d=M.getFileSync(h);d?.template!==void 0&&(e.set(p,d.template),t.set(p,c),s.push(d))}}}let n=new Map;for(let[i,a]of e.entries())this._compile(i,a,void 0,n,e,t.get(i));e.clear(),n.clear();for(let i of s)i.template=void 0}_loadFile(e){for(let t=0;t<this._path.length;t++){let s=this._path[t],n=D(s,e),i=this._getExtension(e),a=this._getKey(e);if(i==".html"){let o=K(n,"utf8");this._compile(a,o,void 0,void 0,void 0,e)}else if(i==".ts"||i==".js"){let o=M.getFileSync(n);o?.template!==void 0&&(this._compile(a,o.template,void 0,void 0,void 0,e),o.template=void 0)}else throw new Error(`File ${e} is not support`)}}_getExtension(e){return ne(e).toLowerCase()}_readTemplateFile(e){for(let t of this._path){let s=ne(e).toLowerCase();if(s){let o=D(t,e);if(F(o)&&$(o).isFile()){if(s===".html")return K(o,"utf8");if(s===".ts"||s===".js")try{return M.getFileSync(o)?.template??null}catch{return null}}continue}let n=D(t,`${e}.ts`),i=D(t,`${e}.js`);if(F(n)&&$(n).isFile())try{return M.getFileSync(n)?.template??null}catch{}else if(F(i)&&$(i).isFile())try{return M.getFileSync(n)?.template??null}catch{}let a=D(t,`${e}.html`);if(F(a)&&$(a).isFile())return K(a,"utf8")}return null}_isValidFile(e){return this._supportedExtensions.has(this._getExtension(e))}_getBaseAtLine(e,t){let s=/<base\b([^>]*?)>/gi,n=/<\/base>/gi,i=t,a,o;for(;(a=s.exec(e))!==null&&!((e.slice(0,a.index).match(/\n/g)||[]).length+1>i);){let h=a[1].match(/\sid\s*=\s*(["']?)([^"'\s>]+)\1/i),l=h?.[2]??null,p=!!h;for(n.lastIndex||(n.lastIndex=s.lastIndex);(o=n.exec(e))!==null;){if((e.slice(0,o.index).match(/\n/g)||[]).length+1>i)return{baseId:l,hasId:p};s.lastIndex=n.lastIndex;break}}return null}_validateTemplate(e,t,s=e){let n=x.validateTemplate(t);if(!n.valid&&n.errors.length>0){let i=n.errors[0],a=this._getBaseAtLine(t,i.line),o=a?.hasId?` on base "${a.baseId}"`:"",r=`${s}, line ${i.line}`;throw new Error(`Template${o} (${r}): ${i.message}`)}}_getKey(e){return e.replace(/\.[^/.]+$/,"")}_compile(e,t,s,n,i,a=e){let o=this._map.get(e),r=o||{},c=!1;this._validateTemplate(e,t,a);let h=x.processImportBlocks(t,p=>i&&i.has(p)?i.get(p):this._readTemplateFile(p),0,n);this._validateTemplate(e,h,a);let l=x._processBaseBlocks(h);(s===void 0||s?.media===!1||o?.media===void 0)&&(r.media=x.compileBlockMedia(h,l),c=!0),(s===void 0||s?.message===!1||o?.message===void 0)&&(r.message=x.compileBlockMessage(h,l),c=!0),(s===void 0||s?.keyboard===!1||o?.keyboard===void 0)&&(r.keyboard=x.compileBlockKeyboards(h,l),c=!0),(s===void 0||s?.description===!1||o?.description===void 0)&&(r.description=x.compileBlockDescription(h,l),c=!0),c&&this._map.set(e,r)}getMedia(e,t="default",s="default",n){let a=this._map.get(e)?.media?.[t],o=a?.[s]||a?.default;try{if(!o)throw new Error("Media function not found, please check your template");return o(n)}catch{return{}}}getMessage(e,t="default",s="default",n){try{let a=this._map.get(e)?.message?.[t],o=a?.[s]||a?.default;if(!o)throw"";return o(n)}catch{return""}}getDescription(e,t="default",s="default",n="default",i){try{let o=this._map.get(e)?.description?.[t]?.[n],r=o?.[s]||o?.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 o=this._map.get(e)?.keyboard?.[t],r=o?.[s]?.[n]||o?.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=D(this._path[s],e);if(F(n))return Se(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 xe,webhookCallback as ie}from"grammy";var q=class{constructor(e){this.maxSize=e;if(!Number.isFinite(e)||e<=0)throw new Error("WebhookQueue maxSize must be a positive number")}maxSize;static{m(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 Ae=Ie((()=>{try{return k}catch{return _e(import.meta.url)}})()),ve=JSON.parse(Ce(oe(Ae,"../../package.json"),"utf-8")).version,ae=class{static{m(this,"Gramstax")}templateManager;cacheKeyboard;cacheSession;pages;optionsPage={shortCallbackData:!1};log;bot;botConfig;webhookQueue;webhookQueueInstance;webhookServer;handlerBotUpdate;deployType;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?W:e.log?e.log:void 0,this.log?.info?.(`Gramstax v${ve}`),this.cacheSession=e.cacheSession||new L("memory"),this.cacheKeyboard=e.cacheKeyboard||new Map,this.botConfig=e.botConfig,this.webhookQueue=e.webhookQueue,this.templateManager=e.templateManager||new G({path:[oe(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.stop()),process.once("SIGTERM",()=>this.stop()),this.hookBeforeStart(),e.deploy.startsWith("polling"))this.deployType="polling",this._runPolling();else if(e.deploy.startsWith("webhook:"))this.deployType="webhook",this._runWebhook(e.deploy.split("webhook:")[1]);else if(e.deploy.startsWith("serverless:"))this.deployType="serverless",this._runServerless(e.deploy.split("serverless:")[1]);else if(e.deploy.startsWith("test"))this.deployType="test";else throw new Error("Params deploy is not valid, expected: polling, webhook:<public-url>, serverless:<your-adapter>")}async stop(){await this.bot.stop(),this.deployType==="webhook"&&(await this.webhookServer?.stop(),this.webhookServer=void 0)}_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 deploy ${t} started: ${n} ${t=="webhook"||t=="serverless"?`(${s})`:""}`),this.hookAfterStart()}createBot(e){return new xe(e,this.botConfig)}createCtx(e){return new V({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:m(e=>{this._onStart(e,"polling",null)},"onStart")})}async _runWebhook(e){let{serve:t}=await import("bun"),s=ie(this.bot,"bun"),n=this.webhookQueue,i=n?.enabled===!0;this.handlerBotUpdate=i?this.bot.handleUpdate.bind(this.bot):s;let a=i?new q(n?.maxQueueSize??5e3):void 0,o=n?.workerCount??8,r=n?.perChatConcurrency??1,c=n?.blockWhenFull!==!1,h=new Map,l=new Map;this.webhookQueueInstance=a;let p=m(b=>b?.message?.chat?.id??b?.edited_message?.chat?.id??b?.channel_post?.chat?.id??b?.edited_channel_post?.chat?.id??b?.callback_query?.message?.chat?.id??b?.callback_query?.from?.id??b?.inline_query?.from?.id??b?.chosen_inline_result?.from?.id,"getChatId"),d=m(async b=>{if(!i||r<=0||b===void 0||b===null)return()=>{};let C=String(b),_=h.get(C)||0;if(_<r)return h.set(C,_+1),()=>this._releaseWebhookChat(C,h,l);await new Promise(P=>{let Y=l.get(C)||[];Y.push(P),l.set(C,Y)});let R=(h.get(C)||0)+1;return h.set(C,R),()=>this._releaseWebhookChat(C,h,l)},"acquireChat");if(i&&a){await this.bot.init();for(let b=0;b<o;b++)this._startWebhookWorker(a,d,p)}let u=new URL(e),g=u.pathname,f=parseInt(u.port)||3e3,T=this.log,w="/stats_queue";this.webhookServer?.stop();let A=t({port:f,async fetch(b){let{pathname:C}=new URL(b.url);if(b.method=="POST"&&C==g){if(!i||!a)return s(b);if(!c&&a.length>=(n?.maxQueueSize??5e3))return new Response("Queue full",{status:429});try{let _=await b.json();return await a.enqueue(_),new Response("OK",{status:200})}catch(_){return T?.error?.(`Webhook queue error: ${String(_)}`),new Response("Bad Request",{status:400})}}if(b.method=="GET"&&C==w){let _=a?.getStats()||{length:0,maxSize:n?.maxQueueSize??5e3,waitingEnqueue:0,waitingDequeue:0};return new Response(JSON.stringify({enabled:i,path:w,timestamp:new Date().toISOString(),maxQueueSize:n?.maxQueueSize??5e3,workerCount:o,perChatConcurrency:r,blockWhenFull:c,queue:_,activeChats:h.size}),{status:200,headers:{"Content-Type":"application/json"}})}if(b.method=="GET"&&C=="/"){let _=new Date().toISOString();return new Response(JSON.stringify({status:"OK",timestamp:_}),{status:200,headers:{"Content-Type":"application/json"}})}return new Response("Not found",{status:404})}});this.webhookServer=A,(await this.bot.api.getWebhookInfo()).url!=e&&await this.bot.api.setWebhook(e);let B=await this.bot.api.getMe();await this._onStart(B,"webhook",e)}_startWebhookWorker(e,t,s){m(async()=>{for(;;){let i=await e.dequeue(),a=await t(s(i));try{await this.bot.handleUpdate(i)}catch(o){this.log?.error?.(`Webhook worker error: ${String(o)}`)}finally{a()}}},"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 a=s.get(e);a&&a.length>0&&(a.shift()(),a.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=ie(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}=Me(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,a="handle",o="Args",r="Command",c="Caption",h="Free",l=t.routeDynamic,p=t.routeDynamicSpesific;t.all[n]=e;for(let u of["listRouteStatic","listRouteStaticIntent"]){let g=u==="listRouteStatic"?"lenListRouteStatic":"lenListRouteStaticIntent";for(let f=0;f<t[g];f++){let T=t[u][f];if(typeof i[T]!="function")continue;let w=t.routeStatic[T],A=t.routeStaticIntent[T],O={name:n,routeName:T},B=w||A;if(B!==void 0){let b=T.includes(r),C=T.endsWith("CallbackData"),_=T.endsWith("Text"),R;if(b){let P=e.data.intentCommandText;R=P?`/${P}`:void 0}else if(C){let P=e.data.intentCallbackData;this.optionsPage.shortCallbackData===!0&&(P=String(s),e.data.intentCallbackData=P),R=P}else _?R=e.data.intentText:R=e.data.name;R&&(B[R]=O)}}}for(let u=0;u<t.lenListRouteStaticSession;u++){let g=t.listRouteStaticSession[u];if(typeof i[g]!="function")continue;let f=t.routeStaticSession[g],T={name:n,routeName:g};if(f!==void 0){let w=g.replace("handle",""),O=`methodSession${w.startsWith("Session")?w.slice(7):w}`,B=i[O]?.(n);f[B]=T}}let d=["handleFreeText","handleFreePhoto","handleFreeVideo","handleFreeAudio","handleFreeDocument","handleFreeAnimation","handleFreeVoice","handleFreeVideoNote","handleFreeSticker","handleFreeLocation","handleFreeContact"];for(let u of d)if(Object.hasOwn(i,u)&&typeof i[u]=="function"){let g=u.replace(a,"").replace(o,"").replace(r,"").replace(c,"").replace(h,"").toLowerCase();p[g]?.some(T=>T.name===n)||p[g].push({name:n,routeName:u})}i.handleFree&&l.push(n)}async executeSyncBlocksDescription(e){let t=new Map,s=e?.routeStatic?.handleCommandText;if(s){for(let[,n]of Object.entries(s)){let i=n.name,a=this.templateManager.getDescriptionScopes(i);for(let o of a){t.has(o)||t.set(o,new Set);let r=this.templateManager.getDescriptionLanguage(i,"default",o);for(let c of r)t.get(o).add(c)}}for(let[n,i]of t)for(let a of i){let o=[];for(let[,h]of Object.entries(s)){let l=h.name,p=this.templateManager.getDescription(l,"default",a,n);p&&o.push({command:l,description:p})}if(o.length===0)continue;let r={type:n},c=a==="default"?void 0:a;try{let h=await this.bot.api.getMyCommands({scope:r,language_code:c}),l=JSON.stringify(h.map(d=>({command:d.command,description:d.description})).sort((d,u)=>d.command.localeCompare(u.command))),p=JSON.stringify(o.sort((d,u)=>d.command.localeCompare(u.command)));l!==p&&(await this.bot.api.setMyCommands(o,{scope:r,language_code:c}),this.log?.info?.(`Synced descriptions for scope: ${n},${c?` lang: ${c},`:""} total (${o.length})`))}catch(h){this.log?.error?.(`Failed to sync descriptions for scope: ${n},${c?` lang: ${c},`:""} error: ${String(h)}`)}}}}_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","handleCommandCaptionArgsVoice"],s=m(r=>`handleSession${r.startsWith("handle")?r.slice(6):r}`,"toSession"),n=[...e.map(s),...t.map(s),"handleSessionFreeText","handleSessionFreePhoto","handleSessionFreeVideo","handleSessionFreeAudio","handleSessionFreeDocument","handleSessionFreeAnimation","handleSessionFreeVoice","handleSessionFreeVideoNote","handleSessionFreeSticker","handleSessionFreeLocation","handleSessionFreeContact"],i=m((r,c)=>Object.fromEntries(r.map(h=>[h,c()])),"makeObject"),a=m(()=>[],"initDynamicSpesific"),o={all:{},routeDynamic:[],routeDynamicSpesific:{text:a(),photo:a(),video:a(),audio:a(),document:a(),animation:a(),voice:a(),videonote:a(),sticker:a(),location:a(),contact:a()},routeStatic:i(e,()=>({})),routeStaticIntent:i(t,()=>({})),routeStaticSession:i(n,()=>({})),listRouteStatic:e,listRouteStaticIntent:t,listRouteStaticSession:n,lenListRouteStatic:e.length,lenListRouteStaticIntent:t.length,lenListRouteStaticSession:n.length};return M.getFileManySync(void 0).forEach(({path:r,page:c},h)=>{this._pageBuildData(c,r),this._pageSorts(c,o,h),c.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 a=await e.getSession();if(a){let o=a.method,r=this.pages.routeStaticSession;for(let c=0;c<this.pages.lenListRouteStaticSession;c++){let h=this.pages.listRouteStaticSession[c];if(h.toLowerCase().endsWith(t)&&(n=r[h][o]),n)break}n!==void 0&&(s=this.pages.all[n.name])}}if(s===void 0){let a=e.callbackData,o=e.msgText,r=e.msgCaption,c=this.pages.routeStatic;for(let h=0;h<this.pages.lenListRouteStatic;h++){let l=this.pages.listRouteStatic[h];if(l.toLowerCase().endsWith(t)&&(n=c[l][a||o||r]),n)break}n!==void 0&&(s=this.pages.all[n.name])}if(s===void 0){let a=this.pages.routeStaticIntent,o=t==="callbackdata",r=o?"colon":"space",c=o?e.callbackData:e.msgText||e.msgCaption,h=e.haveArgs(c,r);if(c&&h)for(let l=0;l<this.pages.lenListRouteStaticIntent;l++){let p=this.pages.listRouteStaticIntent[l];if(!p.toLowerCase().endsWith(t))continue;let d=a[p];if(n=d[e.getIntent(c,r,1)],!n&&!o&&(n=d[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 o=await new s(e)[n.routeName]?.();return e.temp.isAnswer===!0?o:null}let i=this.pages.routeDynamicSpesific[t]||[];for(let a=0;a<i.length;a++){let o=i[a];if(o===void 0)continue;let r=this.pages.all[o.name];r!==void 0&&typeof r.prototype[o.routeName]=="function"&&await new r(e)[o.routeName]()}for(let a=0;a<this.pages.routeDynamic.length;a++){let o=this.pages.routeDynamic[a];if(o===void 0)continue;let r=this.pages.all[o];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 re=class{static{m(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 a=m((o,r)=>`<keyboard type="${s}" lang="${r}">${n?this.label._reverse(o):o}</keyboard>`,"pro");return t?a(i[t],t):Object.keys(i).map(o=>a(i[o],o)).join(" ")}};var ce=class{static{m(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 Re,Worker as Pe}from"worker_threads";var v=class{constructor(e,t){this.send=e;this.register=t}send;register;static{m(this,"WorkerThreadRpc")}map=new Map;async make(e){let t=this.map,s=this.send,{id:n,method:i,params:a,result:o,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 h=await c.apply(this.register,a);s({id:n,result:h})}catch(c){s({id:n,error:c instanceof Error?{message:c.message,stack:c.stack,name:c.name}:c})}else if(o!==void 0){let c=t.get(n);c&&(c.resolve(o),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(),a={id:i,method:e,params:t,...n};return s?new Promise((o,r)=>{this.map.set(i,{resolve:o,reject:r}),this.send(a)}):this.send(a)}};var U=class{constructor(e,t,s){this.path=e;this.argv=t;this.register=s;this.init(),s||(s=this),this.rpc=new v(this.send.bind(this),s)}path;argv;register;static{m(this,"WorkerThreadLaunch")}static isMainThread=Re;_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 Pe(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 le=class y{static{m(this,"WorkerThreadExport")}static launchGatewayClient(e){let t=new Proxy({},{get(n,i){if(!(typeof i!="string"||i==="then"))return async(a,...o)=>{let r=a.gatewayClients.get(e);return r||(r=await a.createGatewayClient(e)),r.request(i,o)}}}),s=m(function(n){return new Proxy({},{get(i,a){if(!(typeof a!="string"||a==="then"))return async(...o)=>{let r=n.gatewayClients.get(e);return r||(r=await n.createGatewayClient(e)),r.request(a,o)}}})},"ctor");return Object.setPrototypeOf(s,t),s}static init(e){let{WTInit:t,WTLaunch:s=U,path:n,wrap:i}=e,a=`for-${n}`;if(process.argv[2]===a)return new t,{launchGatewayClient:m(l=>y.launchGatewayClient(l||t.gatewayServerPath),"launchGatewayClient")};let o,r=new Proxy({},{get(l,p){if(p!=="then")return p==="sendRequest"||p==="request"||p==="kill"||p==="send"?(...d)=>{if(!o)throw new Error(`Thread at ${n} not launched yet.`);return o[p](...d)}:(...d)=>{if(!o)throw new Error(`Thread at ${n} not launched yet.`);return o.request(p,d)}}}),h={...i?i(r):{},launchWorker:m(async(l=[])=>(o=new s(n,[a,...l]),await o.ready(),o),"launchWorker"),launchGatewayClient:m(l=>y.launchGatewayClient(l||t.gatewayServerPath),"launchGatewayClient")};return new Proxy(h,{get(l,p){if(p!=="then")return p==="launchGatewayClient"?l.launchGatewayClient:p==="launchWorker"?l.launchWorker:p in l?l[p]:typeof p=="string"?(...d)=>{if(!o)throw new Error(`Thread at ${n} not launched yet.`);return o.request(p,d)}:l[p]}})}};import{Client as Oe}from"net-ipc";var N=class{static{m(this,"WorkerThreadGatewayClient")}client=new Oe;rpc;constructor(){this.rpc=new v(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 De}from"net-ipc";var j=class{static{m(this,"WorkerThreadGatewayServer")}server=new De;rpc=new Map;register={};constructor(){this.server.on("connect",e=>{let t=new v(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 Be,threadId as Fe,isMainThread as $e}from"worker_threads";var de=class{static{m(this,"WorkerThreadInit")}argv=process.argv;id=Fe;pid=process.pid;rpc={};parentPort=Be;gatewayServer;gatewayClients=new Map;gatewayClientLatest;static gatewayServerPath;gatewayServerPath=this.constructor.gatewayServerPath;get gatewayClient(){return this.gatewayClientLatest}static isMainThread=$e;constructor(){this.init(),this.rpc=new v(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 j,await this.gatewayServer.start(t,e),this.constructor.gatewayServerPath=t,!0}async createGatewayClient(e){let t=new N;return await t.connect(e),this.gatewayClients.set(e,t),this.gatewayClientLatest=t,t}};var he=class{static{m(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 pe=class{static{m(this,"MockTelegramServer")}botToken="";hostname;port;log;handlers;defaultHandler;apiRoot="";webhookUrl="";requests=[];updates=[];server;_nextUpdateId=1;_nextMessageId=1;constructor(e={}){this.hostname=e.hostname??"127.0.0.1",this.port=e.port??0,this.log=e.log===!0?W:e.log?e.log:void 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:m(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.log?.info?.(`Mock Telegram server started: ${this.apiRoot}`),this.apiRoot}async stop(){this.server?.stop(),this.server=void 0,this.log?.info?.("Mock Telegram server stopped")}_json(e){return new Response(JSON.stringify(e),{status:200,headers:{"Content-Type":"application/json"}})}lastRequest(e){if(!e)return this.requests[this.requests.length-1];for(let t=this.requests.length-1;t>=0;t--){let s=this.requests[t];if(s?.method===e)return s}}clearRequests(){this.requests.length=0}_defaultResponse(e,t){if(e==="getMe")return{ok:!0,result:{id:123456789,is_bot:!0,first_name:"Mock",username:"mock_gramstax_bot"}};if(e==="getUpdates")return{ok:!0,result:[]};if(e==="getMyCommands")return{ok:!0,result:[]};if(e==="setMyCommands")return{ok:!0,result:!0};if(e==="setWebhook"){let s=this._bodyRecord(t),n=typeof s?.url=="string"?s.url:"";return this.webhookUrl=n,this.log?.info?.(`Mock Telegram webhook set: ${n}`),{ok:!0,result:!0}}return e==="getWebhookInfo"?{ok:!0,result:{url:this.webhookUrl}}:{ok:!0,result:!0}}async _handleRequest(e){let{pathname:t}=new URL(e.url),s=t.match(/^\/bot([^/]+)\/(.+)$/);if(!s)return new Response("Not found",{status:404});let n=s[1],i=s[2];if(!n||!i)return new Response("Not found",{status:404});this.botToken=n;let a=await this._readBody(e.clone());this.log?.debug?.(`Mock Telegram API request: ${i}`),this.requests.push({method:i,body:a,url:e.url,requestMethod:e.method,headers:Object.fromEntries(e.headers.entries())});let o=this.handlers[i]??this.defaultHandler,r=o?await o({method:i,request:e}):this._defaultResponse(i,a);return this._json(r)}_bodyRecord(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}async _readBody(e){if(e.method==="GET"||e.method==="HEAD")return;let t=e.headers.get("content-type")||"";try{if(t.includes("application/json"))return await e.json();if(t.includes("multipart/form-data")||t.includes("application/x-www-form-urlencoded")){let n=await e.formData();return Object.fromEntries(n.entries())}let s=await e.text();if(!s)return;try{return JSON.parse(s)}catch{return s}}catch{return}}_defaultUser(e){return{id:e?.id??1001,is_bot:e?.is_bot??!1,first_name:e?.first_name??"Test",...e?.last_name?{last_name:e.last_name}:{},...e?.username?{username:e.username}:{},language_code:e?.language_code??"en"}}_defaultChat(e){return{id:e?.id??1001,type:e?.type??"private",first_name:e?.first_name??"Test",...e?.last_name?{last_name:e.last_name}:{},...e?.username?{username:e.username}:{},...e?.title?{title:e.title}:{}}}_nextIds(e){return{updateId:this._nextUpdateId++,messageId:e?.message_id??this._nextMessageId++,date:e?.date??Math.floor(Date.now()/1e3)}}_buildMessageUpdate(e,t){let{updateId:s,messageId:n,date:i}=this._nextIds(t);return{update_id:s,message:{message_id:n,date:i,chat:this._defaultChat(t?.chat),from:this._defaultUser(t?.user),...e}}}async _postUpdate(e,t){if(await this._waitForWebhookUrl(t?.responseTimeoutMs??1e3),!this.webhookUrl)throw new Error("Webhook URL is not set. Call setWebhook first or assign mockServer.webhookUrl.");let s=this.requests.length;this.updates.push(e),this.log?.info?.(`Mock Telegram update sent: ${this.webhookUrl}`);let n=await fetch(this.webhookUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!n.ok)throw new Error(`Webhook request failed with status ${n.status}`);let i=await this._waitForResponses(s,t?.responseTimeoutMs??1e3);return this.log?.info?.(`Mock Telegram bot responses captured: ${i.length}`),i}async _waitForWebhookUrl(e){if(this.webhookUrl||e<=0)return this.webhookUrl;let t=Date.now();for(;Date.now()-t<e&&(await new Promise(s=>setTimeout(s,5)),!this.webhookUrl););return this.webhookUrl}async _waitForResponses(e,t){if(t<=0)return this._userResponseRequests(e);if(this._userResponseRequests(e).length>0)return this._userResponseRequests(e);let s=Date.now();for(;Date.now()-s<t&&(await new Promise(n=>setTimeout(n,5)),!(this._userResponseRequests(e).length>0)););return this._userResponseRequests(e)}_userResponseRequests(e){return this.requests.slice(e).filter(t=>this._isUserResponseMethod(t.method))}_isUserResponseMethod(e){return e.startsWith("send")||e.startsWith("edit")||e.startsWith("answer")||e.startsWith("delete")||e.startsWith("copy")||e.startsWith("forward")||e==="pinChatMessage"||e==="unpinChatMessage"||e==="setMessageReaction"}async sendText(e,t){let s=e.startsWith("/")?[{offset:0,length:e.split(" ")[0]?.length??e.length,type:"bot_command"}]:void 0;return await this._postUpdate(this._buildMessageUpdate({text:e,...s?{entities:s}:{}},t),t)}async sendPhoto(e){return await this._postUpdate(this._buildMessageUpdate({photo:[{file_id:"mock-photo-file-id",file_unique_id:"mock-photo-unique-id",width:1,height:1}],...e?.caption?{caption:e.caption}:{}},e),e)}async sendVideo(e){return await this._postUpdate(this._buildMessageUpdate({video:{file_id:"mock-video-file-id",file_unique_id:"mock-video-unique-id",width:1,height:1,duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendAudio(e){return await this._postUpdate(this._buildMessageUpdate({audio:{file_id:"mock-audio-file-id",file_unique_id:"mock-audio-unique-id",duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendDocument(e){return await this._postUpdate(this._buildMessageUpdate({document:{file_id:"mock-document-file-id",file_unique_id:"mock-document-unique-id",file_name:"mock.txt"},...e?.caption?{caption:e.caption}:{}},e),e)}async sendAnimation(e){return await this._postUpdate(this._buildMessageUpdate({animation:{file_id:"mock-animation-file-id",file_unique_id:"mock-animation-unique-id",width:1,height:1,duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendVoice(e){return await this._postUpdate(this._buildMessageUpdate({voice:{file_id:"mock-voice-file-id",file_unique_id:"mock-voice-unique-id",duration:1},...e?.caption?{caption:e.caption}:{}},e),e)}async sendVideoNote(e){return await this._postUpdate(this._buildMessageUpdate({video_note:{file_id:"mock-video-note-file-id",file_unique_id:"mock-video-note-unique-id",length:1,duration:1}},e),e)}async sendSticker(e){return await this._postUpdate(this._buildMessageUpdate({sticker:{file_id:"mock-sticker-file-id",file_unique_id:"mock-sticker-unique-id",type:"regular",width:1,height:1,is_animated:!1,is_video:!1}},e),e)}async sendLocation(e){return await this._postUpdate(this._buildMessageUpdate({location:{latitude:e?.latitude??0,longitude:e?.longitude??0}},e),e)}async sendContact(e){return await this._postUpdate(this._buildMessageUpdate({contact:{phone_number:e?.phone_number??"+10000000000",first_name:e?.first_name??"Test",...e?.last_name?{last_name:e.last_name}:{},...e?.user_id?{user_id:e.user_id}:{}}},e),e)}async sendCallbackQuery(e,t){let{updateId:s,messageId:n,date:i}=this._nextIds(t);return await this._postUpdate({update_id:s,callback_query:{id:t?.id??`mock-callback-${s}`,from:this._defaultUser(t?.user),message:{message_id:n,date:i,chat:this._defaultChat(t?.chat),text:t?.messageText??"Mock message"},chat_instance:"mock-chat-instance",data:e}},t)}};export{re as BlockKeyboard,L as CacheExternal,V as Ctx,ae as Gramstax,ce as LabelKeyboard,H as LoggingHelper,pe as MockTelegramServer,M as PageManager,x as TemplateEngine,G as TemplateManager,q as WebhookQueue,le as WorkerThreadExport,N as WorkerThreadGatewayClient,j as WorkerThreadGatewayServer,de as WorkerThreadInit,U as WorkerThreadLaunch,he as WorkerThreadPool,v as WorkerThreadRpc,W as log};
|