UNPKG

create-t3-app-deepmeta

Version:
57 lines (54 loc) 20.1 kB
#!/usr/bin/env node import R from"path";import W from"fs-extra";import j from"path";import D from"fs-extra";import F from"path";import{fileURLToPath as Ne}from"url";var Ee=Ne(import.meta.url),Re=F.dirname(Ee),m=F.join(Re,"../"),V=` ___ ___ ___ __ _____ ___ _____ ____ __ ___ ___ / __| _ \\ __| / \\_ _| __| |_ _|__ / / \\ | _ \\ _ \\ | (__| / _| / /\\ \\| | | _| | | |_ \\ / /\\ \\| _/ _/ \\___|_|_\\___|_/\u203E\u203E\\_\\_| |___| |_| |___/ /_/\u203E\u203E\\_\\_| |_| `,C="my-t3-app",M="create-t3-app";var B=({projectDir:e,packages:t})=>{let i=t?.nextAuth.inUse,o=t?.prisma.inUse,n=Me(!!i,!!o),s=i&&o?"with-auth-prisma.mjs":i?"with-auth.mjs":o?"with-prisma.mjs":"";if(s!==""){let p=j.join(m,"template/extras/src/env",s),c=j.join(e,"src/env.mjs");D.copySync(p,c)}let r=j.join(e,".env"),l=j.join(e,".env.example");D.writeFileSync(r,n,"utf-8"),D.writeFileSync(l,De+n,"utf-8")},Me=(e,t)=>{let i=` # When adding additional environment variables, the schema in "/src/env.mjs" # should be updated accordingly. `.trim().concat(` `);return t&&(i+=` # Prisma # https://www.prisma.io/docs/reference/database-reference/connection-urls#env DATABASE_URL="file:./db.sqlite" `),e&&(i+=` # Next Auth # You can generate a new secret on the command line with: # openssl rand -base64 32 # https://next-auth.js.org/configuration/options#secret # NEXTAUTH_SECRET="" NEXTAUTH_URL="http://localhost:3000" # Next Auth Discord Provider DISCORD_CLIENT_ID="" DISCORD_CLIENT_SECRET="" `),!e&&!t&&(i+=` # Example: # SERVERVAR="foo" # NEXT_PUBLIC_CLIENTVAR="bar" `),i},De=` # 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. `.trim().concat(` `);import k from"path";import K from"fs-extra";import Y from"path";import H from"fs-extra";var z={"next-auth":"^4.19.0","@next-auth/prisma-adapter":"^1.0.5",prisma:"^4.9.0","@prisma/client":"^4.9.0",tailwindcss:"^3.2.0",autoprefixer:"^10.4.7",postcss:"^8.4.14",prettier:"^2.8.1","prettier-plugin-tailwindcss":"^0.2.1","@types/prettier":"^2.7.2","@trpc/client":"^10.9.0","@trpc/server":"^10.9.0","@trpc/react-query":"^10.9.0","@trpc/next":"^10.9.0","@tanstack/react-query":"^4.20.2",superjson:"1.9.1"};import Ge from"sort-package-json";var u=e=>{let{dependencies:t,devMode:i,projectDir:o}=e,n=H.readJSONSync(Y.join(o,"package.json"));t.forEach(r=>{let l=z[r];i&&n.devDependencies?n.devDependencies[r]=l:n.dependencies&&(n.dependencies[r]=l)});let s=Ge(n);H.writeJSONSync(Y.join(o,"package.json"),s,{spaces:2})};var q=({projectDir:e,packages:t})=>{let i=t?.prisma.inUse,o=["next-auth"];i&&o.push("@next-auth/prisma-adapter"),u({projectDir:e,dependencies:o,devMode:!1});let n=k.join(m,"template/extras"),s="src/pages/api/auth/[...nextauth].ts",r=k.join(n,s),l=k.join(e,s),p=k.join(n,"src/server/auth",i?"with-prisma.ts":"base.ts"),c=k.join(e,"src/server/auth.ts");K.copySync(r,l),K.copySync(p,c)};import x from"path";import T from"fs-extra";var X=({projectDir:e,packages:t})=>{u({projectDir:e,dependencies:["prisma"],devMode:!0}),u({projectDir:e,dependencies:["@prisma/client"],devMode:!1});let i=x.join(m,"template/extras"),o=x.join(i,"prisma/schema",t?.nextAuth.inUse?"with-auth.prisma":"base.prisma"),n=x.join(e,"prisma/schema.prisma"),s=x.join(i,"src/server/db.ts"),r=x.join(e,"src/server/db.ts"),l=x.join(e,"package.json"),p=T.readJSONSync(l);p.scripts={...p.scripts,postinstall:"prisma generate"},T.copySync(o,n),T.copySync(s,r),T.writeJSONSync(l,p,{spaces:2})};import g from"path";import _ from"fs-extra";var Q=({projectDir:e})=>{u({projectDir:e,dependencies:["tailwindcss","postcss","autoprefixer","prettier","prettier-plugin-tailwindcss","@types/prettier"],devMode:!0});let t=g.join(m,"template/extras"),i=g.join(t,"config/tailwind.config.cjs"),o=g.join(e,"tailwind.config.cjs"),n=g.join(t,"config/postcss.config.cjs"),s=g.join(e,"postcss.config.cjs"),r=g.join(t,"config/prettier.config.cjs"),l=g.join(e,"prettier.config.cjs"),p=g.join(t,"src/styles/globals.css"),c=g.join(e,"src/styles/globals.css");_.copySync(i,o),_.copySync(n,s),_.copySync(p,c),_.copySync(r,l);let h=g.join(e,"src/pages/index.module.css");_.unlinkSync(h)};import P from"fs-extra";import f from"path";var Z=({projectDir:e,packages:t})=>{u({projectDir:e,dependencies:["@tanstack/react-query","superjson","@trpc/server","@trpc/client","@trpc/next","@trpc/react-query"],devMode:!1});let i=t?.nextAuth.inUse,o=t?.prisma.inUse,n=f.join(m,"template/extras"),s=f.join(n,"src/pages/api/trpc/[trpc].ts"),r=f.join(e,"src/pages/api/trpc/[trpc].ts"),l=f.join(n,"src/utils/api.ts"),p=f.join(e,"src/utils/api.ts"),c=i&&o?"with-auth-prisma.ts":i?"with-auth.ts":o?"with-prisma.ts":"base.ts",h=f.join(n,"src/server/api/trpc",c),Ie=f.join(e,"src/server/api/trpc.ts"),Ae=f.join(n,"src/server/api/root.ts"),Ce=f.join(e,"src/server/api/root.ts"),je=i&&o?"with-auth-prisma.ts":i?"with-auth.ts":o?"with-prisma.ts":"base.ts",Te=f.join(n,"src/server/api/routers/example",je),Oe=f.join(e,"src/server/api/routers/example.ts");P.copySync(s,r),P.copySync(l,p),P.copySync(h,Ie),P.copySync(Ae,Ce),P.copySync(Te,Oe)};var ee=["nextAuth","prisma","tailwind","trpc","envVariables"],te=e=>({nextAuth:{inUse:e.includes("nextAuth"),installer:q},prisma:{inUse:e.includes("prisma"),installer:X},tailwind:{inUse:e.includes("tailwind"),installer:Q},trpc:{inUse:e.includes("trpc"),installer:Z},envVariables:{inUse:!0,installer:B}});import oe from"chalk";import{Command as Le}from"commander";import y from"inquirer";import Ue from"path";import $e from"fs-extra";var v=()=>{let e=Ue.join(m,"package.json");return $e.readJSONSync(e).version??"1.0.0"};var d=()=>{let e=process.env.npm_config_user_agent;return e?e.startsWith("yarn")?"yarn":e.startsWith("pnpm")?"pnpm":"npm":"npm"};import O from"chalk";var a={error(...e){console.log(O.red(...e))},warn(...e){console.log(O.yellow(...e))},info(...e){console.log(O.cyan(...e))},success(...e){console.log(O.green(...e))}};var Je=/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,ne=e=>{let t=e.split("/"),i=t.findIndex(n=>n.startsWith("@")),o=t[t.length-1];return t.findIndex(n=>n.startsWith("@"))!==-1&&(o=t.slice(i).join("/")),e==="."||Je.test(o??"")?!0:"App name must consist of only lowercase alphanumeric characters, '-', and '_'"};var ie=e=>e.startsWith(".")||e.startsWith("/")?"Import alias can't start with '.' or '/'":!0;var N={appName:C,packages:["nextAuth","prisma","tailwind","trpc"],flags:{noGit:!1,noInstall:!1,default:!1,CI:!1,tailwind:!1,trpc:!1,prisma:!1,nextAuth:!1,importAlias:"~/"}},se=async()=>{let e=N,t=new Le().name(M);t.description("A CLI for creating web applications with the t3 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 t3-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`.",n=>!!n&&n!=="false").option("--nextAuth [boolean]","Experimental: Boolean value if we should install NextAuth.js. Must be used in conjunction with `--CI`.",n=>!!n&&n!=="false").option("--prisma [boolean]","Experimental: Boolean value if we should install Prisma. Must be used in conjunction with `--CI`.",n=>!!n&&n!=="false").option("--trpc [boolean]","Experimental: Boolean value if we should install tRPC. Must be used in conjunction with `--CI`.",n=>!!n&&n!=="false").option("-i, --import-alias","Explicitly tell the CLI to use a custom import alias",N.flags.importAlias).version(v(),"-v, --version","Display the version number").addHelpText("afterAll",` The t3 stack was inspired by ${oe.hex("#E8DCFF").bold("@t3dotgg")} and has been used to build awesome fullstack applications like ${oe.hex("#E24A8D").underline("https://ping.gg")} `).parse(process.argv),process.env.npm_config_user_agent?.startsWith("yarn/3")&&a.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-t3-app with another package manager such as pnpm, npm, or Yarn Classic. See: https://github.com/t3-oss/create-t3-app/issues/57`);let i=t.args[0];i&&(e.appName=i),e.flags=t.opts();let o=!1;e.flags.CI&&(o=!0,e.packages=[],e.flags.trpc&&e.packages.push("trpc"),e.flags.tailwind&&e.packages.push("tailwind"),e.flags.prisma&&e.packages.push("prisma"),e.flags.nextAuth&&e.packages.push("nextAuth"));try{if(process.env.SHELL?.toLowerCase().includes("git")&&process.env.SHELL?.includes("bash")){a.warn(` WARNING: It looks like you are using Git Bash which is non-interactive. Please run create-t3-app with another terminal such as Windows Terminal or PowerShell if you want to use the interactive CLI.`);let n=new Error("Non-interactive environment");throw n.isTTYError=!0,n}!e.flags.default&&!o&&(i||(e.appName=await We()),await Fe(),e.packages=await Ve(),e.flags.noGit||(e.flags.noGit=!await Be()),e.flags.noInstall||(e.flags.noInstall=!await ze()),e.flags.importAlias=await Ye())}catch(n){if(n instanceof Error&&n.isTTYError){a.warn(` ${M} needs an interactive terminal to provide options`);let{shouldContinue:s}=await y.prompt({name:"shouldContinue",type:"confirm",message:"Continue scaffolding a default T3 app?",default:!0});s||(a.info("Exiting..."),process.exit(0)),a.info(`Bootstrapping a default T3 app in ./${e.appName}`)}else throw n}return e},We=async()=>{let{appName:e}=await y.prompt({name:"appName",type:"input",message:"What will your project be called?",default:N.appName,validate:ne,transformer:t=>t.trim()});return e},Fe=async()=>{let{language:e}=await y.prompt({name:"language",type:"list",message:"Will you be using TypeScript or JavaScript?",choices:[{name:"TypeScript",value:"typescript",short:"TypeScript"},{name:"JavaScript",value:"javascript",short:"JavaScript"}],default:"typescript"});e==="javascript"?a.error("Wrong answer, using TypeScript instead..."):a.success("Good choice! Using TypeScript!")},Ve=async()=>{let{packages:e}=await y.prompt({name:"packages",type:"checkbox",message:"Which packages would you like to enable?",choices:ee.filter(t=>t!=="envVariables").map(t=>({name:t,checked:!1}))});return e},Be=async()=>{let{git:e}=await y.prompt({name:"git",type:"confirm",message:"Initialize a new git repository?",default:!0});return e?a.success("Nice one! Initializing repository!"):a.info("Sounds good! You can come back and run git init later."),e},ze=async()=>{let e=d(),{install:t}=await y.prompt({name:"install",type:"confirm",message:`Would you like us to run '${e}`+(e==="yarn"?"'?":" install'?"),default:!0});return t?a.success("Alright. We'll install the dependencies for you!"):e==="yarn"?a.info(`No worries. You can run '${e}' later to install the dependencies.`):a.info(`No worries. You can run '${e} install' later to install the dependencies.`),t},Ye=async()=>{let{importAlias:e}=await y.prompt({name:"importAlias",type:"input",message:"What import alias would you like configured?",default:N.flags.importAlias,validate:ie,transformer:t=>t.trim()});return e};import qe from"path";import ae from"chalk";import He from"ora";var re=e=>{let{packages:t}=e;a.info("Adding boilerplate...");for(let[i,o]of Object.entries(t))if(o.inUse){let n=He(`Boilerplating ${i}...`).start();o.installer(e),n.succeed(ae.green(`Successfully setup boilerplate for ${ae.green.bold(i)}`))}a.info("")};import G from"path";import w from"chalk";import S from"fs-extra";import le from"inquirer";import Ke from"ora";var pe=async({projectName:e,projectDir:t,pkgManager:i,noInstall:o})=>{let n=G.join(m,"template/base");o?a.info(""):a.info(` Using: ${w.cyan.bold(i)} `);let s=Ke(`Scaffolding in: ${t}... `).start();if(S.existsSync(t))if(S.readdirSync(t).length===0)e!=="."&&s.info(`${w.cyan.bold(e)} exists but is empty, continuing... `);else{s.stopAndPersist();let{overwriteDir:l}=await le.prompt({name:"overwriteDir",type:"list",message:`${w.redBright.bold("Warning:")} ${w.cyan.bold(e)} already exists and isn't empty. How would you like to proceed?`,choices:[{name:"Abort installation (recommended)",value:"abort",short:"Abort"},{name:"Clear the directory and continue installation",value:"clear",short:"Clear"},{name:"Continue installation and overwrite conflicting files",value:"overwrite",short:"Overwrite"}],default:"abort"});l==="abort"&&(s.fail("Aborting installation..."),process.exit(1));let p=l==="clear"?"clear the directory":"overwrite conflicting files",{confirmOverwriteDir:c}=await le.prompt({name:"confirmOverwriteDir",type:"confirm",message:`Are you sure you want to ${p}?`,default:!1});c||(s.fail("Aborting installation..."),process.exit(1)),l==="clear"&&(s.info(`Emptying ${w.cyan.bold(e)} and creating t3 app.. `),S.emptyDirSync(t))}s.start(),S.copySync(n,t),S.renameSync(G.join(t,"_gitignore"),G.join(t,".gitignore"));let r=e==="."?"App":w.cyan.bold(e);s.succeed(`${r} ${w.green("scaffolded successfully!")} `)};import b from"path";import ce from"fs-extra";var me=({projectDir:e,packages:t})=>{let i=b.join(m,"template/extras/src/pages/_app"),o=t.trpc.inUse,n=t.nextAuth.inUse,s="";if(n&&o?s="with-auth-trpc.tsx":n&&!o?s="with-auth.tsx":!n&&o&&(s="with-trpc.tsx"),s!==""){let r=b.join(i,s),l=b.join(e,"src/pages/_app.tsx");ce.copySync(r,l)}},fe=({projectDir:e,packages:t})=>{let i=b.join(m,"template/extras/src/pages/index"),o=t.trpc.inUse,n=t.tailwind.inUse,s=t.nextAuth.inUse,r="";if(o&&n&&s?r="with-auth-trpc-tw.tsx":o&&!n&&s?r="with-auth-trpc.tsx":o&&n?r="with-trpc-tw.tsx":o&&!n?r="with-trpc.tsx":!o&&n&&(r="with-tw.tsx"),r!==""){let l=b.join(i,r),p=b.join(e,"src/pages/index.tsx");ce.copySync(l,p)}};var ge=async({projectName:e,packages:t,noInstall:i})=>{let o=d(),n=qe.resolve(process.cwd(),e);return await pe({projectName:e,projectDir:n,pkgManager:o,noInstall:i}),re({projectDir:n,pkgManager:o,packages:t,noInstall:i}),me({projectDir:n,packages:t}),fe({projectDir:n,packages:t}),n};import I from"chalk";import{execSync as $}from"child_process";import{execa as A}from"execa";import ue from"fs-extra";import de from"inquirer";import Xe from"ora";import U from"path";var Qe=e=>{try{return $("git --version",{cwd:e}),!0}catch{return!1}},Ze=e=>ue.existsSync(U.join(e,".git")),et=async e=>{try{return await A("git",["rev-parse","--is-inside-work-tree"],{cwd:e,stdout:"ignore"}),!0}catch{return!1}},tt=()=>{let t=$("git --version").toString().trim().split(" ")[2],i=t?.split(".")[0],o=t?.split(".")[1];return{major:Number(i),minor:Number(o)}},nt=()=>$("git config --global init.defaultBranch || echo main").toString().trim(),he=async e=>{if(a.info("Initializing Git..."),!Qe(e)){a.warn("Git is not installed. Skipping Git initialization.");return}let t=Xe(`Creating a new git repo... `).start(),i=Ze(e),o=await et(e),n=U.parse(e).name;if(o&&i){t.stop();let{overwriteGit:s}=await de.prompt({name:"overwriteGit",type:"confirm",message:`${I.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?`,default:!1});if(!s){t.info("Skipping Git initialization.");return}ue.removeSync(U.join(e,".git"))}else if(o&&!i){t.stop();let{initializeChildGitRepo:s}=await de.prompt({name:"initializeChildGitRepo",type:"confirm",message:`${I.redBright.bold("Warning:")} "${n}" is already in a git worktree. Would you still like to initialize a new git repository in this directory?`,default:!1});if(!s){t.info("Skipping Git initialization.");return}}try{let s=nt(),{major:r,minor:l}=tt();r<2||l<28?(await A("git",["init"],{cwd:e}),await A("git",["branch","-m",s],{cwd:e})):await A("git",["init",`--initial-branch=${s}`],{cwd:e}),await A("git",["add","."],{cwd:e}),t.succeed(`${I.green("Successfully initialized and staged")} ${I.green.bold("git")} `)}catch{t.fail(`${I.bold.red("Failed:")} could not initialize git. Update git to the latest version! `)}};import E from"fs";import it from"path";function ye(e,t,i){E.readdirSync(e).forEach(n=>{let s=it.join(e,n);if(E.statSync(s).isDirectory())ye(s,t,i);else{let l=E.readFileSync(s,"utf8").replace(new RegExp(t,"g"),i);E.writeFileSync(s,l,"utf8")}})}var we=(e,t)=>{let i=t.replace(/\*/g,"").replace(/[^\/]$/,"$&/");ye(e,"~/",i)};var xe=({projectName:e=C,packages:t,noInstall:i})=>{let o=d();a.info("Next steps:"),e!=="."&&a.info(` cd ${e}`),i&&(o==="yarn"?a.info(` ${o}`):a.info(` ${o} install`)),t?.prisma.inUse&&a.info(` ${o==="npm"?"npx":o} prisma db push`),a.info(` ${o==="npm"?"npm run":o} dev`)};import ve from"path";var be=e=>{let t=e.split("/"),i=t[t.length-1];if(i==="."){let s=ve.resolve(process.cwd());i=ve.basename(s)}let o=t.findIndex(s=>s.startsWith("@"));t.findIndex(s=>s.startsWith("@"))!==-1&&(i=t.slice(o).join("/"));let n=t.filter(s=>!s.startsWith("@")).join("/");return[i,n]};import ot from"gradient-string";var st={blue:"#add7ff",cyan:"#89ddff",green:"#5de4c7",magenta:"#fae4fc",red:"#d0679d",yellow:"#fffac2"},ke=()=>{let e=ot(Object.values(st)),t=d();(t==="yarn"||t==="pnpm")&&console.log(""),console.log(e.multiline(V))};import{execSync as at}from"child_process";import rt from"https";var _e=e=>{let t=v();t.includes("beta")?(a.warn(" You are using a beta version of create-t3-app."),a.warn(" Please report any bugs you encounter.")):t.includes("next")?(a.warn(" You are running create-t3-app with the @next tag which is no longer maintained."),a.warn(" Please run the CLI with @latest instead.")):t!==e&&(a.warn(" You are using an outdated version of create-t3-app."),a.warn(" Your version:",t+".","Latest version in the npm registry:",e),a.warn(" Please run the CLI with @latest to get the latest updates.")),console.log("")};function lt(){return new Promise((e,t)=>{rt.get("https://registry.npmjs.org/-/package/create-t3-app/dist-tags",i=>{if(i.statusCode===200){let o="";i.on("data",n=>o+=n),i.on("end",()=>{e(JSON.parse(o).latest)})}else t()}).on("error",()=>{t()})})}var Pe=()=>lt().catch(()=>{try{return at("npm view create-t3-app version").toString().trim()}catch{return null}});import pt from"chalk";import{execa as J}from"execa";import L from"ora";var ct=async(e,t)=>{switch(e){case"npm":return await J(e,["install"],{cwd:t,stderr:"inherit"}),null;case"pnpm":let i=L("Running pnpm install...").start(),o=J(e,["install"],{cwd:t,stdout:"pipe"});return await new Promise((r,l)=>{o.stdout?.on("data",p=>{let c=p.toString();c.includes("Progress")&&(i.text=c.includes("|")?c.split(" | ")[1]??"":c)}),o.on("error",p=>l(p)),o.on("close",()=>r())}),i;case"yarn":let n=L("Running yarn...").start(),s=J(e,[],{cwd:t,stdout:"pipe"});return await new Promise((r,l)=>{s.stdout?.on("data",p=>{n.text=p.toString()}),s.on("error",p=>l(p)),s.on("close",()=>r())}),n}},Se=async({projectDir:e})=>{a.info("Installing dependencies...");let t=d();(await ct(t,e)||L()).succeed(pt.green(`Successfully installed dependencies! `))};var mt=async()=>{let e=await Pe();ke(),e&&_e(e);let{appName:t,packages:i,flags:{noGit:o,noInstall:n,importAlias:s}}=await se(),r=te(i),[l,p]=be(t),c=await ge({projectName:p,packages:r,importAlias:s,noInstall:n}),h=W.readJSONSync(R.join(c,"package.json"));h.name=l,h.ct3aMetadata={initVersion:v()},W.writeJSONSync(R.join(c,"package.json"),h,{spaces:2}),s!=="~/"&&we(c,s),n||await Se({projectDir:c}),W.renameSync(R.join(c,"_eslintrc.cjs"),R.join(c,".eslintrc.cjs")),o||await he(c),xe({projectName:p,packages:r,noInstall:n}),process.exit(0)};mt().catch(e=>{a.error("Aborting installation..."),e instanceof Error?a.error(e):(a.error("An unknown error has occurred. Please open an issue on github with the below:"),console.log(e)),process.exit(1)}); //# sourceMappingURL=index.js.map