create-gramstax 0.0.27 → 0.1.0

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.
Files changed (31) hide show
  1. package/dist/src/index.cjs +2 -2
  2. package/dist/src/index.js +2 -2
  3. package/dist/src/templates/.env.example +4 -7
  4. package/dist/src/templates/README.md +0 -1
  5. package/dist/src/templates/package.json +48 -54
  6. package/dist/src/templates/src/base/guard.ts +1 -1
  7. package/dist/src/templates/src/base/index.ts +4 -0
  8. package/dist/src/templates/src/base/page.ts +1 -1
  9. package/dist/src/templates/src/core/bot.ts +3 -3
  10. package/dist/src/templates/src/core/index.ts +2 -0
  11. package/dist/src/templates/src/db/index.ts +0 -2
  12. package/dist/src/templates/src/env.ts +0 -1
  13. package/dist/src/templates/src/guards/index.ts +1 -0
  14. package/dist/src/templates/src/guards/user.ts +4 -4
  15. package/dist/src/templates/src/pages/general-error-input-notfound.ts +6 -17
  16. package/dist/src/templates/src/pages/general-error.ts +5 -4
  17. package/dist/src/templates/src/pages/help.ts +6 -18
  18. package/dist/src/templates/src/pages/start.ts +7 -8
  19. package/dist/src/templates/src/pages/username-notfound.ts +8 -21
  20. package/dist/src/templates/src/repositories/example.ts +1 -3
  21. package/dist/src/templates/src/repositories/index.ts +1 -0
  22. package/dist/src/templates/src/services/example.ts +1 -2
  23. package/dist/src/templates/src/services/index.ts +1 -0
  24. package/dist/src/templates/src/threads/index.ts +1 -0
  25. package/dist/src/templates/src/threads/main.ts +2 -2
  26. package/dist/src/templates/src/utils/index.ts +1 -0
  27. package/dist/src/templates/src/utils/log.ts +2 -3
  28. package/package.json +63 -57
  29. package/dist/src/templates/.prettierignore +0 -1
  30. package/dist/src/templates/ecosystem.config.js +0 -26
  31. package/dist/src/templates/src/base/general.ts +0 -3
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var x=Object.create;var u=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var F=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty;var g=(m,e)=>u(m,"name",{value:e,configurable:!0});var N=(m,e,n,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of D(e))!E.call(m,i)&&i!==n&&u(m,i,{get:()=>e[i],enumerable:!(t=M(e,i))||t.enumerable});return m};var f=(m,e,n)=>(n=m!=null?x(F(m)):{},N(e||!m||!m.__esModule?u(n,"default",{value:m,enumerable:!0}):n,m));var j=require("logging-pretty"),r=new j.LoggingPretty;var a=f(require("fs"),1),p=f(require("path"),1),v=require("url");var d=require("child_process"),y=f(require("enquirer"),1),T={};var R=(0,v.fileURLToPath)(T.url),L=p.dirname(R),l=class{constructor(e){this.projectDirectory=e}static{g(this,"Create")}config;printBanner(){console.log(`
2
+ "use strict";var M=Object.create;var f=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var R=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty;var m=(o,e)=>f(o,"name",{value:e,configurable:!0});var N=(o,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of F(e))!E.call(o,a)&&a!==t&&f(o,a,{get:()=>e[a],enumerable:!(n=D(e,a))||n.enumerable});return o};var d=(o,e,t)=>(t=o!=null?M(R(o)):{},N(e||!o||!o.__esModule?f(t,"default",{value:o,enumerable:!0}):t,o));var L=m(()=>typeof document>"u"?new URL(`file:${__filename}`).href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?document.currentScript.src:new URL("main.js",document.baseURI).href,"getImportMetaUrl"),u=L();var v=require("logging-pretty"),r=new v.LoggingPretty;var i=d(require("fs"),1),s=d(require("path"),1),w=require("url");var _=require("child_process"),y=d(require("enquirer"),1);var T=(0,w.fileURLToPath)(u),U=s.dirname(T),g=class{constructor(e){this.projectDirectory=e}static{m(this,"Create")}config;printBanner(){console.log(`
3
3
  $$$$$$\\ $$\\
4
4
  $$ __$$\\ $$ |
5
5
  $$ / \\__| $$$$$$\\ $$$$$$\\ $$$$$$\\$$$$\\ $$$$$$$\\ $$$$$$\\ $$$$$$\\ $$\\ $$\\
@@ -9,4 +9,4 @@ $$ | $$ |$$ | $$ __$$ |$$ | $$ | $$ | \\____$$\\ $$ |$$\\ $$ __$$ | $$
9
9
  \\$$$$$$ |$$ | \\$$$$$$$ |$$ | $$ | $$ |$$$$$$$ | \\$$$$ |\\$$$$$$$ |$$ /\\$$\\
10
10
  \\______/ \\__| \\_______|\\__| \\__| \\__|\\_______/ \\____/ \\_______|\\__/ \\__|
11
11
 
12
- `)}getPackageManagerCommands(e){return{bun:{install:"bun install",dev:"bun dev",start:"bun start","pm2:start":"bun run pm2:start","pm2:stop":"bun run pm2:stop","pm2:restart":"bun run pm2:restart","pm2:delete":"bun run pm2:delete","pm2:logs":"bun run pm2:logs","pm2:monit":"bun run pm2:monit"},npm:{install:"npm install",dev:"npm run dev",start:"npm start","pm2:start":"npm run pm2:start","pm2:stop":"npm run pm2:stop","pm2:restart":"npm run pm2:restart","pm2:delete":"npm run pm2:delete","pm2:logs":"npm run pm2:logs","pm2:monit":"npm run pm2:monit"},pnpm:{install:"pnpm install",dev:"pnpm dev",start:"pnpm start","pm2:start":"pnpm pm2:start","pm2:stop":"pnpm pm2:stop","pm2:restart":"pnpm pm2:restart","pm2:delete":"pnpm pm2:delete","pm2:logs":"pnpm pm2:logs","pm2:monit":"pnpm pm2:monit"},yarn:{install:"yarn install",dev:"yarn dev",start:"yarn start","pm2:start":"yarn pm2:start","pm2:stop":"yarn pm2:stop","pm2:restart":"yarn pm2:restart","pm2:delete":"yarn pm2:delete","pm2:logs":"yarn pm2:logs","pm2:monit":"yarn pm2:monit"}}[e]}copyDirectorySync(e,n,t={}){a.existsSync(n)||a.mkdirSync(n,{recursive:!0});let i=a.readdirSync(e,{withFileTypes:!0});for(let o of i){let $=p.join(e,o.name),c=p.join(n,o.name);if(o.isDirectory())this.copyDirectorySync($,c,t);else if(o.isFile()){let s=a.readFileSync($,"utf-8");s=this.replaceTemplateVariables(s,t),a.writeFileSync(c,s)}}}replaceTemplateVariables(e,n){let t=e;for(let[i,o]of Object.entries(n))t=t.replace(new RegExp(`{{${i}}}`,"g"),o);return t}async promptForProjectName(){return(await y.default.prompt({type:"input",name:"projectName",message:"What is your project named?",initial:"",validate:g(n=>n===""||/^[a-z0-9-_]+$/i.test(n)?!0:"Project name can only contain letters, numbers, hyphens, and underscores","validate")})).projectName}async promptForConfiguration(){let e=[];e.push({type:"select",name:"packageManager",message:"Which package manager would you like to use?",choices:[{name:"bun",message:"Bun (recommended)",value:"bun"},{name:"npm",message:"npm",value:"npm"},{name:"pnpm",message:"pnpm",value:"pnpm"},{name:"yarn",message:"Yarn",value:"yarn"}],initial:0}),e.push({type:"select",name:"runtime",message:"Which runtime would you like to use?",choices:[{name:"bun",message:"Bun (recommended)",value:"bun"},{name:"node",message:"Node.js",value:"node"}],initial:0}),e.push({type:"confirm",name:"eslint",message:"Would you like to use ESLint?",initial:!0});let n=await y.default.prompt(e);return{packageManager:n.packageManager,runtime:n.runtime,eslint:n.eslint}}async installDependencies(e,n){return await new Promise((t,i)=>{let c=(0,d.spawn)(n,["install"],{cwd:e,stdio:"inherit",shell:!0});c.on("close",s=>{s===0?t(!0):(r.fail("Dependencies installation failed"),t(!1))}),c.on("error",s=>{r.fail(`Dependencies installation failed: ${s.message}`),t(!1)})})}async gatherProjectConfig(){this.printBanner();let e=this.projectDirectory,n,t=!1;e?(n=p.resolve(process.cwd(),e),t=!1):(e=await this.promptForProjectName(),e===""?(e=p.basename(process.cwd()),n=process.cwd(),t=!0):(n=p.resolve(process.cwd(),e),t=!1));let i=await this.promptForConfiguration(),o=i.packageManager,$=i.runtime,c=i.eslint;return r.info(`Project: ${e}`),r.info(`Location: ${n}`),r.info(`Package Manager: ${o}`),r.info(`Runtime: ${$}`),r.info(`ESLint: ${c?"Yes":"No"}`),t?a.readdirSync(n).length>0&&(r.error("Current directory is not empty!"),process.exit(1)):a.existsSync(n)&&(r.error(`Directory "${e}" already exists!`),process.exit(1)),{projectName:e,projectPath:n,packageManager:o,runtime:$,setupEslint:c}}async executeProjectGeneration(e){let{projectName:n,projectPath:t,packageManager:i,runtime:o,setupEslint:$}=e;r.info("Creating project directory.."),a.existsSync(t)||a.mkdirSync(t,{recursive:!0}),r.info("Copying template files..");let c=p.join(L,"templates"),s=this.getPackageManagerCommands(i),C={projectName:n,installCmd:s.install,runDevCmd:s.dev,runStartCmd:s.start,runPm2StartCmd:s["pm2:start"],runPm2StopCmd:s["pm2:stop"],runPm2RestartCmd:s["pm2:restart"],runPm2DeleteCmd:s["pm2:delete"],runPm2LogsCmd:s["pm2:logs"],runPm2MonitCmd:s["pm2:monit"]};this.copyDirectorySync(c,t,C),r.info("Creating logs directory.."),a.mkdirSync(p.join(t,"logs"),{recursive:!0}),a.writeFileSync(p.join(t,"logs/.gitkeep"),"");let S=p.join(t,".env"),_=p.join(t,".env.example");if(a.existsSync(_)&&(r.info("Creating .env file.."),a.renameSync(_,S)),o!=="bun"){r.info("Removing bunfig.toml for Node.js runtime..");let P=p.join(t,"bunfig.toml");a.existsSync(P)&&a.unlinkSync(P)}let h=p.join(t,"tsconfig.json"),k=a.readFileSync(h,{encoding:"utf8"}).replace("//{{types}}",o=="bun"?'"bun-types"':"");if(a.writeFileSync(h,k,{encoding:"utf8"}),r.info("Installing dependencies.."),!await this.installDependencies(t,i))return r.fail("Project created failed!"),process.exit();$&&(r.info("Setting up ESLint.."),await this.setupEslintConfig(t,i)),r.info("Project created successfully!"),r.info(`Next steps: ${e.projectPath!==process.cwd()?`cd ${n} && `:" "}${s.install} && ${s.dev}`),r.info(`For production: ${s["pm2:start"]}`),r.info("Done..")}async setupEslintConfig(e,n){return new Promise(t=>{let i=(0,d.spawn)("npm",["init","@eslint/config@latest"],{cwd:e,stdio:"inherit",shell:!0});i.on("close",o=>{o===0||r.fail("ESLint setup failed. You can set it up later with: npm init @eslint/config"),t()}),i.on("error",o=>{r.fail(`ESLint setup failed: ${o.message}`),r.info("You can set it up later with: npm init @eslint/config"),t()})})}async createProject(){try{this.config=await this.gatherProjectConfig(),await this.executeProjectGeneration(this.config)}catch(e){e instanceof Error?r.error(`Failed to create project: ${e.message}`):r.error(`Failed to create project: ${String(e)}`),process.exit(1)}}};var b=require("commander"),B="0.0.0",w=new b.Command;w.name("create-gramstax").description("CLI to create a new Gramstax Telegram bot project").version(B).argument("[project-directory]","Directory to create the project in").action(async m=>{try{await new l(m).createProject()}catch(e){r.error(`Failed to create project: ${String(e)}`),process.exit(1)}});w.parse();
12
+ `)}getPackageManagerCommands(e){return{bun:{install:"bun install",dev:"bun dev",start:"bun start"},npm:{install:"npm install",dev:"npm run dev",start:"npm start"},pnpm:{install:"pnpm install",dev:"pnpm dev",start:"pnpm start"},yarn:{install:"yarn install",dev:"yarn dev",start:"yarn start"}}[e]}copyDirectorySync(e,t,n={}){i.existsSync(t)||i.mkdirSync(t,{recursive:!0});let a=i.readdirSync(e,{withFileTypes:!0});for(let c of a){let p=s.join(e,c.name),$=s.join(t,c.name);if(c.isDirectory())this.copyDirectorySync(p,$,n);else if(c.isFile()){let l=i.readFileSync(p,"utf-8");l=this.replaceTemplateVariables(l,n),i.writeFileSync($,l)}}}replaceTemplateVariables(e,t){let n=e;for(let[a,c]of Object.entries(t))n=n.replace(new RegExp(`{{${a}}}`,"g"),c);return n}async promptForProjectName(){return(await y.default.prompt({type:"input",name:"projectName",message:"What is your project named?",initial:"",validate:m(t=>t===""||/^[a-z0-9-_]+$/i.test(t)?!0:"Project name can only contain letters, numbers, hyphens, and underscores","validate")})).projectName}async promptForConfiguration(){let e=[];e.push({type:"select",name:"packageManager",message:"Which package manager would you like to use?",choices:[{name:"bun",message:"Bun (recommended)",value:"bun"},{name:"npm",message:"npm",value:"npm"},{name:"pnpm",message:"pnpm",value:"pnpm"},{name:"yarn",message:"Yarn",value:"yarn"}],initial:0}),e.push({type:"select",name:"runtime",message:"Which runtime would you like to use?",choices:[{name:"bun",message:"Bun (recommended)",value:"bun"},{name:"node",message:"Node.js",value:"node"}],initial:0}),e.push({type:"confirm",name:"eslint",message:"Would you like to use ESLint?",initial:!0});let t=await y.default.prompt(e);return{packageManager:t.packageManager,runtime:t.runtime,eslint:t.eslint}}async installDependencies(e,t){return await new Promise(n=>{let p=(0,_.spawn)(t,["install"],{cwd:e,stdio:"inherit",shell:!0});p.on("close",$=>{$===0?n(!0):(r.fail("Dependencies installation failed"),n(!1))}),p.on("error",$=>{r.fail(`Dependencies installation failed: ${$.message}`),n(!1)})})}async gatherProjectConfig(){this.printBanner();let e=this.projectDirectory,t,n=!1;e?(t=s.resolve(process.cwd(),e),n=!1):(e=await this.promptForProjectName(),e===""?(e=s.basename(process.cwd()),t=process.cwd(),n=!0):(t=s.resolve(process.cwd(),e),n=!1));let a=await this.promptForConfiguration(),c=a.packageManager,p=a.runtime,$=a.eslint;return r.info(`Project: ${e}`),r.info(`Location: ${t}`),r.info(`Package Manager: ${c}`),r.info(`Runtime: ${p}`),r.info(`ESLint: ${$?"Yes":"No"}`),n?i.readdirSync(t).length>0&&(r.error("Current directory is not empty!"),process.exit(1)):i.existsSync(t)&&(r.error(`Directory "${e}" already exists!`),process.exit(1)),{projectName:e,projectPath:t,packageManager:c,runtime:p,setupEslint:$}}async executeProjectGeneration(e){let{projectName:t,projectPath:n,packageManager:a,runtime:c,setupEslint:p}=e;r.info("Creating project directory.."),i.existsSync(n)||i.mkdirSync(n,{recursive:!0}),r.info("Copying template files..");let $=s.join(U,"templates"),l=this.getPackageManagerCommands(a),k={projectName:t,installCmd:l.install,runDevCmd:l.dev,runStartCmd:l.start};this.copyDirectorySync($,n,k),r.info("Creating logs directory.."),i.mkdirSync(s.join(n,"logs"),{recursive:!0}),i.writeFileSync(s.join(n,"logs/.gitkeep"),"");let C=s.join(n,".env"),h=s.join(n,".env.example");if(i.existsSync(h)&&(r.info("Creating .env file.."),i.renameSync(h,C)),c!=="bun"){r.info("Removing bunfig.toml for Node.js runtime..");let P=s.join(n,"bunfig.toml");i.existsSync(P)&&i.unlinkSync(P)}let j=s.join(n,"tsconfig.json"),x=i.readFileSync(j,{encoding:"utf8"}).replace("//{{types}}",c=="bun"?'"bun-types"':"");if(i.writeFileSync(j,x,{encoding:"utf8"}),r.info("Installing dependencies.."),!await this.installDependencies(n,a))return r.fail("Project created failed!"),process.exit();p&&(r.info("Setting up ESLint.."),await this.setupEslintConfig(n)),r.info("Project created successfully!"),r.info(`Next steps: ${e.projectPath!==process.cwd()?`cd ${t} && `:" "}${l.install} && ${l.dev}`),r.info("Done..")}async setupEslintConfig(e){return new Promise(t=>{let n=(0,_.spawn)("npm",["init","@eslint/config@latest"],{cwd:e,stdio:"inherit",shell:!0});n.on("close",a=>{a===0||r.fail("ESLint setup failed. You can set it up later with: npm init @eslint/config"),t()}),n.on("error",a=>{r.fail(`ESLint setup failed: ${a.message}`),r.info("You can set it up later with: npm init @eslint/config"),t()})})}async createProject(){try{this.config=await this.gatherProjectConfig(),await this.executeProjectGeneration(this.config)}catch(e){e instanceof Error?r.error(`Failed to create project: ${e.message}`):r.error(`Failed to create project: ${String(e)}`),process.exit(1)}}};var b=require("commander"),I="0.0.0",S=new b.Command;S.name("create-gramstax").description("CLI to create a new Gramstax Telegram bot project").version(I).argument("[project-directory]","Directory to create the project in").action(async o=>{try{await new g(o).createProject()}catch(e){r.error(`Failed to create project: ${String(e)}`),process.exit(1)}});S.parse();
package/dist/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var b=Object.defineProperty;var u=($,e)=>b($,"name",{value:e,configurable:!0});import{LoggingPretty as w}from"logging-pretty";var n=new w;import*as a from"fs";import*as o from"path";import{fileURLToPath as C}from"url";import{spawn as y}from"child_process";import _ from"enquirer";var S=C(import.meta.url),k=o.dirname(S),l=class{constructor(e){this.projectDirectory=e}static{u(this,"Create")}config;printBanner(){console.log(`
2
+ var w=Object.defineProperty;var g=(l,e)=>w(l,"name",{value:e,configurable:!0});import{LoggingPretty as k}from"logging-pretty";var r=new k;import*as i from"fs";import*as a from"path";import{fileURLToPath as C}from"url";import{spawn as _}from"child_process";import y from"enquirer";var x=C(import.meta.url),M=a.dirname(x),m=class{constructor(e){this.projectDirectory=e}static{g(this,"Create")}config;printBanner(){console.log(`
3
3
  $$$$$$\\ $$\\
4
4
  $$ __$$\\ $$ |
5
5
  $$ / \\__| $$$$$$\\ $$$$$$\\ $$$$$$\\$$$$\\ $$$$$$$\\ $$$$$$\\ $$$$$$\\ $$\\ $$\\
@@ -9,4 +9,4 @@ $$ | $$ |$$ | $$ __$$ |$$ | $$ | $$ | \\____$$\\ $$ |$$\\ $$ __$$ | $$
9
9
  \\$$$$$$ |$$ | \\$$$$$$$ |$$ | $$ | $$ |$$$$$$$ | \\$$$$ |\\$$$$$$$ |$$ /\\$$\\
10
10
  \\______/ \\__| \\_______|\\__| \\__| \\__|\\_______/ \\____/ \\_______|\\__/ \\__|
11
11
 
12
- `)}getPackageManagerCommands(e){return{bun:{install:"bun install",dev:"bun dev",start:"bun start","pm2:start":"bun run pm2:start","pm2:stop":"bun run pm2:stop","pm2:restart":"bun run pm2:restart","pm2:delete":"bun run pm2:delete","pm2:logs":"bun run pm2:logs","pm2:monit":"bun run pm2:monit"},npm:{install:"npm install",dev:"npm run dev",start:"npm start","pm2:start":"npm run pm2:start","pm2:stop":"npm run pm2:stop","pm2:restart":"npm run pm2:restart","pm2:delete":"npm run pm2:delete","pm2:logs":"npm run pm2:logs","pm2:monit":"npm run pm2:monit"},pnpm:{install:"pnpm install",dev:"pnpm dev",start:"pnpm start","pm2:start":"pnpm pm2:start","pm2:stop":"pnpm pm2:stop","pm2:restart":"pnpm pm2:restart","pm2:delete":"pnpm pm2:delete","pm2:logs":"pnpm pm2:logs","pm2:monit":"pnpm pm2:monit"},yarn:{install:"yarn install",dev:"yarn dev",start:"yarn start","pm2:start":"yarn pm2:start","pm2:stop":"yarn pm2:stop","pm2:restart":"yarn pm2:restart","pm2:delete":"yarn pm2:delete","pm2:logs":"yarn pm2:logs","pm2:monit":"yarn pm2:monit"}}[e]}copyDirectorySync(e,r,t={}){a.existsSync(r)||a.mkdirSync(r,{recursive:!0});let p=a.readdirSync(e,{withFileTypes:!0});for(let s of p){let c=o.join(e,s.name),m=o.join(r,s.name);if(s.isDirectory())this.copyDirectorySync(c,m,t);else if(s.isFile()){let i=a.readFileSync(c,"utf-8");i=this.replaceTemplateVariables(i,t),a.writeFileSync(m,i)}}}replaceTemplateVariables(e,r){let t=e;for(let[p,s]of Object.entries(r))t=t.replace(new RegExp(`{{${p}}}`,"g"),s);return t}async promptForProjectName(){return(await _.prompt({type:"input",name:"projectName",message:"What is your project named?",initial:"",validate:u(r=>r===""||/^[a-z0-9-_]+$/i.test(r)?!0:"Project name can only contain letters, numbers, hyphens, and underscores","validate")})).projectName}async promptForConfiguration(){let e=[];e.push({type:"select",name:"packageManager",message:"Which package manager would you like to use?",choices:[{name:"bun",message:"Bun (recommended)",value:"bun"},{name:"npm",message:"npm",value:"npm"},{name:"pnpm",message:"pnpm",value:"pnpm"},{name:"yarn",message:"Yarn",value:"yarn"}],initial:0}),e.push({type:"select",name:"runtime",message:"Which runtime would you like to use?",choices:[{name:"bun",message:"Bun (recommended)",value:"bun"},{name:"node",message:"Node.js",value:"node"}],initial:0}),e.push({type:"confirm",name:"eslint",message:"Would you like to use ESLint?",initial:!0});let r=await _.prompt(e);return{packageManager:r.packageManager,runtime:r.runtime,eslint:r.eslint}}async installDependencies(e,r){return await new Promise((t,p)=>{let m=y(r,["install"],{cwd:e,stdio:"inherit",shell:!0});m.on("close",i=>{i===0?t(!0):(n.fail("Dependencies installation failed"),t(!1))}),m.on("error",i=>{n.fail(`Dependencies installation failed: ${i.message}`),t(!1)})})}async gatherProjectConfig(){this.printBanner();let e=this.projectDirectory,r,t=!1;e?(r=o.resolve(process.cwd(),e),t=!1):(e=await this.promptForProjectName(),e===""?(e=o.basename(process.cwd()),r=process.cwd(),t=!0):(r=o.resolve(process.cwd(),e),t=!1));let p=await this.promptForConfiguration(),s=p.packageManager,c=p.runtime,m=p.eslint;return n.info(`Project: ${e}`),n.info(`Location: ${r}`),n.info(`Package Manager: ${s}`),n.info(`Runtime: ${c}`),n.info(`ESLint: ${m?"Yes":"No"}`),t?a.readdirSync(r).length>0&&(n.error("Current directory is not empty!"),process.exit(1)):a.existsSync(r)&&(n.error(`Directory "${e}" already exists!`),process.exit(1)),{projectName:e,projectPath:r,packageManager:s,runtime:c,setupEslint:m}}async executeProjectGeneration(e){let{projectName:r,projectPath:t,packageManager:p,runtime:s,setupEslint:c}=e;n.info("Creating project directory.."),a.existsSync(t)||a.mkdirSync(t,{recursive:!0}),n.info("Copying template files..");let m=o.join(k,"templates"),i=this.getPackageManagerCommands(p),P={projectName:r,installCmd:i.install,runDevCmd:i.dev,runStartCmd:i.start,runPm2StartCmd:i["pm2:start"],runPm2StopCmd:i["pm2:stop"],runPm2RestartCmd:i["pm2:restart"],runPm2DeleteCmd:i["pm2:delete"],runPm2LogsCmd:i["pm2:logs"],runPm2MonitCmd:i["pm2:monit"]};this.copyDirectorySync(m,t,P),n.info("Creating logs directory.."),a.mkdirSync(o.join(t,"logs"),{recursive:!0}),a.writeFileSync(o.join(t,"logs/.gitkeep"),"");let j=o.join(t,".env"),g=o.join(t,".env.example");if(a.existsSync(g)&&(n.info("Creating .env file.."),a.renameSync(g,j)),s!=="bun"){n.info("Removing bunfig.toml for Node.js runtime..");let d=o.join(t,"bunfig.toml");a.existsSync(d)&&a.unlinkSync(d)}let f=o.join(t,"tsconfig.json"),v=a.readFileSync(f,{encoding:"utf8"}).replace("//{{types}}",s=="bun"?'"bun-types"':"");if(a.writeFileSync(f,v,{encoding:"utf8"}),n.info("Installing dependencies.."),!await this.installDependencies(t,p))return n.fail("Project created failed!"),process.exit();c&&(n.info("Setting up ESLint.."),await this.setupEslintConfig(t,p)),n.info("Project created successfully!"),n.info(`Next steps: ${e.projectPath!==process.cwd()?`cd ${r} && `:" "}${i.install} && ${i.dev}`),n.info(`For production: ${i["pm2:start"]}`),n.info("Done..")}async setupEslintConfig(e,r){return new Promise(t=>{let p=y("npm",["init","@eslint/config@latest"],{cwd:e,stdio:"inherit",shell:!0});p.on("close",s=>{s===0||n.fail("ESLint setup failed. You can set it up later with: npm init @eslint/config"),t()}),p.on("error",s=>{n.fail(`ESLint setup failed: ${s.message}`),n.info("You can set it up later with: npm init @eslint/config"),t()})})}async createProject(){try{this.config=await this.gatherProjectConfig(),await this.executeProjectGeneration(this.config)}catch(e){e instanceof Error?n.error(`Failed to create project: ${e.message}`):n.error(`Failed to create project: ${String(e)}`),process.exit(1)}}};import{Command as x}from"commander";var M="0.0.0",h=new x;h.name("create-gramstax").description("CLI to create a new Gramstax Telegram bot project").version(M).argument("[project-directory]","Directory to create the project in").action(async $=>{try{await new l($).createProject()}catch(e){n.error(`Failed to create project: ${String(e)}`),process.exit(1)}});h.parse();
12
+ `)}getPackageManagerCommands(e){return{bun:{install:"bun install",dev:"bun dev",start:"bun start"},npm:{install:"npm install",dev:"npm run dev",start:"npm start"},pnpm:{install:"pnpm install",dev:"pnpm dev",start:"pnpm start"},yarn:{install:"yarn install",dev:"yarn dev",start:"yarn start"}}[e]}copyDirectorySync(e,t,n={}){i.existsSync(t)||i.mkdirSync(t,{recursive:!0});let s=i.readdirSync(e,{withFileTypes:!0});for(let o of s){let $=a.join(e,o.name),c=a.join(t,o.name);if(o.isDirectory())this.copyDirectorySync($,c,n);else if(o.isFile()){let p=i.readFileSync($,"utf-8");p=this.replaceTemplateVariables(p,n),i.writeFileSync(c,p)}}}replaceTemplateVariables(e,t){let n=e;for(let[s,o]of Object.entries(t))n=n.replace(new RegExp(`{{${s}}}`,"g"),o);return n}async promptForProjectName(){return(await y.prompt({type:"input",name:"projectName",message:"What is your project named?",initial:"",validate:g(t=>t===""||/^[a-z0-9-_]+$/i.test(t)?!0:"Project name can only contain letters, numbers, hyphens, and underscores","validate")})).projectName}async promptForConfiguration(){let e=[];e.push({type:"select",name:"packageManager",message:"Which package manager would you like to use?",choices:[{name:"bun",message:"Bun (recommended)",value:"bun"},{name:"npm",message:"npm",value:"npm"},{name:"pnpm",message:"pnpm",value:"pnpm"},{name:"yarn",message:"Yarn",value:"yarn"}],initial:0}),e.push({type:"select",name:"runtime",message:"Which runtime would you like to use?",choices:[{name:"bun",message:"Bun (recommended)",value:"bun"},{name:"node",message:"Node.js",value:"node"}],initial:0}),e.push({type:"confirm",name:"eslint",message:"Would you like to use ESLint?",initial:!0});let t=await y.prompt(e);return{packageManager:t.packageManager,runtime:t.runtime,eslint:t.eslint}}async installDependencies(e,t){return await new Promise(n=>{let $=_(t,["install"],{cwd:e,stdio:"inherit",shell:!0});$.on("close",c=>{c===0?n(!0):(r.fail("Dependencies installation failed"),n(!1))}),$.on("error",c=>{r.fail(`Dependencies installation failed: ${c.message}`),n(!1)})})}async gatherProjectConfig(){this.printBanner();let e=this.projectDirectory,t,n=!1;e?(t=a.resolve(process.cwd(),e),n=!1):(e=await this.promptForProjectName(),e===""?(e=a.basename(process.cwd()),t=process.cwd(),n=!0):(t=a.resolve(process.cwd(),e),n=!1));let s=await this.promptForConfiguration(),o=s.packageManager,$=s.runtime,c=s.eslint;return r.info(`Project: ${e}`),r.info(`Location: ${t}`),r.info(`Package Manager: ${o}`),r.info(`Runtime: ${$}`),r.info(`ESLint: ${c?"Yes":"No"}`),n?i.readdirSync(t).length>0&&(r.error("Current directory is not empty!"),process.exit(1)):i.existsSync(t)&&(r.error(`Directory "${e}" already exists!`),process.exit(1)),{projectName:e,projectPath:t,packageManager:o,runtime:$,setupEslint:c}}async executeProjectGeneration(e){let{projectName:t,projectPath:n,packageManager:s,runtime:o,setupEslint:$}=e;r.info("Creating project directory.."),i.existsSync(n)||i.mkdirSync(n,{recursive:!0}),r.info("Copying template files..");let c=a.join(M,"templates"),p=this.getPackageManagerCommands(s),j={projectName:t,installCmd:p.install,runDevCmd:p.dev,runStartCmd:p.start};this.copyDirectorySync(c,n,j),r.info("Creating logs directory.."),i.mkdirSync(a.join(n,"logs"),{recursive:!0}),i.writeFileSync(a.join(n,"logs/.gitkeep"),"");let P=a.join(n,".env"),u=a.join(n,".env.example");if(i.existsSync(u)&&(r.info("Creating .env file.."),i.renameSync(u,P)),o!=="bun"){r.info("Removing bunfig.toml for Node.js runtime..");let d=a.join(n,"bunfig.toml");i.existsSync(d)&&i.unlinkSync(d)}let f=a.join(n,"tsconfig.json"),v=i.readFileSync(f,{encoding:"utf8"}).replace("//{{types}}",o=="bun"?'"bun-types"':"");if(i.writeFileSync(f,v,{encoding:"utf8"}),r.info("Installing dependencies.."),!await this.installDependencies(n,s))return r.fail("Project created failed!"),process.exit();$&&(r.info("Setting up ESLint.."),await this.setupEslintConfig(n)),r.info("Project created successfully!"),r.info(`Next steps: ${e.projectPath!==process.cwd()?`cd ${t} && `:" "}${p.install} && ${p.dev}`),r.info("Done..")}async setupEslintConfig(e){return new Promise(t=>{let n=_("npm",["init","@eslint/config@latest"],{cwd:e,stdio:"inherit",shell:!0});n.on("close",s=>{s===0||r.fail("ESLint setup failed. You can set it up later with: npm init @eslint/config"),t()}),n.on("error",s=>{r.fail(`ESLint setup failed: ${s.message}`),r.info("You can set it up later with: npm init @eslint/config"),t()})})}async createProject(){try{this.config=await this.gatherProjectConfig(),await this.executeProjectGeneration(this.config)}catch(e){e instanceof Error?r.error(`Failed to create project: ${e.message}`):r.error(`Failed to create project: ${String(e)}`),process.exit(1)}}};import{Command as D}from"commander";var F="0.0.0",h=new D;h.name("create-gramstax").description("CLI to create a new Gramstax Telegram bot project").version(F).argument("[project-directory]","Directory to create the project in").action(async l=>{try{await new m(l).createProject()}catch(e){r.error(`Failed to create project: ${String(e)}`),process.exit(1)}});h.parse();
@@ -4,15 +4,12 @@ BOT_TOKEN=your_bot_token_here
4
4
  # Bot Deployment Mode
