create-w3-app
Version:
Create ethereum dApps with w3 stack
61 lines (52 loc) • 25.5 kB
JavaScript
import $e from"path";import{execa as vt}from"execa";import Fe from"fs-extra";import*as m from"@clack/prompts";import ee from"chalk";import{Command as Xe}from"commander";import X from"path";import{fileURLToPath as Be}from"url";var Le=Be(import.meta.url),ze=X.dirname(Le),p=X.join(ze,"../"),q=`
\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557
\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D
\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2550\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u255D
\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2554\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551
\u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
`,T="my-w3-app",G="create-w3-app";import Ke from"path";import Ye from"fs-extra";var v=()=>{let e=Ke.join(p,"package.json");return Ye.readJSONSync(e).version??"1.0.0"};var f=()=>{let e=process.env.npm_config_user_agent;return e?e.startsWith("yarn")?"yarn":e.startsWith("pnpm")?"pnpm":e.startsWith("bun")?"bun":"npm":"npm"};var k=class extends Error{constructor(t){super(t)}};import R from"chalk";var r={error(...e){console.log(R.red(...e))},warn(...e){console.log(R.yellow(...e))},info(...e){console.log(R.cyan(...e))},success(...e){console.log(R.green(...e))}};var M=e=>(e.length>1&&e.endsWith("/")&&(e=e.slice(0,-1)),e);var He=/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,Q=e=>{let t=M(e),o=t.split("/"),i=o.findIndex(s=>s.startsWith("@")),n=o[o.length-1];if(o.findIndex(s=>s.startsWith("@"))!==-1&&(n=o.slice(i).join("/")),!(t==="."||He.test(n??"")))return"App name must consist of only lowercase alphanumeric characters, '-', and '_'"};var Z=e=>{if(e.startsWith(".")||e.startsWith("/"))return"Import alias can't start with '.' or '/'"};var P={appName:T,packages:["tailwind","privy","eslint"],flags:{noGit:!1,noInstall:!1,default:!1,CI:!1,tailwind:!1,shadcn:!1,privy:!1,rainbow:!1,importAlias:"~/",appRouter:!1,eslint:!1,biome:!1}},te=async()=>{let e=P,t=new Xe().name(G).description("A CLI for creating dApps with the w3-app stack").argument("[dir]","The name of the application, as well as the name of the directory to create").option("--noGit","Explicitly tell the CLI to not initialize a new git repo in the project",!1).option("--noInstall","Explicitly tell the CLI to not run the package manager's install command",!1).option("-y, --default","Bypass the CLI and use all default options to bootstrap a new w3-app app",!1).option("--CI","Boolean value if we're running in CI",!1).option("--tailwind [boolean]","Experimental: Boolean value if we should install Tailwind CSS. Must be used in conjunction with `--CI`.",i=>!!i&&i!=="false").option("--shadcn [boolean]","Experimental: Boolean value if we should install shadcn/ui. Must be used in conjunction with `--CI`.",i=>!!i&&i!=="false").option("-i, --import-alias","Explicitly tell the CLI to use a custom import alias",P.flags.importAlias).option("--appRouter [boolean]","Explicitly tell the CLI to use the new Next.js app router",i=>!!i&&i!=="false").option("--eslint [boolean]","Experimental: Boolean value if we should install eslint and prettier. Must be used in conjunction with `--CI`.",i=>!!i&&i!=="false").option("--biome [boolean]","Experimental: Boolean value if we should install biome. Must be used in conjunction with `--CI`.",i=>!!i&&i!=="false").version(v(),"-v, --version","Display the version number").addHelpText("afterAll",`
The w3-app stack was inspired by ${ee.hex("#E8DCFF").bold("create-w3-app")}
)}
`).parse(process.argv);process.env.npm_config_user_agent?.startsWith("yarn/3")&&r.warn(` WARNING: It looks like you are using Yarn 3. This is currently not supported,
and likely to result in a crash. Please run create-w3-app with another
package manager such as pnpm, npm, or Yarn Classic.`);let o=t.args[0];if(o&&(e.appName=o),e.flags=t.opts(),e.flags.CI)return e.packages=[],e.flags.tailwind&&e.packages.push("tailwind"),e.flags.shadcn&&e.packages.push("shadcn"),e.flags.privy&&e.packages.push("privy"),e.flags.rainbow&&e.packages.push("rainbow"),e.flags.eslint&&e.packages.push("eslint"),e.flags.biome&&e.packages.push("biome"),e.flags.biome&&e.flags.eslint&&(r.warn("Incompatible combination Biome + ESLint. Exiting."),process.exit(0)),!e.flags.tailwind&&e.flags.shadcn&&(r.warn("Cannot install Shadcn UI without Tailwind Css. Exiting."),process.exit(0)),e;if(e.flags.default)return e;try{if(process.env.TERM_PROGRAM?.toLowerCase().includes("mintty"))throw r.warn(` WARNING: It looks like you are using MinTTY, which is non-interactive. This is most likely because you are
using Git Bash. If that's that case, please use Git Bash from another terminal, such as Windows Terminal. Alternatively, you
can provide the arguments from the CLI directly to skip the prompts.`),new k("Non-interactive environment");let i=f(),n=await m.group({...!o&&{name:()=>m.text({message:"What will your project be called?",defaultValue:o,validate:Q})},language:()=>m.select({message:"Will you be using TypeScript or JavaScript?",options:[{value:"typescript",label:"TypeScript"},{value:"javascript",label:"JavaScript"}],initialValue:"typescript"}),_:({results:a})=>a.language==="javascript"?m.note(ee.redBright("Wrong answer, using TypeScript instead")):void 0,styling:()=>m.confirm({message:"Will you be using Tailwind CSS for styling?"}),shadcn:()=>m.confirm({message:"Would you like to use Shadcn UI for component library?",initialValue:!0}),wallet:()=>m.select({message:"Which wallet authentication solution would you like to use?",options:[{value:"none",label:"None"},{value:"privy",label:"Privy"},{value:"rainbow",label:"Rainbow Kit"}],initialValue:"privy"}),appRouter:()=>m.confirm({message:"Would you like to use Next.js App Router?",initialValue:!0}),linter:()=>m.select({message:"Would you like to use ESLint and Prettier or Biome for linting and formatting?",options:[{value:"eslint",label:"ESLint/Prettier"},{value:"biome",label:"Biome"}],initialValue:"eslint"}),...!e.flags.noGit&&{git:()=>m.confirm({message:"Should we initialize a Git repository and stage the changes?",initialValue:!P.flags.noGit})},...!e.flags.noInstall&&{install:()=>m.confirm({message:`Should we run '${i}`+(i==="yarn"?"'?":" install' for you?"),initialValue:!P.flags.noInstall})},importAlias:()=>m.text({message:"What import alias would you like to use?",defaultValue:P.flags.importAlias,placeholder:P.flags.importAlias,validate:Z})},{onCancel(){process.exit(1)}}),s=[];return n.styling&&s.push("tailwind"),n.shadcn&&(s.push("shadcn"),s.includes("tailwind")||s.push("tailwind")),n.wallet==="privy"&&s.push("privy"),n.wallet==="rainbow"&&s.push("rainbow"),n.appRouter&&(e.flags.appRouter=n.appRouter),n.linter==="eslint"&&s.push("eslint"),n.linter==="biome"&&s.push("biome"),n.git!==void 0&&(e.flags.noGit=!n.git),{appName:n.name??e.appName,packages:s,flags:{...e.flags,appRouter:n.appRouter??e.flags.appRouter,noGit:!n.git||e.flags.noGit,noInstall:!n.install||e.flags.noInstall,importAlias:n.importAlias??e.flags.importAlias}}}catch(i){if(i instanceof k)r.warn(`
${G} needs an interactive terminal to provide options`),await m.confirm({message:"Continue scaffolding a default w3-app app?",initialValue:!0})||(r.info("Exiting..."),process.exit(0)),r.info(`Bootstrapping a default w3-app app in ./${e.appName}`);else throw i}return e};import pe from"fs";import S from"path";import ie from"chalk";import qe from"ora";var ne=e=>{let{packages:t}=e;r.info("Adding boilerplate...");for(let[o,i]of Object.entries(t))if(i.inUse){let n=qe(`Boilerplating ${o}...`).start();i.installer(e),n.succeed(ie.green(`Successfully setup boilerplate for ${ie.green.bold(o)}`))}r.info("")};import V from"path";import*as h from"@clack/prompts";import y from"chalk";import I from"fs-extra";import Qe from"ora";var oe=async({projectName:e,projectDir:t,pkgManager:o,noInstall:i})=>{let n=V.join(p,"template/base");i?r.info(""):r.info(`
Using: ${y.cyan.bold(o)}
`);let s=Qe(`Scaffolding in: ${t}...
`).start();if(I.existsSync(t))if(I.readdirSync(t).length===0)e!=="."&&s.info(`${y.cyan.bold(e)} exists but is empty, continuing...
`);else{s.stopAndPersist();let l=await h.select({message:`${y.redBright.bold("Warning:")} ${y.cyan.bold(e)} already exists and isn't empty. How would you like to proceed?`,options:[{label:"Abort installation (recommended)",value:"abort"},{label:"Clear the directory and continue installation",value:"clear"},{label:"Continue installation and overwrite conflicting files",value:"overwrite"}],initialValue:"abort"});(h.isCancel(l)||l==="abort")&&(s.fail("Aborting installation..."),process.exit(1));let c=await h.confirm({message:`Are you sure you want to ${l==="clear"?"clear the directory":"overwrite conflicting files"}?`,initialValue:!1});(h.isCancel(c)||!c)&&(s.fail("Aborting installation..."),process.exit(1)),l==="clear"&&(s.info(`Emptying ${y.cyan.bold(e)} and creating w3-app..
`),I.emptyDirSync(t))}s.start(),I.copySync(n,t),I.renameSync(V.join(t,"_gitignore"),V.join(t,".gitignore"));let a=e==="."?"App":y.cyan.bold(e);s.succeed(`${a} ${y.green("scaffolded successfully!")}
`)};import d from"path";import N from"fs-extra";var se=({projectDir:e,packages:t})=>{let o=d.join(p,"template/extras/src/pages/_app"),i=t.tailwind.inUse,n=t.privy.inUse,s=t.rainbow.inUse,a="base.tsx";n&&i?a="with-privy-tw.tsx":n&&!i?a="with-privy.tsx":s&&i?a="with-rbow-tw.tsx":s&&!i?a="with-rbow.tsx":i&&!n&&!s&&(a="with-tw.tsx");let l=d.join(o,a),c=d.join(e,"src/pages/_app.tsx");N.copySync(l,c)},ae=({projectDir:e,packages:t})=>{let o=d.join(p,"template/extras/src/app/layout"),i=t.tailwind.inUse,n=t.privy.inUse,s=t.rainbow.inUse,a="base.tsx";n&&i?a="with-privy-tw.tsx":n&&!i?a="with-privy.tsx":s&&i?a="with-rbow-tw.tsx":s&&!i?a="with-rbow.tsx":i&&!n&&!s&&(a="with-tw.tsx");let l=d.join(o,a),c=d.join(e,"src/app/layout.tsx");N.copySync(l,c)},re=({projectDir:e,packages:t})=>{let o=d.join(p,"template/extras/src/pages/index"),i=t.tailwind.inUse,n=t.privy.inUse,s=t.rainbow.inUse,a="base.tsx";n&&i?a="with-privy-tw.tsx":n&&!i?a="with-privy.tsx":s&&i?a="with-rbow-tw.tsx":s&&!i?a="with-rbow.tsx":i&&!n&&!s&&(a="with-tw.tsx");let l=d.join(o,a),c=d.join(e,"src/pages/index.tsx");N.copySync(l,c)},le=({projectDir:e,packages:t})=>{let o=d.join(p,"template/extras/src/app/page"),i=t.tailwind.inUse,n=t.privy.inUse,s=t.rainbow.inUse,a="base.tsx";n&&i?a="with-privy-tw.tsx":n&&!i?a="with-privy.tsx":s&&i?a="with-rbow-tw.tsx":s&&!i?a="with-rbow.tsx":i&&!n&&!s&&(a="with-tw.tsx");let l=d.join(o,a),c=d.join(e,"src/app/page.tsx");N.copySync(l,c)};var ce=async({projectName:e,scopedAppName:t,packages:o,noInstall:i,appRouter:n})=>{let s=f(),a=S.resolve(process.cwd(),e);if(await oe({projectName:e,projectDir:a,pkgManager:s,scopedAppName:t,noInstall:i,appRouter:n}),ne({projectName:e,scopedAppName:t,projectDir:a,pkgManager:s,packages:o,noInstall:i,appRouter:n}),n?(pe.copyFileSync(S.join(p,"template/extras/config/next-config-appdir.js"),S.join(a,"next.config.js")),ae({projectDir:a,packages:o}),le({projectDir:a,packages:o})):(se({projectDir:a,packages:o}),re({projectDir:a,packages:o})),!o.tailwind.inUse){let l=S.join(p,"template/extras/src/index.module.css"),c=S.join(a,"src",n?"app":"pages","index.module.css");pe.copyFileSync(l,c)}return a};import{execSync as F}from"child_process";import W from"path";import*as $ from"@clack/prompts";import j from"chalk";import{execa as C}from"execa";import me from"fs-extra";import Ze from"ora";var et=e=>{try{return F("git --version",{cwd:e}),!0}catch{return!1}},J=e=>me.existsSync(W.join(e,".git")),B=async e=>{try{return await C("git",["rev-parse","--is-inside-work-tree"],{cwd:e,stdout:"ignore"}),!0}catch{return!1}},tt=()=>{let t=F("git --version").toString().trim().split(" ")[2],o=t?.split(".")[0],i=t?.split(".")[1];return{major:Number(o),minor:Number(i)}},it=()=>F("git config --global init.defaultBranch || echo main").toString().trim(),fe=async e=>{if(r.info("Initializing Git..."),!et(e)){r.warn("Git is not installed. Skipping Git initialization.");return}let t=Ze(`Creating a new git repo...
`).start(),o=J(e),i=await B(e),n=W.parse(e).name;if(i&&o){if(t.stop(),!await $.confirm({message:`${j.redBright.bold("Warning:")} Git is already initialized in "${n}". Initializing a new git repository would delete the previous history. Would you like to continue anyways?`,initialValue:!1})){t.info("Skipping Git initialization.");return}me.removeSync(W.join(e,".git"))}else if(i&&!o&&(t.stop(),!await $.confirm({message:`${j.redBright.bold("Warning:")} "${n}" is already in a git worktree. Would you still like to initialize a new git repository in this directory?`,initialValue:!1}))){t.info("Skipping Git initialization.");return}try{let s=it(),{major:a,minor:l}=tt();a<2||a==2&&l<28?(await C("git",["init"],{cwd:e}),await C("git",["symbolic-ref","HEAD",`refs/heads/${s}`],{cwd:e})):await C("git",["init",`--initial-branch=${s}`],{cwd:e}),await C("git",["add","."],{cwd:e}),t.succeed(`${j.green("Successfully initialized and staged")} ${j.green.bold("git")}
`)}catch{t.fail(`${j.bold.red("Failed:")} could not initialize git. Update git to the latest version!
`)}};var ge=async({projectName:e=T,packages:t,noInstall:o,projectDir:i})=>{let n=f();r.info("Next steps:"),e!=="."&&r.info(` cd ${e}`),o&&(n==="yarn"?r.info(` ${n}`):r.info(` ${n} install`)),["npm","bun"].includes(n)?r.info(` ${n} run dev`):r.info(` ${n} dev`),!await B(i)&&!J(i)&&r.info(" git init"),r.info(' git commit -m "initial commit"')};import D from"fs";import nt from"path";function de(e,t,o){D.readdirSync(e).forEach(n=>{let s=nt.join(e,n);if(D.statSync(s).isDirectory())de(s,t,o);else{let l=D.readFileSync(s,"utf8").replace(new RegExp(t,"g"),o);D.writeFileSync(s,l,"utf8")}})}var ue=(e,t)=>{let o=t.replace(/\*/g,"").replace(/[^/]$/,"$&/");de(e,"~/",o)};import L from"path";import st from"fs-extra";import ye from"path";import he from"fs-extra";import ot from"sort-package-json";var we={tailwindcss:"^4.0.15",postcss:"^8.5.3","@tailwindcss/postcss":"^4.0.15","class-variance-authority":"^0.7.1",clsx:"^2.1.1","lucide-react":"^0.515.0","tailwind-merge":"^3.3.1","tw-animate-css":"^1.3.4",prettier:"^3.5.3","@eslint/eslintrc":"^3.3.1","prettier-plugin-tailwindcss":"^0.6.11",eslint:"^9.23.0","eslint-config-next":"^15.2.3","eslint-plugin-drizzle":"^0.2.3","typescript-eslint":"^8.27.0","@biomejs/biome":"^1.9.4","@privy-io/react-auth":"^2.4.14","@rainbow-me/rainbowkit":"^2.2.6","@tanstack/react-query":"^5.69.0",wagmi:"^2.15.6",viem:"^2.31.0"};var g=e=>{let{dependencies:t,devMode:o,projectDir:i}=e,n=he.readJSONSync(ye.join(i,"package.json"));t.forEach(a=>{let l=we[a];o&&n.devDependencies?n.devDependencies[a]=l:n.dependencies&&(n.dependencies[a]=l)});let s=ot(n);he.writeJSONSync(ye.join(i,"package.json"),s,{spaces:2})};var be=({projectDir:e})=>{g({projectDir:e,dependencies:["@privy-io/react-auth"],devMode:!1});let t=L.join(p,"template/extras"),o=L.join(t,"src/provider/privy-provider.tsx"),i=L.join(e,"src/components/provider/privy-provider.tsx");st.copySync(o,i)};import A from"path";import xe from"fs-extra";var ve=({projectDir:e})=>{g({projectDir:e,dependencies:["@rainbow-me/rainbowkit","wagmi","viem","@tanstack/react-query"],devMode:!1});let t=A.join(p,"template/extras"),o=A.join(t,"src/provider/rainbow-provider.tsx"),i=A.join(e,"src/components/provider/rainbow-provider.tsx"),n=A.join(t,"config/wagmi.ts"),s=A.join(e,"src/config/wagmi.ts");xe.copySync(o,i),xe.copySync(n,s)};import b from"path";import z from"fs-extra";var Pe=({projectDir:e})=>{g({projectDir:e,dependencies:["class-variance-authority","clsx","lucide-react","tailwind-merge"],devMode:!1}),g({projectDir:e,dependencies:["tw-animate-css"],devMode:!0});let t=b.join(p,"template/extras"),o=b.join(t,"config/components.json"),i=b.join(e,"components.json"),n=b.join(t,"src/lib/utils.ts"),s=b.join(e,"src/lib/utils.ts"),a=b.join(t,"src/styles/shadcn-globals.css"),l=b.join(e,"src/styles/globals.css");z.copySync(o,i),z.copySync(n,s),z.copySync(a,l)};import E from"path";import ke from"fs-extra";var Ie=({projectDir:e})=>{g({projectDir:e,dependencies:["tailwindcss","postcss","@tailwindcss/postcss"],devMode:!0});let t=E.join(p,"template/extras"),o=E.join(t,"config/postcss.config.js"),i=E.join(e,"postcss.config.js"),n=E.join(t,"src/styles/globals.css"),s=E.join(e,"src/styles/globals.css");ke.copySync(o,i),ke.copySync(n,s)};import K from"path";import lt from"fs-extra";import at from"path";import Se from"fs-extra";import rt from"sort-package-json";var U=e=>{let{scripts:t,projectDir:o}=e,i=at.join(o,"package.json"),n=Se.readJSONSync(i);n.scripts={...n.scripts,...t};let s=rt(n);Se.writeJSONSync(i,s,{spaces:2})};var je=({projectDir:e})=>{g({projectDir:e,dependencies:["@biomejs/biome"],devMode:!0});let t=K.join(p,"template/extras"),o=K.join(t,"config/biome.jsonc"),i=K.join(e,"biome.jsonc");lt.copySync(o,i),U({projectDir:e,scripts:{"biome:unsafe":"biome check --write --unsafe .","biome:write":"biome check --write .",biome:"biome check ."}})};import Ce from"path";import Ae from"fs-extra";var Ee=({projectDir:e,packages:t})=>{let o=t?.privy.inUse,i=t?.rainbow.inUse,n="";o?n="with-privy.js":i&&(n="with-rbow.js");let s=Ce.join(e,".env"),a=Ce.join(e,".env.example"),l=pt(o,i),c=ct();Ae.writeFileSync(s,l,"utf-8"),Ae.writeFileSync(a,c,"utf-8")},pt=(e,t)=>{let o=`
`.trim().concat(`
`);return e&&(o+=`# Privy Configuration
NODE_ENV=""
NEXT_PUBLIC_PRIVY_APP_ID=""
`),t&&(o+=`# Rainbow Kit Configuration
NODE_ENV=""
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=""
`),!e&&!t&&(o+=`# Example:
# NODE_ENV=""
`),o},ct=()=>`
# Since the ".env" file is gitignored, you can use the ".env.example" file to
# build a new ".env" file when you clone the repo. Keep this file up-to-date
# when you add new variables to \`.env\`.
# This file will be committed to version control, so make sure not to have any
# secrets in it. If you are cloning this repo, create a copy of this file named
# ".env" and populate it with your secrets.
NODE_ENV=""
# Privy Configuration (if using Privy)
NEXT_PUBLIC_PRIVY_APP_ID=""
PRIVY_APP_SECRET=""
# Rainbow Kit Configuration (if using Rainbow)
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=""
`.trim().concat(`
`);import w from"path";import Y from"fs-extra";var Oe=({projectDir:e,packages:t})=>{let o=["prettier","eslint","eslint-config-next","typescript-eslint","@eslint/eslintrc"];t?.tailwind.inUse&&o.push("prettier-plugin-tailwindcss"),g({projectDir:e,dependencies:o,devMode:!0});let i=w.join(p,"template/extras"),n;t?.tailwind.inUse?n=w.join(i,"config/_tailwind.prettier.config.js"):n=w.join(i,"config/_prettier.config.js");let s=w.join(e,"prettier.config.js");if(Y.copySync(n,s),f()==="pnpm"){let x=w.join(i,"pnpm/_npmrc");Y.copySync(x,w.join(e,".npmrc"))}U({projectDir:e,scripts:{lint:"next lint","lint:fix":"next lint --fix",check:"next lint && tsc --noEmit","format:write":'prettier --write "**/*.{ts,tsx,js,jsx,mdx}" --cache',"format:check":'prettier --check "**/*.{ts,tsx,js,jsx,mdx}" --cache'}});let l=w.join(i,"config/_eslint.base.js"),c=w.join(e,"eslint.config.js");Y.copySync(l,c)};var _e=e=>({tailwind:{inUse:e.includes("tailwind"),installer:Ie},shadcn:{inUse:e.includes("shadcn"),installer:Pe},privy:{inUse:e.includes("privy"),installer:be},rainbow:{inUse:e.includes("rainbow"),installer:ve},envVariables:{inUse:!0,installer:Ee},eslint:{inUse:e.includes("eslint"),installer:Oe},biome:{inUse:e.includes("biome"),installer:je}});import Te from"path";var Re=e=>{let o=M(e).split("/"),i=o[o.length-1];if(i==="."){let a=Te.resolve(process.cwd());i=Te.basename(a)}let n=o.findIndex(a=>a.startsWith("@"));o.findIndex(a=>a.startsWith("@"))!==-1&&(i=o.slice(n).join("/"));let s=o.filter(a=>!a.startsWith("@")).join("/");return[i,s]};import mt from"gradient-string";var ft={blue:"#add7ff",cyan:"#89ddff",green:"#5de4c7",magenta:"#fae4fc",red:"#d0679d",yellow:"#fffac2"},Me=()=>{let e=mt(Object.values(ft)),t=f();(t==="yarn"||t==="pnpm")&&console.log(""),console.log(e.multiline(q))};import gt from"chalk";import{execa as dt}from"execa";import ut from"ora";var Ne=async({pkgManager:e,projectDir:t,eslint:o})=>{r.info("Formatting project with eslint...");let i=ut(`Running format command
`).start();o&&await dt(e,["run","format:write"],{cwd:t}),i.succeed(`${gt.green("Successfully formatted project")}`)};import wt from"chalk";import{execa as De}from"execa";import Ue from"ora";var H=async(e,t,o)=>{let{onDataHandle:i,args:n=["install"],stdout:s="pipe"}=o,a=Ue(`Running ${t} install...`).start(),l=De(t,n,{cwd:e,stdout:s});return await new Promise((c,x)=>{i&&l.stdout?.on("data",i(a)),l.on("error",O=>x(O)),l.on("close",()=>c())}),a},yt=async(e,t)=>{switch(e){case"npm":return await De(e,["install"],{cwd:t,stderr:"inherit"}),null;case"pnpm":return H(t,e,{onDataHandle:o=>i=>{let n=i.toString();n.includes("Progress")&&(o.text=n.includes("|")?n.split(" | ")[1]??"":n)}});case"yarn":return H(t,e,{onDataHandle:o=>i=>{o.text=i.toString()}});case"bun":return H(t,e,{stdout:"ignore"})}},Ge=async({projectDir:e})=>{r.info("Installing dependencies...");let t=f();(await yt(t,e)??Ue()).succeed(wt.green(`Successfully installed dependencies!
`))};import{execSync as ht}from"child_process";import bt from"https";var Ve=e=>{let t=v();t.includes("beta")?(r.warn(" You are using a beta version of create-w3-app."),r.warn(" Please report any bugs you encounter.")):t.includes("next")?(r.warn(" You are running create-w3-app with the @next tag which is no longer maintained."),r.warn(" Please run the CLI with @latest instead.")):t!==e&&(r.warn(" You are using an outdated version of create-w3-app."),r.warn(" Your version:",t+".","Latest version in the npm registry:",e),r.warn(" Please run the CLI with @latest to get the latest updates.")),console.log("")};function xt(){return new Promise((e,t)=>{bt.get("https://registry.npmjs.org/-/package/create-w3-app/dist-tags",o=>{if(o.statusCode===200){let i="";o.on("data",n=>i+=n),o.on("end",()=>{e(JSON.parse(i).latest)})}else t()}).on("error",()=>{t()})})}var We=()=>xt().catch(()=>{try{return ht("npm view create-w3-app version").toString().trim()}catch{return null}});var Pt=async()=>{let e=await We(),t=f();Me(),e&&Ve(e);let{appName:o,packages:i,flags:{noGit:n,noInstall:s,importAlias:a,appRouter:l}}=await te(),c=_e(i),[x,O]=Re(o),u=await ce({projectName:O,scopedAppName:x,packages:c,importAlias:a,noInstall:s,appRouter:l}),_=Fe.readJSONSync($e.join(u,"package.json"));if(_.name=x,_.cweb3aMetadata={initVersion:v()},t!=="bun"){let{stdout:Je}=await vt(t,["-v"],{cwd:u});_.packageManager=`${t}@${Je.trim()}`}Fe.writeJSONSync($e.join(u,"package.json"),_,{spaces:2}),a!=="~/"&&ue(u,a),s||(await Ge({projectDir:u}),await Ne({pkgManager:t,projectDir:u,eslint:i.includes("eslint")})),n||await fe(u),await ge({projectName:O,packages:c,appRouter:l,noInstall:s,projectDir:u}),process.exit(0)};Pt().catch(e=>{r.error("Aborting installation..."),e instanceof Error?r.error(e):(r.error("An unknown error has occurred. Please open an issue on github with the below:"),console.log(e)),process.exit(1)});