@minima-global/create-minima-app
Version:
<p align="center"> A Cli for creating and building MiniDapps on the Minima Blockchain. </p>
26 lines • 16.1 kB
JavaScript
import{Command as fe}from"commander";var j={name:"@minima-global/create-minima-app",version:"0.2.3",files:["dist","templates","README.md"],type:"module",exports:"./dist/index.js",bin:{"create-minima-app":"./dist/index.js"},publishConfig:{access:"public"},keywords:["minima","typescript","mds","minidapps","minima-blockchain","web3"],homepage:"https://github.com/minima-global/dev-tools",bugs:{url:"https://github.com/minima-global/dev-tools/issues"},repository:{type:"git",url:"https://github.com/minima-global/dev-tools"},author:"Minima Global",license:"MIT",scripts:{build:"tsup",dev:"tsup --watch",lint:"eslint .",clean:"rm -rf dist",format:'prettier --write "./src/**/**.ts" --write',"check-format":'prettier "./src/**/**.ts" --check'},dependencies:{"@minima-global/mds":"0.14.11","@minima-global/minima-cli":"0.1.5",axios:"^1.7.7",chalk:"^5.3.0",commander:"^12.1.0",figlet:"^1.8.0",ora:"^8.1.1",prompts:"^2.4.2",puppeteer:"^23.9.0",zod:"^3.23.8",vite:"^6.0.2"},devDependencies:{"@types/figlet":"^1.7.0","@types/fs-extra":"^11.0.4","@types/node":"^20.14.10","@types/prompts":"^2.4.9","@typescript-eslint/eslint-plugin":"^6.0.0","@typescript-eslint/parser":"^6.0.0",eslint:"^8.0.0",tsup:"^8.0.0",typescript:"^5.0.0"}};import{configureDappConf as x,install as T,zip as O}from"@minima-global/minima-cli";import k from"chalk";import{exec as C}from"child_process";import{Command as ae}from"commander";import re from"figlet";import*as u from"fs";import{readFileSync as oe}from"fs";import D from"path";import m from"prompts";import{fileURLToPath as se}from"url";import{z as d}from"zod";import{execSync as G}from"child_process";import _ from"fs";import V from"path";import{execSync as I}from"child_process";function g(){try{if(process.env.npm_config_user_agent)return process.env.npm_config_user_agent.startsWith("yarn")?"yarn":process.env.npm_config_user_agent.startsWith("pnpm")?"pnpm":process.env.npm_config_user_agent.startsWith("bun")?"bun":"npm";try{return I("bun -v",{stdio:"ignore"}),"bun"}catch{try{return I("pnpm -v",{stdio:"ignore"}),"pnpm"}catch{try{return I("yarn -v",{stdio:"ignore"}),"yarn"}catch{return"npm"}}}}catch{return"npm"}}function y(e){switch(e){case"npm":return"npm install";case"yarn":return"yarn";case"pnpm":return"pnpm install";case"bun":return"bun install"}}function h(e,n){switch(e){case"npm":return`npm run ${n}`;case"yarn":return`yarn run ${n}`;case"pnpm":return`pnpm run ${n}`;case"bun":return`bun run ${n}`}}import M from"chalk";var r={error(...e){console.log(M.red(e.join(" ")))},warn(...e){console.log(M.yellow(e.join(" ")))},info(...e){console.log(M.blue(e.join(" ")))},success(...e){console.log(M.green(e.join(" ")))},log(...e){console.log(e.join(" "))},secondary(...e){console.log(M.gray(e.join(" ")))},break(){console.log("")}};import B from"ora";function w(e,n){return B({text:e,isSilent:n?.silent})}async function S(e,n){let i=w("Configuring Minima CLI...").start();try{let t=V.join(e,"package.json"),a=JSON.parse(_.readFileSync(t,"utf-8")),o=a.devDependencies?.["@minima-global/minima-cli"]||a.dependencies?.["@minima-global/minima-cli"],c=a.devDependencies?.["@minima-global/mds"]||a.dependencies?.["@minima-global/mds"],s=n.toLowerCase().includes("react"),p=g();(!o||s&&!c)&&(i.stop(),r.secondary("Installing required packages..."),o||G(`${y(p)} -D @minima-global/minima-cli`,{cwd:e,stdio:"inherit"}),s&&!c&&G(`${y(p)} @minima-global/mds`,{cwd:e,stdio:"inherit"}),a=JSON.parse(_.readFileSync(t,"utf-8")),i.start()),i.text="Configuring Minima CLI scripts...";let l=Object.keys(a.scripts||{}).some(E=>E.startsWith("minima:"));l||(a.scripts={...a.scripts,"minima:zip":"minima zip","minima:install":"minima install","minima:update":"minima update","minima:uninstall":"minima uninstall","minima:refresh":"minima zip && minima uninstall && minima install"},_.writeFileSync(t,JSON.stringify(a,null,2)+`
`)),i.succeed(o&&l?"Minima CLI already configured":"Successfully configured Minima CLI scripts")}catch(t){throw i.fail("Failed to configure Minima CLI"),r.error(t instanceof Error?t.message:String(t)),t}}import{existsSync as v}from"fs";import{join as N}from"path";async function R(){let e=process.cwd(),n=v(N(e,"src","AppContext.tsx"))||v(N(e,"src","routes")),t=N(e,n?"public":".","dapp.conf");return v(t)?{exists:!0,template:n?"react-ts":"vanilla-js"}:{exists:!1,template:null}}import L from"chalk";import F from"fs/promises";import W from"path";import H from"puppeteer";import{z as f}from"zod";import{writeFile as z}from"fs";import{z as b}from"zod";var J=b.object({VITE_DEBUG:b.literal("true"),VITE_DEBUG_HOST:b.string(),VITE_DEBUG_MDS_PORT:b.number(),VITE_DEBUG_SESSION_ID:b.string()});async function $(e){let n=J.parse(e);var i="";i+=`VITE_DEBUG=true
`,i+=`VITE_DEBUG_HOST=${n.VITE_DEBUG_HOST}
`,i+=`VITE_DEBUG_MDS_PORT=${n.VITE_DEBUG_MDS_PORT}
`,i+=`VITE_DEBUG_SESSION_ID=${n.VITE_DEBUG_SESSION_ID}
`,await new Promise((t,a)=>{z(".env",i,o=>{o&&a(o),t(!0)})})}var Y=f.object({port:f.number(),password:f.string(),packageManager:f.custom(),appName:f.string(),host:f.string(),logs:f.boolean(),template:f.string()});async function P(e){let n=w("Configuring debug settings...").start();try{let i=Y.parse(e),t=await q(),a=await Z(t,i.host,i.port);await K(a,i.password,n),await Q(a,n);let o=await X(a);await t.close(),await ee(i,o),ne(i,n),process.exit(0)}catch(i){let t=i instanceof Error?i:new Error(String(i));n.fail("Debug configuration failed"),r.error(`Error: ${t.message}`),process.exit(1)}}async function q(){return await H.launch({headless:!0,acceptInsecureCerts:!0,ignoreDefaultArgs:["--disable-extensions","--ignore-certificate-errors"]})}async function Z(e,n,i){let t=await e.newPage();return await t.setViewport({width:1280,height:1024}),await t.goto(`https://${n}:${i}`),await t.waitForNetworkIdle(),t}async function K(e,n,i){try{await e.type("#password",n),await Promise.all([e.waitForNavigation({waitUntil:"networkidle0"}),e.click("[type='submit']")]),await new Promise(t=>setTimeout(t,2e3))}catch(t){i.fail("Login failed"),t instanceof Error&&r.error(`Failed to login: ${t.message}`),r.info("Please check your password, host, port and try again."),process.exit(1)}}async function Q(e,n){try{await e.evaluate(()=>document.body.innerText.includes("Click anywhere to continue")).catch(()=>!1)&&(await e.click("body").catch(t=>{n.fail("Something went wrong!"),r.error(`Failed to click body: ${t.message}`),r.info("Please check your password, host, port and try again."),process.exit(1)}),await new Promise(t=>setTimeout(t,2e3)))}catch(i){r.info(`Error checking for fresh node: ${i}. Proceeding anyway.`)}}async function X(e){if(!await e.evaluate(()=>typeof window.MDS<"u"&&window.MDS!==null).catch(()=>!1))throw new Error("MDS object not found on the page. This may indicate that you're not properly logged in or the Minima node is not running correctly.");let i=await e.evaluate(()=>new Promise((t,a)=>{if(!window.MDS){a(new Error("MDS is not defined in the window object"));return}try{window.MDS.dapplink("Health",function(o){if(!o||o.status===!1){a(new Error(`MDS.dapplink failed: ${JSON.stringify(o)}`));return}t(o)})}catch(o){a(new Error(`Exception in MDS.dapplink: ${o}`))}}));if(!i||!i.sessionid)throw new Error(`Invalid data returned from MDS.dapplink: ${JSON.stringify(i)}`);return i.sessionid}async function ee(e,n){e.template==="vanilla-js"?await ie(e,n):await te(e,n)}async function ie(e,n){let i=W.join(process.cwd(),"mds.js"),a=(await F.readFile(i,"utf-8")).replace(/DEBUG_HOST: null,/,`DEBUG_HOST: "${e.host}",`).replace(/DEBUG_PORT: -1,/,`DEBUG_PORT: ${e.port},`).replace(/DEBUG_MINIDAPPID: "0x00",/,`DEBUG_MINIDAPPID: "${n}",`);await F.writeFile(i,a,"utf-8")}async function te(e,n){await $({VITE_DEBUG_MDS_PORT:e.port,VITE_DEBUG_SESSION_ID:n,VITE_DEBUG:"true",VITE_DEBUG_HOST:e.host})}function ne(e,n){n.succeed(L.green(`Debug settings configured successfully!
`)),e.logs&&(r.secondary(`You can navigate to your project directory with:
`),r.secondary(`cd ${e.appName}`),e.template==="react-ts"&&r.secondary(`${h(e.packageManager,"dev")}`)),r.secondary(`If you need further help or guidance, visit https://docs.minima.global
`)}var pe=d.object({appName:d.string().min(1),isNewProject:d.boolean(),port:d.number(),rpc:d.boolean(),template:d.enum(["react-ts","vanilla-js"],{required_error:"Template is required",message:"Template must be either react-ts or vanilla-js"}),service:d.boolean()}),U=new ae().name("init").description("Initialize a new Minima App or configure an existing one").option("-n, --name <name>","the name of the app","minima-app").option("-p, --port <port>","the port of the Minima node","9001").option("-r, --rpc","the RPC URL of the Minima node",!0).option("-s, --service","create a service.js file",!1).option("-t, --template <template>","the template to use","react-ts").action(async e=>{try{r.break(),r.log(re.textSync("Create Minidapp",{font:"ANSI Shadow"})),r.secondary(`Welcome to the Minima CLI. This tool will help you create a new Minima MiniDapp.
Documentation: https://docs.minima.global/docs/development/cli`),r.break();let n=await R(),i=pe.parse({port:Number(e.port)||9001,appName:e.name,rpc:e.rpc,isNewProject:!n,configOnly:e.configOnly,template:n.template?n.template:e.template,service:e.service});if(n.exists){let{RE_CONFIGURE:s}=await m({type:"confirm",name:"RE_CONFIGURE",message:"Looks like you already have a Minima App! Would you like to reconfigure?",initial:!0});s||process.exit(0),await ce(i)}if(i.appName==="minima-app"){let{APP_NAME:s}=await m({type:"text",name:"APP_NAME",message:"What is the name of your project?"});s||process.exit(0),i.appName=s}await le(i.appName)&&(r.error(`${i.appName} already exists`),process.exit(1));let{RUNNING_RPC:t}=await m({type:"confirm",name:"RUNNING_RPC",message:`Are you running Minima RPC?
To learn more about RPC, visit https://docs.minima.global/rpc
`,initial:i.rpc,active:"no",inactive:"yes"});if(i.rpc=t,i.rpc){let{MINIMA_PORT:s}=await m({type:"number",name:"MINIMA_PORT",message:"What port is your Minima node running on?",initial:i.port});s||process.exit(0),i.port=s}let{TEMPLATE:a}=await m({type:"select",name:"TEMPLATE",message:"Which template would you like to use?",choices:[{title:"React TS",value:"react-ts"},{title:"Vanilla JS",value:"vanilla-js"}],initial:0});a||process.exit(0),i.template=a;let{SERVICE:o}=await m({type:"confirm",name:"SERVICE",message:`Would you like to create a service.js file?
To learn more about services, visit https://docs.minima.global/docs/development/minidapp-servicejs
`,initial:!1});i.service=o,await me(i);let c=g();if(i.rpc){let{DEBUG_CONFIG:s}=await m({type:"confirm",name:"DEBUG_CONFIG",message:"Would you like to configure your debug settings?",initial:!0,active:"no",inactive:"yes"});if(s){let{MDS_PASSWORD:p}=await m({type:"password",name:"MDS_PASSWORD",message:"Enter your MDS password:"}),{MINIMA_HOST:l}=await m({type:"text",name:"MINIMA_HOST",message:"Enter the host where Minima is running:",initial:"127.0.0.1",instructions:"This is the host where Minima is running. Default is 127.0.0.1 (localhost)"});i.template||(r.error("Template is required"),process.exit(1)),await P({port:i.port?i.port+2:9003,password:p,packageManager:c,appName:i.appName,host:l,logs:!0,template:i.template})}r.info(`Project created successfully!
`),r.info("To be able to run your minidapp in debug mode, you need to configure your debug settings."),r.info(`You can re-run the init command inside your project directory to configure your debug settings at any time.
`),r.info(`You can navigate to your project directory with:
`),r.info(`cd ${i.appName}
`)}}catch(n){n instanceof d.ZodError&&(r.error("Invalid options:"),n.errors.forEach(i=>{r.error(`- ${i.path.join(".")}: ${i.message}`)})),process.exit(1)}});async function ce(e){let{RUNNING_RPC:n}=await m({type:"confirm",name:"RUNNING_RPC",message:`Are you running Minima RPC?
To learn more about RPC, visit https://docs.minima.global/rpc
`,initial:!0,active:"no",inactive:"yes"});n||process.exit(0);let{MINIMA_PORT:i}=await m({type:"number",name:"MINIMA_PORT",message:"What port is your Minima node running on?",initial:e.port});i||process.exit(0),e.port=i;let t=JSON.parse(oe("package.json","utf-8"));await S(process.cwd(),e.template);let a=w("Installing MiniDapp...").start();await x();let o=`${t.name}-${t.version}.mds.zip`,c=e.template==="react-ts"?"build/":"./";await O(o,c),await T({port:e.port?e.port+4:9005,pathToFile:process.cwd(),miniDappName:t.name,miniDappVersion:t.version}),a.succeed("MiniDapp installed successfully!");let{DEBUG_CONFIG:s}=await m({type:"confirm",name:"DEBUG_CONFIG",message:"Would you like to configure your debug settings and install the Minima CLI?",initial:!0,active:"no",inactive:"yes"});if(s){let{MDS_PASSWORD:p}=await m({type:"password",name:"MDS_PASSWORD",message:"Enter your MDS password:"}),{MINIMA_HOST:l}=await m({type:"text",name:"MINIMA_HOST",message:"Enter the host where Minima is running:",initial:"127.0.0.1"}),E=g();e.template||(r.error("Template is required"),process.exit(1)),await P({port:i+2,password:p,packageManager:E,appName:t.name,host:l,logs:!0,template:e.template})}else{let p=g();r.info(`You can now run your MiniDapp with:
`),r.info(`cd ${t.name}
`),r.info(`${h(p,"dev")}
`),process.exit(0)}}async function me(e){let n=se(import.meta.url),i=D.dirname(n),t=w("Creating project directory...").start();try{await u.promises.mkdir(e.appName),t.text="Setting up template...";let a=D.join(i,`../templates/${e.template}`);if(!await u.promises.access(a).then(()=>!0).catch(()=>!1))throw new Error(`Template directory not found: ${a}`);await u.promises.cp(a,e.appName,{recursive:!0}),process.chdir(e.appName),e.template==="react-ts"?await ue(e,t):await ge(e,t),t.succeed(k.green("Project created successfully!"))}catch(a){a instanceof Error?(t.fail(k.red(`${a.message}`)),r.break(),r.info("Your project has been created but the installation failed"),r.info("You can install the MiniDapp manually or re-run the `init` command inside your project directory to try again"),r.break(),r.info("For more information, visit https://docs.minima.global/docs/development/cli")):t.fail(k.red(`Something went wrong:
${a}`)),process.exit(1)}}async function le(e){return u.promises.access(D.join(process.cwd(),e)).then(()=>!0).catch(()=>!1)}async function ue(e,n){if(e.service){let c=D.join(process.cwd(),"public","service.js");await u.promises.writeFile(c,"")}n.text="Configuring package.json...";let i="./package.json",t=JSON.parse(await u.promises.readFile(i,"utf-8"));t.name=e.appName,t.description=`${e.appName} MiniDapp`,await u.promises.writeFile(i,JSON.stringify(t,null,2));let a=g();n.text="Installing dependencies...",await new Promise((c,s)=>{C(y(a),(p,l)=>{p&&s(p),c(l)})}),n.text="Configuring Minima CLI...",await S(process.cwd(),e.template),n.text="Building MiniDapp...",await new Promise((c,s)=>{C(h(a,"build"),(p,l)=>{p&&s(p),c(l)})}),await x();let o=`${t.name}-${t.version}.mds.zip`;await O(o,"build/"),e.rpc&&await T({port:e.port?e.port+4:9005,pathToFile:process.cwd(),miniDappName:t.name,miniDappVersion:t.version})}async function ge(e,n){if(e.service){let c=D.join(process.cwd(),"service.js");await u.promises.writeFile(c,"")}n.text="Configuring package.json...";let i="./package.json",t=JSON.parse(await u.promises.readFile(i,"utf-8"));t.name=e.appName,t.description=`${e.appName} MiniDapp`,await u.promises.writeFile(i,JSON.stringify(t,null,2));let a=g();n.text="Installing dependencies...",await new Promise((c,s)=>{C(y(a),(p,l)=>{p&&s(p),c(l)})}),n.text="Configuring Minima CLI...",await S(process.cwd(),e.template),n.text="Building MiniDapp...",await x(),n.text="Zipping and installing MiniDapp...";let o=`${t.name}-${t.version}.mds.zip`;await O(o,"./"),n.text="Installing MiniDapp...",await T({port:e.port?e.port+4:9005,pathToFile:process.cwd(),miniDappName:t.name,miniDappVersion:t.version})}process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function de(){let e=new fe().name("create-minima-app").description("Create a Minima App").version(j.version||"0.0.1","-v, --version","display the version number");e.addCommand(U),e.parse()}de();
//# sourceMappingURL=index.js.map