UNPKG

@selemondev/create-react-next

Version:

The Next Generation React Scaffolding Tool ✨

24 lines (16 loc) 15.5 kB
#!/usr/bin/env node var me=Object.defineProperty;var ue=(t,s)=>{for(var r in s)me(t,r,{get:s[r],enumerable:!0})};import{Command as fe}from"commander";var h={name:"@selemondev/create-react-next",version:"1.0.3",description:"The Next Generation React Scaffolding Tool \u2728",type:"module",main:"./dist/index.cjs",module:"./dist/index.js",types:"./dist/index.d.ts",scripts:{dev:"esno src/index.ts","build:package":"tsup-node src/index.ts --format cjs,esm --clean --dts --minify --shims","generate:release":"npx changelogen@latest --release","package:beta":"npm run build && npm publish --tag beta",package:"pnpm build:package && npm publish --access=public"},exports:{".":{types:"./dist/index.d.ts",require:"./dist/index.cjs",import:"./dist/index.js"}},bin:{"@selemondev/create-react-next":"./dist/index.js"},files:["dist","src","template"],keywords:["@selemondev/create-react-next","React 18 CLI","React CLI","Vite CLI","Vite","React-ts","React-js","TypeScript"],author:"Selemondev",license:"MIT",devDependencies:{"@types/ejs":"^3.1.5","@types/fs-extra":"^11.0.4","@types/node":"^20.11.30","@types/prompts":"^2.4.9","@types/validate-npm-package-name":"^4.0.2",conf:"^12.0.0",esno:"^4.0.0",tsup:"^8.0.2",typescript:"^5.3.3"},dependencies:{chalk:"^5.3.0",commander:"^12.0.0",ejs:"^3.1.9","fs-extra":"^11.2.0",ora:"^8.0.1",prettier:"^3.5.3",prompts:"^2.4.2","validate-npm-package-name":"^5.0.0"},pnpm:{overrides:{},onlyBuiltDependencies:["esbuild"]}};var ge=new fe(h.name),d=ge;import{execSync as ve}from"child_process";import k from"chalk";var a={info:(...t)=>{console.log(k.cyan(...t))},error:(...t)=>{console.log(k.red(...t))},warning:(...t)=>{console.log(k.yellow(...t))},success:(...t)=>{console.log(k.green(...t))}};var E=()=>{try{let t=process.env.npm_config_user_agent;return t&&t.startsWith("yarn")||ve("yarnpkg --version",{stdio:"ignore"}),!0}catch(t){return t instanceof Error&&a.error(t.message),!1}};import{execSync as ye}from"child_process";var D=()=>{try{let t=process.env.config_user_agent;return t&&t.startsWith("pnpm")||ye("pnpm --version",{stdio:"ignore"}),!0}catch(t){return t instanceof Error&&a.error(t.message),!1}};import{execSync as we}from"child_process";var L=()=>{try{let t=process.env.config_user_agent;return t&&t.startsWith("bun")||we("bun --version",{stdio:"ignore"}),!0}catch(t){return t instanceof Error&&a.error(t.message),!1}};var M=E(),F=D(),A=L(),J={name:"package",type:"select",message:"Which package manager do you prefer to use?",choices:[{title:"I prefer manual installation",value:"none"},{title:A?"Bun":"Bun is not installed",value:"bun",disabled:!A},{title:F?"Pnpm":"Pnpm is not installed",value:"pnpm",disabled:!F},{title:M?"Yarn":"Yarn is not installed",value:"yarn",disabled:!M},{title:"Npm",value:"npm"}]};var xe={},e=xe;import Q from"fs-extra";import{resolve as be}from"path";function Y(t){let s=be(process.cwd(),t);if(!Q.existsSync(s))return!0;let r=Q.readdirSync(s);return r.length===0||r.length===1&&r[0]===".git"}import he from"validate-npm-package-name";function z(t){let s=he(t);return s.validForNewPackages?{valid:!0}:{valid:!1,problems:[...s.errors||[],...s.warnings||[]]}}var ke="create-react-next",Te=[{name:"name",type:"text",message:"What should we call your project?",initial:ke,validate:t=>{let s=z(t);return s.valid?(e.name=t,!0):"Invalid project name: "+s.problems[0]},active:"Yes",inactive:"No"},{name:"overwrite",type:()=>e.name&&Y(e.name)?null:"confirm",message:()=>`Directory "${e.name}" is not empty. Do you want to overwrite it?`},{name:"overwrite",type:(t,s)=>{if(s.overwrite===!1)throw new Error("Operation cancelled");return null}}],_=Te;var O={name:"deploy",type:"select",message:"Where should we deploy your project?",choices:[{title:"I prefer manual deployment",value:"none"},{title:"Vercel",value:"vercel"},{title:"Netlify",value:"netlify"}]};var Se=[{name:"useRouter",type:()=>"toggle",message:"Add React Router DOM for Single Page Application development?",initial:!0,active:"Yes",inactive:"No"},{name:"useHooks",type:()=>"toggle",message:"Add useHooks for a collection of modern, server-safe React hooks?",initial:!1,active:"Yes",inactive:"No"},{name:"useVitest",type:()=>"toggle",message:"Add Vitest for unit testing?",initial:!0,active:"Yes",inactive:"No"}],U=Se;var $={};ue($,{constantDevDeps:()=>Fe,constantProDeps:()=>Ae,eslintJs:()=>Pe,eslintTs:()=>Re,javascript:()=>x,jotai:()=>Ie,netlifyCLI:()=>Me,reactHooks:()=>Ce,redux:()=>$e,router:()=>je,tailwind:()=>Ne,tanStackReactQuery:()=>Ee,typescript:()=>w,vercelCLI:()=>Le,vitest:()=>De,zustand:()=>Ve});var je={name:"react-router-dom",version:"^6.22.3",stableVersion:"^6.22.3",env:"pro"},$e={name:["react-redux","@reduxjs/toolkit"],version:["^9.1.0","^2.2.1"],stableVersion:["^9.1.0","^2.2.1"],env:"pro"},Ve={name:"zustand",version:"^4.5.2",stableVersion:"^4.5.2",env:"pro"},Ie={name:["jotai","jotai-immer"],version:["^2.7.1","^0.3.0"],stableVersion:["^2.7.1","^0.3.0"],env:"pro"},Pe={name:["eslint","eslint-plugin-react","eslint-plugin-react-hooks","eslint-plugin-react-refresh"],version:["^8.57.0","^7.34.0","^4.6.0","^0.4.5"],stableVersion:["^8.57.0","^7.34.0","^4.6.0","^0.4.5"],env:["dev","dev","dev","dev"]},Re={name:["eslint","eslint-plugin-react-hooks","eslint-plugin-react-refresh","@typescript-eslint/eslint-plugin","@typescript-eslint/parser"],version:["^8.57.0","^4.6.0","^0.4.5","^7.1.1","^7.1.1"],stableVersion:["^8.57.0","^4.6.0","^0.4.5","^7.1.1","^7.1.1"],env:["dev","dev","dev","dev","dev"]},Ne={name:["tailwindcss","postcss","autoprefixer"],version:["^3.4.1","^8.4.35","^10.4.18"],stableVersion:["^3.4.1","^8.4.35","^10.4.18"],env:["dev","dev","dev"]},Ce={name:"@uidotdev/usehooks",version:"^2.4.1",stableVersion:"^2.4.1",env:"pro"},w={name:["typescript","@types/react","@types/react-dom","@types/node"],version:["^5.2.2","^18.2.64","^18.2.21","^20.11.28"],stableVersion:["^5.2.2","^18.2.64","^18.2.21","^20.11.28"],dev:["dev","dev","dev","dev"]},x={name:[],version:[],stableVersion:[],dev:[]},Ee={name:["@tanstack/react-query","@tanstack/react-query-devtools"],version:["^5.28.0","^5.28.0"],stableVersion:["^5.28.0","^5.28.0"],dev:["pro","pro"]},De={name:["vitest","jsdom","@testing-library/react","@testing-library/jest-dom"],version:["^1.2.2","^24.0.0","^14.2.1","^6.4.2"],stableVersion:["^1.2.2","^24.0.0","^14.2.1","^6.4.2"],dev:["dev","dev","dev","dev"]},Le={name:["vercel"],version:["^34.1.7"],stableVersion:["^34.1.7"],dev:["dev"]},Me={name:["netlify-cli"],version:["^17.30.0"],stableVersion:["^17.30.0"],dev:["dev"]},Fe={name:e.useTypeScript?w.name:x.name,version:e.useTypeScript?w.version:x.version,stableVersion:e.useTypeScript?w.stableVersion:x.stableVersion,dev:e.useTypeScript?w.dev:x.dev},Ae={name:["react","react-dom"],version:["^18.2.0","^18.2.0"],stableVersion:["^18.2.0","^18.2.0"],dev:"pro"};var c=new Map,b=$;Object.keys(b).forEach(t=>{let s=b[t].name;if(Array.isArray(s)){let r="";s.forEach((l,p)=>{r+=`"${l}":"${b[t].version[p]}",`}),c.set(t,r)}else c.set(t,`"${b[t].name}":"${b[t].version}",`)});var B=new Map([["EslintScript",'"lint": "eslint . --ext ts,tsx,js,jsx --report-unused-disable-directives --max-warnings 0",'],["VitestScript",'"test:unit": "vitest",']]);import Je from"prompts";async function m(t){let s=await Je(t,{onCancel:()=>{throw new Error("\u274C Operation cancelled")}});return Object.assign(e,s),Promise.resolve(e)}async function Qe(){let t=c.get("eslintJs"),s=c.get("eslintTs"),r=c.get("vitest"),l=c.get("tanStackReactQuery"),p=c.get("router"),f=c.get("redux"),g=c.get("jotai"),v=c.get("zustand"),u=c.get("tailwind"),S=c.get("typescript"),j=c.get("javascript"),le=c.get("reactHooks");return W(e,c),W(e,B),e.constantDevDeps=c.get("constantDevDeps"),e.constantProDeps=c.get("constantProDeps"),e.Eslint=e.useTypeScript?s:t,e.Vitest=r,e.Router=p,e.Jotai=g,e.Zustand=v,e.TanStackReactQuery=l,e.Redux=f,e.UseHooks=le,e.Tailwind=u,e.TypeScript=S,e.JavaScript=j,e.useEslintTs=e.useTypeScript,e.useJavaScript=e.useTypeScript===!1,Promise.resolve(!0)}async function G(){await m(U),await Qe()}function W(t,s){Array.from(s.keys()).forEach(r=>{t[r]=s.get(r)})}var Ye=[{name:"useGitInit",type:()=>"toggle",message:"Initialize a new git repository?",initial:!0,active:"Yes",inactive:"No"}],H=Ye;var ze=[{name:"useTailwind",type:()=>"toggle",message:"Add TailwindCSS for styling?",initial:!0,active:"Yes",inactive:"No"}],q=ze;var _e=[{name:"useTypeScript",type:()=>"toggle",message:"Add TypeScript for type safety?",initial:!0,active:"Yes",inactive:"No"}],Z=_e;var Oe=[{name:"useEslint",type:()=>"toggle",message:"Add ESLint for code quality?",initial:!0,active:"Yes",inactive:"No"}],K=Oe;var X={name:"stateManagement",type:"select",message:"Which state management solution do you prefer?",choices:[{title:"None",value:"none"},{title:"Redux",value:"redux"},{title:"Zustand",value:"zustand"},{title:"Jotai",value:"jotai"}]};var Ue=[{name:"useTanStackReactQuery",type:()=>"toggle",message:"Add TanStack React Query for server state management?",initial:!1,active:"Yes",inactive:"No"}],ee=Ue;async function Be(){try{e.name=d.args[0]??(await m(_)).name,e.useTypeScript||await m(Z),e.useTailwind||await m(q),await m(X),await G(),await m(ee),e.useEslint||await m(K),e.package||await m(J);let t=c.get("vercelCLI"),s=c.get("netlifyCLI"),r=await m(O);e.VercelCLI=r?.deploy==="vercel"&&t,e.NetlifyCLI=r?.deploy==="netlify"&&s,e.useVercelCLI=!!e.VercelCLI,e.useNetlifyCLI=!!e.NetlifyCLI,await m(H)}catch(t){t instanceof Error&&(a.error(t.message),process.exit(1))}return Promise.resolve()}var te=Be;async function We(){console.clear(),a.info("Welcome To Create React Next. The Next Generation React Scaffolding Tool \u2728"),console.log()}var se=We;import{spawn as Ge}from"child_process";var re=(t,s="inherit")=>function(r,l){let p=Ge(r,l,{cwd:t,stdio:s,shell:!0});return new Promise((f,g)=>{p.on("close",v=>{v===0?f(!0):g(!1)})}).catch(f=>f)};import He from"ora";import qe from"chalk";async function Ze(){let t=re(e.dest,"ignore"),s=He("Copying template...").start(),r=new Date().getTime();e.useGitInit&&(await t("git",["init"]),await t("git",["add ."]),await t("git",['commit -m "Initialized by create-react-next"'])),e.package&&e.package!=="none"&&(s.text=qe.cyan(`Installing dependencies with ${e.package}. Please wait...`),await t(e.package,["install"])),s.stop();let p=(new Date().getTime()-r)/1e3;console.log(),a.info(`\u{1F680} Completed in ${p}s`),console.log(),a.success("\u2705 Project created successfully"),console.log(),a.info(`cd ${e.name}`),console.log(),e.package!=="none"?(a.info(e.package==="npm"?`${e.package} run dev to start the dev server`:`${e.package} dev to start the dev server`),e.useEslint&&console.log(),e.useEslint&&a.info(`${e.package} run lint to format your code`),e.useVitest&&console.log(),e.useVitest&&a.info(`${e.package} run test:unit to run tests`)):(a.info("npm install - To install dependencies"),console.log(),e.useEslint&&a.info("npm run lint to format your code"),e.useEslint&&console.log(),a.info("npm run dev to start the dev server"),e.useVitest&&console.log(),e.useVitest&&a.info("npm run test:unit to run tests"))}var oe=Ze;import ce from"fs-extra";import y from"node:path";import Ke from"ejs";import V from"fs-extra";import{resolve as I,extname as ne,parse as Xe}from"path";import{format as T}from"prettier/standalone";import P from"prettier/parser-babel";import R from"prettier/plugins/estree";async function ie(t,s){try{let r="",l=Xe(t),p=I(process.cwd(),s),f=I(p,l.dir,`${l.name}.ejs`),g=I(p,t),v=await V.readFile(f),u=Ke.render(v.toString(),e),S=ne(t).replace(/[.]/g,"");try{switch(S){case"ts":case"tsx":case"jsx":case"js":r=await T(u,{parser:"babel",plugins:[P,R]});break;case"json":r=await T(u,{parser:"json",plugins:[P,R]});break;case"cjs":r=await T(u,{parser:"babel",plugins:[P,R]});break;case"toml":r=u;break;case"":r=u;break;default:r=await T(u,{parser:ne});break}}catch(j){console.log(j)}await V.outputFile(g,r),await V.remove(f)}catch(r){console.log(r)}}import tt from"chalk";var N=new Map;N.set("react",et);function et(){return["package.json",e.useTypeScript?"src/main.tsx":"src/main.jsx",e.useTypeScript?"src/App.tsx":"src/App.jsx",e.useTypeScript?"src/components/TheWelcome.tsx":"src/components/TheWelcome.jsx"].filter(Boolean)}import i from"fs-extra";function ae(){async function t(){return e.useRouter||i.remove(`${e.dest}/src/pages`),e.useTailwind||(i.remove(`${e.dest}/tailwind.config.js`),i.remove(`${e.dest}/postcss.config.js`),i.remove(`${e.dest}/src/assets/css/tailwind.css`)),e.useTailwind&&i.remove(`${e.dest}/src/assets/css/base.css`),e.deploy==="none"&&(i.remove(`${e.dest}/netlify.toml`),i.remove(`${e.dest}/vercel.json`)),e.deploy==="netlify"&&i.remove(`${e.dest}/vercel.json`),e.deploy==="vercel"&&i.remove(`${e.dest}/netlify.toml`),e.useTailwind===!1&&i.remove(`${e.dest}/src/assets/css/tailwind.css`),e.useJavaScript&&i.remove(`${e.dest}/src/main.tsx`),e.useVitest||(i.remove(`${e.dest}/vitest.config.ts`),i.remove(`${e.dest}/vitest.config.js`),i.remove(`${e.dest}/tests`)),e.stateManagement==="none"&&(i.remove(`${e.dest}/src/store`),i.remove(`${e.dest}/src/app`),i.remove(`${e.dest}/src/features`)),e.stateManagement==="jotai"&&(i.remove(`${e.dest}/src/app`),i.remove(`${e.dest}/src/store`),i.remove(`${e.dest}/src/features`)),e.stateManagement==="zustand"&&(i.remove(`${e.dest}/src/app`),i.remove(`${e.dest}/src/store/appStore.ts`),i.remove(`${e.dest}/src/store/appStore.js`),i.remove(`${e.dest}/src/features`)),e.stateManagement==="redux"&&(i.remove(`${e.dest}/src/store/store.ts`),i.remove(`${e.dest}/src/store/store.js`)),e.useEslint||i.remove(`${e.dest}/.eslintrc.cjs`),!0}return new Map([["react",t]]).get("react")}import{fileURLToPath as st}from"node:url";import{dirname as rt}from"node:path";import ot from"ora";async function nt(){let t=st(import.meta.url),s=rt(t),r=ot("Copying template...").start(),l=e.useTypeScript?"react-ts":"react-js";e.src=y.resolve(s,`../template/${l}`);let p=e.name&&y.resolve(process.cwd(),e.name);e.dest=p;let f=y.resolve(s,`../../../../template/${l}`);e.templatePath=f;let g=ae();async function v(){let u=y.resolve(s,"../");p&&await ce.copy(`${u}/template/${l}`,p)}await v(),g&&await g(),e.dest&&await ce.move(y.resolve(e.dest,".gitignore.ejs"),y.resolve(e.dest,".gitignore"),{overwrite:!0}),await Promise.all(N.get("react")().map(u=>e.name&&ie(u,e.name))),r.text=tt.green("Template successfully copied!"),r.succeed()}var pe=nt;async function it(){await se(),await te(),await pe(),await oe()}async function C(){await it()}async function at(){d.version(h.version).description("Create React Next. The Next Generation React Scaffolding Tool \u26A1").action(t=>{e.name=t}).option("--ts, --typescript",` Initialize as a TypeScript project. `).option("--tailwind",` Initialize with Tailwind CSS. `).option("--eslint",` Initialize with eslint config. `).option("--use-npm",` Explicitly tell the CLI to bootstrap the application using npm `).option("--use-pnpm",` Explicitly tell the CLI to bootstrap the application using pnpm `).option("--use-yarn",` Explicitly tell the CLI to bootstrap the application using Yarn `).option("--use-bun",` Explicitly tell the CLI to bootstrap the application using Bun `).allowUnknownOption().parse(process.argv),e.useTypeScript=d.opts().typescript,e.useTailwind=d.opts().tailwind,e.useEslint=d.opts().eslint,e.package=d.opts().useNpm?"npm":d.opts().usePnpm?"pnpm":d.opts().useYarn?"yarn":d.opts().useBun?"bun":e.package,await C()}at();