5
5
  # Options:
6
6
  # - polling
7
- # - webhook:https://yourdomain.com (dynamic value = url public)
8
- # - serverless:std/http (dynamic value = adapter)
7
+ # - webhook:<full-public-url> | example: webhook:https://yourdomain.com/telegram-webhook
8
+ # - serverless:<adapter> | example: serverless:std/http
9
9
  BOT_DEPLOY=polling
10
10
 
11
- # Environment
12
- NODE_ENV=development
13
-
14
11
  # Cache configuration for session
15
12
  # Options:
16
13
  # - memory
17
- # - redis://... (use redis)
18
- CACHE_SESSION=memory
14
+ # - redis:<url> | example: redis://127.0.0.1:6379
15
+ CACHE_SESSION=memory
@@ -100,7 +100,6 @@ pm2 save
100
100
  ### Environment Variables
101
101
 
102
102
  - `BOT_TOKEN` - Your Telegram bot token (required)
103
- - `NODE_ENV` - Environment mode (development/production)
104
103
  - `CACHE_SESSION` - Cache type configuration (optional)
105
104
 
106
105
  ### PM2 Configuration
@@ -1,54 +1,48 @@
1
- {
2
- "name": "{{projectName}}",
3
- "version": "0.1.0",
4
- "private": true,
5
- "description": "",
6
- "type": "module",
7
- "repository": {
8
- "type": "git",
9
- "url": ""
10
- },
11
- "bugs": {
12
- "url": ""
13
- },
14
- "homepage": "",
15
- "author": "",
16
- "license": "MIT",
17
- "main": "./dist/src/index.js",
18
- "types": "./dist/src/index.d.ts",
19
- "exports": {
20
- ".": {
21
- "types": "./dist/src/index.d.ts",
22
- "import": "./dist/src/index.js",
23
- "default": "./dist/src/index.js"
24
- }
25
- },
26
- "files": [
27
- "dist",
28
- "src"
29
- ],
30
- "scripts": {
31
- "dev": "bun --watch src/index.ts",
32
- "start": "bun src/index.ts",
33
- "build": "bun build src/index.ts --outdir dist --target bun",
34
- "lint": "eslint '**/*.ts'",
35
- "lint:fix": "eslint '**/*.ts' --fix",
36
- "pm2:start": "pm2 start ecosystem.config.js",
37
- "pm2:stop": "pm2 stop ecosystem.config.js",
38
- "pm2:restart": "pm2 restart ecosystem.config.js",
39
- "pm2:delete": "pm2 delete ecosystem.config.js",
40
- "pm2:logs": "pm2 logs",
41
- "pm2:monit": "pm2 monit"
42
- },
43
- "dependencies": {
44
- "gramstax": "latest",
45
- "logging-pretty": "^3.0.0"
46
- },
47
- "peerDependencies": {
48
- "typescript": "latest"
49
- },
50
- "devDependencies": {
51
- "@types/bun": "latest",
52
- "pm2": "^5.3.0"
53
- }
54
- }
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "description": "",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": ""
10
+ },
11
+ "bugs": {
12
+ "url": ""
13
+ },
14
+ "homepage": "",
15
+ "author": "",
16
+ "license": "MIT",
17
+ "main": "./dist/src/index.js",
18
+ "types": "./dist/src/index.d.ts",
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/src/index.d.ts",
22
+ "import": "./dist/src/index.js",
23
+ "default": "./dist/src/index.js"
24
+ }
25
+ },
26
+ "files": [
27
+ "dist",
28
+ "src"
29
+ ],
30
+ "scripts": {
31
+ "dev": "bun --watch src/index.ts",
32
+ "start": "bun src/index.ts",
33
+ "build": "bun build src/index.ts --outdir dist --target bun",
34
+ "lint": "eslint .",
35
+ "lint:fix": "eslint . --fix"
36
+ },
37
+ "dependencies": {
38
+ "logging-pretty": "^3.0.0",
39
+ "gramstax": "^0.1.0"
40
+ },
41
+ "peerDependencies": {
42
+ "typescript": "5.9.3"
43
+ },
44
+ "devDependencies": {
45
+ "@types/bun": "latest",
46
+ "pm2": "^5.3.0"
47
+ }
48
+ }
@@ -1,4 +1,4 @@
1
- import { CtxCore } from "~/core/ctx"
1
+ import { CtxCore } from "~/core"
2
2
 
3
3
  export abstract class GuardBase extends CtxCore {
4
4
  public constructor(ctx: CtxCore) {
@@ -0,0 +1,4 @@
1
+ export * from "./guard"
2
+ export * from "./page"
3
+ export * from "./repository"
4
+ export * from "./service"
@@ -1,3 +1,3 @@
1
- import { CtxCore } from "~/core/ctx"
1
+ import { CtxCore } from "~/core"
2
2
 
3
3
  export abstract class PageBase extends CtxCore {}
@@ -1,7 +1,7 @@
1
1
  import { Gramstax } from "gramstax"
2
- import { UserGuard } from "../guards/user"
3
- import { GeneralErrorPage } from "../pages/general-error"
4
- import { GeneralErrorInputNotFoundPage } from "../pages/general-error-input-notfound"
2
+ import { UserGuard } from "~/guards"
3
+ import { GeneralErrorPage } from "~/pages/general-error"
4
+ import { GeneralErrorInputNotFoundPage } from "~/pages/general-error-input-notfound"
5
5
  import type { CtxCore } from "./ctx"
6
6
 
7
7
  export class BotCore extends Gramstax {
@@ -0,0 +1,2 @@
1
+ export * from "./bot"
2
+ export * from "./ctx"
@@ -1,3 +1 @@
1
- // YOU CAN DELETE THIS FILE
2
-
3
1
  export class Db {}
@@ -1,6 +1,5 @@
1
1
  export const env = {
2
2
  BOT_TOKEN: process.env.BOT_TOKEN as string,
3
3
  BOT_DEPLOY: process.env.BOT_DEPLOY as string,
4
- NODE_ENV: process.env.NODE_ENV as string,
5
4
  CACHE_SESSION: process.env.CACHE_SESSION as string
6
5
  }
@@ -0,0 +1 @@
1
+ export * from "./user"
@@ -1,11 +1,11 @@
1
- import { GuardBase } from "~/base/guard"
2
- import { GeneralErrorPage } from "../pages/general-error"
3
- import { UserNameNotFoundPage } from "../pages/username-notfound"
1
+ import { GuardBase } from "~/base"
2
+ import { GeneralErrorPage } from "~/pages/general-error"
3
+ import { UserNameNotFoundPage } from "~/pages/username-notfound"
4
4
 
5
5
  export class UserGuard extends GuardBase {
6
6
  public async ensureValid(isEdit: boolean) {
7
7
  try {
8
- if (!this.username || this.username.length == 0) {
8
+ if (!this.userName || this.userName.length == 0) {
9
9
  await new UserNameNotFoundPage(this).transition(isEdit)
10
10
  return null
11
11
  }
@@ -1,10 +1,10 @@
1
- import { PageBase } from "~/base/page"
1
+ import { PageBase } from "~/base"
2
2
  import { StartPage } from "./start"
3
3
 
4
4
  export class GeneralErrorInputNotFoundPage extends PageBase {
5
5
  public kb() {
6
6
  return this.inlineKeyboard((kb, arr) => {
7
- return kb.text(arr[0], StartPage.data.callbackData())
7
+ return kb.text(arr[0]!, StartPage.data.callbackData())
8
8
  })
9
9
  }
10
10
 
@@ -19,21 +19,10 @@ export class GeneralErrorInputNotFoundPage extends PageBase {
19
19
  <keyboard lang="it" type="inline">.. Casa</keyboard>
20
20
  <keyboard lang="id" type="inline">.. Beranda</keyboard>
21
21
 
22
- <message>
23
- <b>❌ Not Found</b>
24
- </message>
25
-
26
- <message lang="en">
27
- <b>❌ Not Found</b>
28
- </message>
29
-
30
- <message lang="it">
31
- <b>❌ Non Trovato</b>
32
- </message>
33
-
34
- <message lang="id">
35
- <b>❌ Tidak Ditemukan</b>
36
- </message>
22
+ <message><b>❌ Not Found</b></message>
23
+ <message lang="en"><b>❌ Not Found</b></message>
24
+ <message lang="it"><b>❌ Non Trovato</b></message>
25
+ <message lang="id"><b>❌ Tidak Ditemukan</b></message>
37
26
  </base>
38
27
  `
39
28
  }
@@ -1,15 +1,16 @@
1
- import { PageBase } from "~/base/page"
1
+ import { log } from "~/utils"
2
+ import { PageBase } from "~/base"
2
3
  import { StartPage } from "./start"
3
4
 
4
5
  export class GeneralErrorPage extends PageBase {
5
6
  public kb() {
6
7
  return this.inlineKeyboard((kb, arr) => {
7
- return kb.text(arr[0], StartPage.data.callbackData())
8
+ return kb.text(arr[0]!, StartPage.data.callbackData())
8
9
  })
9
10
  }
10
11
 
11
- public async transition(constructorName: string, funcName: string, error: any, isUpdate = true) {
12
- this.logError(error, constructorName, funcName)
12
+ public async transition(constructorName: string, funcName: string, error: unknown, isUpdate = true) {
13
+ log.errorMake(error, constructorName, funcName)
13
14
  await this.sessionClear()
14
15
 
15
16
  const kb = this.kb()
@@ -1,11 +1,10 @@
1
- import { PageBase } from "~/base/page"
1
+ import { PageBase } from "~/base"
2
2
  import { StartPage } from "./start"
3
3
 
4
4
  export class HelpPage extends PageBase {
5
5
  public kb() {
6
6
  return this.inlineKeyboard((kb, arr) => {
7
- return kb //
8
- .text(arr[0], StartPage.data.callbackData())
7
+ return kb.text(arr[0]!, StartPage.data.callbackData())
9
8
  })
10
9
  }
11
10
 
@@ -41,21 +40,10 @@ export class HelpPage extends PageBase {
41
40
  <keyboard lang="it" type="inline">.. Ritorno</keyboard>
42
41
  <keyboard lang="id" type="inline">.. Kembali</keyboard>
43
42
 
44
- <message>
45
- <b>Help message</b>
46
- </message>
47
-
48
- <message lang="en">
49
- <b>Help message</b>
50
- </message>
51
-
52
- <message lang="it">
53
- <b>Ordina aiuto</b>
54
- </message>
55
-
56
- <message lang="id">
57
- <b>Pesan bantuan</b>
58
- </message>
43
+ <message><b>Help message</b></message>
44
+ <message lang="en"><b>Help message</b></message>
45
+ <message lang="it"><b>Ordina aiuto</b></message>
46
+ <message lang="id"><b>Pesan bantuan</b></message>
59
47
  </base>
60
48
  `
61
49
  }
@@ -1,17 +1,16 @@
1
1
  import { HelpPage } from "./help"
2
- import { PageBase } from "~/base/page"
2
+ import { PageBase } from "~/base"
3
3
 
4
4
  export class StartPage extends PageBase {
5
5
  public kb() {
6
6
  return this.inlineKeyboard((kb, arr) => {
7
- return kb //
8
- .text(arr[0], HelpPage.data.callbackData())
7
+ return kb.text(arr[0]!, HelpPage.data.callbackData())
9
8
  })
10
9
  }
11
10
 
12
11
  public async internal(edit = true) {
13
12
  const kb = this.kb()
14
- const data = { username: this.username }
13
+ const data = { userName: this.userName }
15
14
  if (edit) {
16
15
  await this.edit(kb, data)
17
16
  } else {
@@ -43,25 +42,25 @@ export class StartPage extends PageBase {
43
42
  <keyboard lang="id" type="inline">❓ Bantuan</keyboard>
44
43
 
45
44
  <message>
46
- <b>Welcome to the bot {{username}}</b>
45
+ <b>Welcome to the bot {{userName}}</b>
47
46
 
48
47
  <b>❓ Help</b> - View help
49
48
  </message>
50
49
 
51
50
  <message lang="en">
52
- <b>Welcome to the bot {{username}}</b>
51
+ <b>Welcome to the bot {{userName}}</b>
53
52
 
54
53
  <b>❓ Help</b> - View help
55
54
  </message>
56
55
 
57
56
  <message lang="it">
58
- <b>Benvenuto nel Bot di {{username}}</b>
57
+ <b>Benvenuto nel Bot di {{userName}}</b>
59
58
 
60
59
  <b>❓ Aiuto</b> - Ottieni assistenza e informazioni
61
60
  </message>
62
61
 
63
62
  <message lang="id">
64
- <b>Selamat datang di bot {{username}}</b>
63
+ <b>Selamat datang di bot {{userName}}</b>
65
64
 
66
65
  <b>❓ Bantuan</b> - Lihat bantuan
67
66
  </message>
@@ -1,21 +1,19 @@
1
1
  import { HelpPage } from "./help"
2
- import { PageBase } from "~/base/page"
2
+ import { PageBase } from "~/base"
3
3
 
4
4
  export class UserNameNotFoundPage extends PageBase {
5
5
  public kb() {
6
6
  return this.inlineKeyboard((kb, arr) => {
7
- return kb //
8
- .text(arr[0], HelpPage.data.callbackData())
7
+ return kb.text(arr[0]!, HelpPage.data.callbackData())
9
8
  })
10
9
  }
11
10
 
12
11
  public async transition(edit = true) {
13
12
  const kb = this.kb()
14
- const data = { username: this.username }
15
13
  if (edit) {
16
- await this.edit(kb, data)
14
+ await this.edit(kb)
17
15
  } else {
18
- await this.reply(kb, data)
16
+ await this.reply(kb)
19
17
  }
20
18
  }
21
19
 
@@ -26,21 +24,10 @@ export class UserNameNotFoundPage extends PageBase {
26
24
  <keyboard lang="es" type="inline">.. Inicio</keyboard>
27
25
  <keyboard lang="id" type="inline">.. Beranda</keyboard>
28
26
 
29
- <message>
30
- Please set the username first before using the bot.
31
- </message>
32
-
33
- <message lang="en">
34
- Please set the username first before using the bot.
35
- </message>
36
-
37
- <message lang="it">
38
- Prima di utilizzare il bot, imposta prima il nome utente.
39
- </message>
40
-
41
- <message lang="id">
42
- Tolong set username dulu sebelum memakai bot
43
- </message>
27
+ <message>Please set the username first before using the bot.</message>
28
+ <message lang="en">Please set the username first before using the bot.</message>
29
+ <message lang="it">Prima di utilizzare il bot, imposta prima il nome utente.</message>
30
+ <message lang="id">Tolong set username dulu sebelum memakai bot</message>
44
31
  </base>
45
32
  `
46
33
  }
@@ -1,5 +1,3 @@
1
- // YOU CAN DELETE THIS FILE
2
-
3
- import { RepositoryBase } from "../base/repository"
1
+ import { RepositoryBase } from "~/base"
4
2
 
5
3
  export class ExampleRepo extends RepositoryBase {}
@@ -0,0 +1 @@
1
+ export * from "./example"
@@ -1,4 +1,3 @@
1
- // YOU CAN DELETE THIS FILE
2
- import { ServiceBase } from "../base/service"
1
+ import { ServiceBase } from "~/base/service"
3
2
 
4
3
  export class ExampleService extends ServiceBase {}
@@ -0,0 +1 @@
1
+ export * from "./example"
@@ -0,0 +1 @@
1
+ export * from "./main"
@@ -1,9 +1,9 @@
1
1
  import { isMainThread } from "bun"
2
2
 
3
3
  export class MainThread {
4
- constructor(mainFunc: () => any) {
4
+ constructor(wrapCode: () => any) {
5
5
  if (isMainThread === true) {
6
- mainFunc()
6
+ wrapCode()
7
7
  }
8
8
  }
9
9
  }
@@ -0,0 +1 @@
1
+ export * from "./log"
@@ -1,3 +1,2 @@
1
- import { LoggingPretty } from "logging-pretty"
2
-
3
- export const log = new LoggingPretty()
1
+ import { log } from "gramstax"
2
+ export { log }
package/package.json CHANGED
@@ -1,57 +1,63 @@
1
- {
2
- "name": "create-gramstax",
3
- "version": "0.0.27",
4
- "private": false,
5
- "description": "CLI tool to quickly create a new Gramstax Telegram bot project with all the best practices",
6
- "keywords": [
7
- "create-gramstax",
8
- "gramstax",
9
- "telegram",
10
- "bot",
11
- "cli",
12
- "generator",
13
- "scaffold",
14
- "telegram-bot"
15
- ],
16
- "repository": {
17
- "type": "git",
18
- "url": "git+https://github.com/gramstax/gramstax.git",
19
- "directory": "packages/create-gramstax"
20
- },
21
- "bugs": {
22
- "url": "https://github.com/gramstax/gramstax/issues"
23
- },
24
- "homepage": "https://github.com/gramstax/gramstax",
25
- "author": "gramstax",
26
- "license": "MIT",
27
- "type": "module",
28
- "main": "./dist/src/index.js",
29
- "module": "./dist/src/index.mjs",
30
- "types": "./dist/src/index.d.ts",
31
- "bin": {
32
- "create-gramstax": "dist/src/index.js"
33
- },
34
- "exports": {
35
- ".": {
36
- "types": "./dist/src/index.d.ts",
37
- "import": "./dist/src/index.js",
38
- "default": "./dist/src/index.js"
39
- }
40
- },
41
- "files": [
42
- "dist"
43
- ],
44
- "devDependencies": {
45
- "@types/bun": "latest",
46
- "tsup": "^8.5.1"
47
- },
48
- "peerDependencies": {
49
- "typescript": "^5.9.3"
50
- },
51
- "dependencies": {
52
- "commander": "^14.0.2",
53
- "enquirer": "^2.4.1",
54
- "gramstax": "latest",
55
- "logging-pretty": "^3.0.0"
56
- }
57
- }
1
+ {
2
+ "name": "create-gramstax",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "publishConfig": {
6
+ "access": "public",
7
+ "provenance": false
8
+ },
9
+ "description": "CLI tool to quickly create a new Gramstax Telegram bot project with all the best practices",
10
+ "keywords": [
11
+ "create-gramstax",
12
+ "gramstax",
13
+ "telegram",
14
+ "bot",
15
+ "cli",
16
+ "generator",
17
+ "scaffold",
18
+ "telegram-bot"
19
+ ],
20
+ "scripts": {
21
+ "nx-release-publish": "npm publish --access public"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/gramstax/gramstax.git",
26
+ "directory": "packages/create-gramstax"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/gramstax/gramstax/issues"
30
+ },
31
+ "homepage": "https://github.com/gramstax/gramstax",
32
+ "author": "gramstax",
33
+ "license": "MIT",
34
+ "type": "module",
35
+ "main": "./dist/src/index.js",
36
+ "module": "./dist/src/index.mjs",
37
+ "types": "./dist/src/index.d.ts",
38
+ "bin": {
39
+ "create-gramstax": "dist/src/index.js"
40
+ },
41
+ "exports": {
42
+ ".": {
43
+ "types": "./dist/src/index.d.ts",
44
+ "import": "./dist/src/index.js",
45
+ "default": "./dist/src/index.js"
46
+ }
47
+ },
48
+ "files": [
49
+ "dist"
50
+ ],
51
+ "devDependencies": {
52
+ "@types/bun": "latest",
53
+ "tsup": "^8.5.1"
54
+ },
55
+ "peerDependencies": {
56
+ "typescript": "^5.9.3"
57
+ },
58
+ "dependencies": {
59
+ "commander": "^14.0.2",
60
+ "enquirer": "^2.4.1",
61
+ "logging-pretty": "^3.0.0"
62
+ }
63
+ }
@@ -1 +0,0 @@
1
- *.html
@@ -1,26 +0,0 @@
1
- module.exports = {
2
- apps: [
3
- {
4
- name: `{{projectName}}`, // Process name (appears in 'pm2 list')
5
- script: `bun`, // Main command to run (using Bun runtime)
6
- args: `src/index.ts`, // Arguments for the command (entry file)
7
- instances: 1, // Number of instances (use 'max' for multi-core)
8
- exec_mode: `fork`, // Cluster mode (PM2 will balance across cores)
9
- autorestart: true, // Automatically restart if the process crashes
10
- watch: false, // Disable auto-reload on file changes (set true for dev)
11
- max_memory_restart: undefined, // Restart if memory usage exceeds (default undefined)
12
- env: {
13
- NODE_ENV: `production`, // Default environment variables
14
- },
15
- env_production: {
16
- NODE_ENV: `production`, // Environment variables for production mode
17
- },
18
- error_file: `./logs/err.log`, // Error log file
19
- out_file: `./logs/out.log`, // Standard output log file
20
- log_file: `./logs/combined.log`, // Combined log file
21
- time: false, // Add timestamps to logs
22
- merge_logs: false, // Merge logs from multiple instances
23
- log_date_format: `YYYY-MM-DD HH:mm:ss Z`, // Log date format
24
- },
25
- ],
26
- };
@@ -1,3 +0,0 @@
1
- import { BaseGeneral } from "gramstax"
2
-
3
- export abstract class GeneralBase extends BaseGeneral {}