@turbo/gen 2.0.4 → 2.0.5-canary.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. package/dist/cli.js +1 -1
  2. package/package.json +3 -3
package/dist/cli.js CHANGED
@@ -64,7 +64,7 @@ Please report this to https://github.com/szmarczak/http2-wrapper/`);_(y)}return}
64
64
  `,`1. Your spelling of example ${wr.default.red(`"${e}"`)} might be incorrect.
65
65
  `,"2. You might not be connected to the internet or you are behind a proxy."),process.exit(1))}let o=Li.default.resolve(t);await em(Li.default.dirname(o))||(yt("The application path is not writable, please check folder permissions and try again."),yt("It is likely you do not have write permissions for this folder."),process.exit(1));let a=Li.default.basename(o);try{await(0,Ni.mkdir)(o,{recursive:!0})}catch(p){yt("Unable to create project directory"),yt(p),process.exit(1)}let{isEmpty:u,conflicts:c}=ls(o);u||(yt(`${wr.default.dim(o)} has ${c.length} conflicting ${c.length===1?"file":"files"} - please try a different location`),process.exit(1));let l=process.cwd();process.chdir(o);let f=kf("Downloading files...");try{!r&&i?(gt(`
66
66
  Downloading files from repo ${wr.default.cyan(e)}. This might take a moment.`),gt(),f.start(),await(0,tm.default)(()=>Zp(o,i),{retries:3})):(gt(`
67
- Downloading files${r?"":` for example ${wr.default.cyan(e)}`}. This might take a moment.`),gt(),f.start(),await(0,tm.default)(()=>Qp(o,e),{retries:3}))}catch(p){throw new Gu(qM(p)?p.message:String(p))}finally{f.stop()}let h=Li.default.join(o,"package.json"),m=(0,Ni.existsSync)(h),_=[];if(m){let p;try{p=(0,Ni.readJsonSync)(h)}catch{}p&&_.push(...Object.keys(p.scripts||{}))}let y=t;return Li.default.join(l,a)===t&&(y=a),{cdPath:y,hasPackageJson:m,availableScripts:_,repoInfo:i}}function nm(t,e={to:"camel"}){switch(e.to){case"camel":return t.replace(/(?:[-_][a-z])/g,r=>r.toUpperCase().replace("-","").replace("_",""));default:throw new Error("Not implemented")}}var yv=require("proxy-agent");var $s={name:"@turbo/gen",version:"2.0.4",description:"Extend a Turborepo",homepage:"https://turbo.build/repo",license:"MIT",repository:{type:"git",url:"https://github.com/vercel/turbo",directory:"packages/turbo-gen"},bugs:{url:"https://github.com/vercel/turbo/issues"},bin:"dist/cli.js",types:"dist/types.d.ts",scripts:{build:"tsup",test:"jest",lint:"eslint src/","check-types":"tsc --noEmit"},dependencies:{"@turbo/workspaces":"workspace:*",chalk:"2.4.2",commander:"^10.0.0","fs-extra":"^10.1.0",inquirer:"^8.2.4",minimatch:"^9.0.0","node-plop":"^0.26.3","proxy-agent":"^6.2.2","ts-node":"^10.9.1","update-check":"^1.5.4","validate-npm-package-name":"^5.0.0"},devDependencies:{"@turbo/eslint-config":"workspace:*","@turbo/test-utils":"workspace:*","@turbo/tsconfig":"workspace:*","@turbo/utils":"workspace:*","@types/fs-extra":"^9.0.13","@types/inquirer":"^8.2.5","@types/jest":"^27.4.0","@types/node":"^18.17.2","@types/validate-npm-package-name":"^4.0.0",jest:"^27.4.3","ts-jest":"^27.1.1",tsup:"^6.7.0",typescript:"5.3.3"},files:["dist"],publishConfig:{access:"public"}};var $C=X(require("chalk")),UC=X(require("update-check"));var jM=(0,UC.default)($s).catch(()=>null);async function im(){try{let t=await jM;t!=null&&t.latest&&(L.log(),L.log($C.default.yellow.bold(`A new version of \`${$s.name}\` is available!`)),L.log()),process.exit()}catch{}}var GC=require("@turbo/workspaces");async function Wu({root:t}){let e=t||process.cwd(),r=Wi(e);if(!r)L.error("Unable to infer repository root - override with --root");else try{return(0,GC.getWorkspaceDetails)({root:r})}catch{L.error(`Unable to determine workspace details. Make sure "${e}" is the root, or add "packageManager" to "package.json" or ensure a lockfile is present.`)}process.exit(1)}var Ar=X(require("path")),Vu=X(require("fs-extra")),zu=X(require("node-plop")),WC=require("ts-node"),zC=require("inquirer");var Me=class extends Error{constructor(r,n){var i;super(r);this.name="GenerateError",this.type=(i=n==null?void 0:n.type)!=null?i:"unknown",Error.captureStackTrace(this,Me)}};var VC=["ts","js","cjs"],$M=Ar.default.join("turbo","generators"),YC=VC.map(t=>Ar.default.join($M,`config.${t}`)),UM=[...YC,...VC.map(t=>Ar.default.join(`plopfile.${t}`))];function KC({project:t,configPath:e}){(0,WC.register)({transpileOnly:!0,cwd:t.paths.root,compilerOptions:{module:"nodenext",moduleResolution:"nodenext"}});let r=WM({project:t}),n;if(e){if(!Vu.default.existsSync(e))throw new Me(`No config at "${e}"`,{type:"plop_no_config"});try{n=(0,zu.default)(e,{destBasePath:e,force:!1})}catch(i){L.error(i)}}else{for(let i of UM){let s=Ar.default.join(t.paths.root,i);if(Vu.default.existsSync(s))try{n=(0,zu.default)(s,{destBasePath:t.paths.root,force:!1});break}catch(o){L.error(o)}}!n&&r.length>0&&(n=(0,zu.default)(r[0].config,{destBasePath:r[0].root,force:!1}),r.shift())}return n&&r.forEach(i=>{try{n==null||n.load(i.config,{destBasePath:i.root,force:!1})}catch(s){L.error(s)}}),n}function sm({project:t,configPath:e}){let r=KC({project:t,configPath:e});if(!r)return[];let i=r.getGeneratorList().map(a=>r.getGenerator(a.name)),s={};i.forEach(a=>{let u=a,c=t.workspaceData.workspaces.find(l=>{if(u.basePath===t.paths.root)return!1;let f=u.basePath.split(Ar.default.sep);return f.pop(),f.pop(),Ar.default.join("/",...f)===l.paths.root});c?(c.name in s||(s[c.name]=[]),s[c.name].push(u)):("root"in s||(s.root=[]),s.root.push(u))});let o=[];return Object.keys(s).forEach(a=>{o.push(new zC.Separator(a)),o.push(...s[a])}),o}function GM({project:t,generator:e}){let r={cwd:process.cwd(),root:t.paths.root,workspace:e.basePath?Gi({cwd:e.basePath,target:"package.json"}):void 0},n={};try{n=If(e.basePath)}catch{}return{turbo:{paths:r,configs:n}}}function WM({project:t}){let e=[];return t.workspaceData.workspaces.forEach(r=>{for(let n of YC)Vu.default.existsSync(Ar.default.join(r.paths.root,n))&&e.push({config:Ar.default.join(r.paths.root,n),root:r.paths.root})}),e}async function JC({project:t,generator:e,bypassArgs:r,configPath:n}){let i=KC({project:t,configPath:n});if(!i)throw new Me("Unable to load generators",{type:"plop_unable_to_load_config"});let s=i.getGenerator(e);if(!s)throw new Me(`Generator ${e} not found`,{type:"plop_generator_not_found"});let o=await s.runPrompts(r),a=await s.runActions({...o,...GM({project:t,generator:s})},{onComment:u=>{L.dimmed(u)}});if(a.failures.length>0)throw a.failures.forEach(u=>{u instanceof Error?L.error(`Error - ${u.message}`):L.error(`Error - ${u.error}. Unable to ${u.type} to "${u.path}"`)}),new Me(`Failed to run "${e}" generator`,{type:"plop_error_running_generator"});a.changes.length>0&&(L.info("Changes made:"),a.changes.forEach(u=>{u.path&&L.item(`${u.path} (${u.type})`)}))}var Rn=require("inquirer");async function XC({generators:t,generator:e}){if(e){if(t.find(n=>!(n instanceof Rn.Separator)&&n.name===e))return{selectedGenerator:e};L.warn(`Generator "${e}" not found`),L.log()}return await(0,Rn.prompt)({type:"list",name:"selectedGenerator",message:"Select generator to run",choices:t.map(n=>n instanceof Rn.Separator?n:{name:n.description?` ${n.name}: ${n.description}`:` ${n.name}`,value:n.name})})}async function ZC(){return(0,Rn.prompt)({type:"list",name:"answer",message:"Should the generator config be created with TS or JS?",default:"ts",choices:[{name:"JavaScript",value:"js"},{name:"TypeScript",value:"ts"}]})}async function QC({message:t}){return(0,Rn.prompt)({type:"confirm",name:"answer",message:t})}var om=X(require("path")),Yu=require("fs-extra");async function ev({project:t,template:e}){let r=om.default.join(t.paths.root,"turbo","generators"),n=`simple-${e}`;if(await(0,Yu.pathExists)(r))throw new Me(`Generator config directory already exists at ${r}`,{type:"config_directory_already_exists"});await(0,Yu.copy)(om.default.join(__dirname,"templates",n),r,{recursive:!0})}async function am({generator:t,project:e,opts:r}){let n=!1,i=sm({project:e,configPath:r.config});if(!i.length){L.error("No generators found."),L.log();let{answer:o}=await QC({message:`Would you like to add a config with a sample custom generator to ${e.name}?`});if(o){n=!0;let{answer:a}=await ZC();try{await ev({project:e,template:a})}catch(u){throw u instanceof Me||L.error("Failed to create generator config"),u}if(L.log(),L.info("Generator config successfully created!"),L.info("Loading generator config..."),L.log(),i=sm({project:e,configPath:r.config}),!i.length){L.error("Error loading generator");return}}else{L.log(),L.dimmed("Learn more about custom Turborepo generators - https://turbo.build/repo/docs/core-concepts/monorepos/code-generation#custom-generators");return}}let{selectedGenerator:s}=await XC({generators:i,generator:t});try{await JC({project:e,generator:s,bypassArgs:r.args,configPath:r.config})}catch(o){if(o instanceof Me)throw o;let a="Failed to run generator";throw o instanceof Error&&(a=o.message),new Me(a,{type:"plop_error_running_generator"})}finally{n&&(L.log(),L.info("Congrats! You just ran your first Turborepo generator"),L.dimmed("Learn more about custom Turborepo generators - https://turbo.build/repo/docs/core-concepts/monorepos/code-generation#custom-generators"))}L.log(),L.bold(L.turboGradient(">>> Success!"))}var fm=X(require("path")),Gs=require("fs-extra"),fv=X(require("chalk"));var Us=X(require("path")),iv=require("fs-extra"),vt=require("inquirer"),sv=require("minimatch"),lm=X(require("validate-npm-package-name"));var um=X(require("path"));var tv=X(require("path"));function rv({project:t}){let r=t.workspaceData.workspaces.map(i=>tv.default.relative(t.paths.root,i.paths.root)),n=new Set;return t.workspaceData.globs.forEach(i=>{if(!r.includes(i)){if(!i.startsWith("!")){let o=i.split("/")[0];n.add(o)}}}),Array.from(n)}function cm({project:t,workspace:e}){return um.default.relative(t.paths.root,e.paths.root).split(um.default.sep)[0]}function Ku({project:t}){let e=rv({project:t}),r=e.includes("apps"),n=e.includes("packages"),i={},s=[];return t.workspaceData.workspaces.forEach(o=>{let a=cm({project:t,workspace:o});a!=="apps"&&s.push(o),a in i||(i[a]=[]),i[a].push(o)}),{hasRootApps:r,hasRootPackages:n,workspacesByGroup:i,nonAppWorkspaces:s}}var nv=require("inquirer");function Ju({project:t,type:e,showAllDependencies:r}){let n=Ku({project:t}),i=[],s=t.workspaceData.workspaces;r||(e==="app"&&n.hasRootApps?s=n.workspacesByGroup.apps:e==="package"&&n.nonAppWorkspaces.length>0&&(s=n.nonAppWorkspaces));let o;return s.forEach(a=>{let u=cm({project:t,workspace:a});u!==o&&i.push(new nv.Separator(u)),o=u,i.push(a)}),i}async function ov({override:t,suggestion:e,workspaceType:r}){let{validForNewPackages:n}=(0,lm.default)(t||"");return t&&n?{answer:t}:(0,vt.prompt)({type:"input",name:"answer",default:e,validate:i=>{let{validForNewPackages:s}=(0,lm.default)(i);return s||`Invalid ${r} name`},message:`What is the name of the ${r}?`})}async function av({override:t,message:e}){return t?{answer:t}:(0,vt.prompt)({type:"list",name:"answer",message:e!=null?e:"What type of workspace should be added?",choices:[{name:"app",value:"app"},{name:"package",value:"package"}]})}async function uv({workspaceType:t,workspaceName:e,destination:r,project:n}){let i=e.includes("/")?e.split("/")[1]:e;if(r){let{valid:u,root:c}=ua(r);if(u)return{absolute:c,relative:Us.default.relative(n.paths.root,c)}}let s,o=Ku({project:n});t==="app"&&o.hasRootApps?s=`${n.paths.root}/apps/${i}`:t==="package"&&o.hasRootPackages&&(s=`${n.paths.root}/packages/${i}`);let{answer:a}=await(0,vt.prompt)({type:"input",name:"answer",message:`Where should "${e}" be added?`,default:s?Us.default.relative(n.paths.root,s):void 0,validate:u=>{let c=Us.default.join(n.paths.root,u),{valid:l,error:f}=ua(c),h=n.workspaceData.globs.some(m=>(0,sv.minimatch)(u,m));return l&&h?!0:h?f:`${u} is not a valid workspace location`}});return{absolute:Us.default.join(n.paths.root,a),relative:a}}async function cv({override:t,workspaces:e,workspaceName:r}){if(t){let i=e.find(s=>s instanceof vt.Separator?!1:s.name===t);if(i)return{answer:i};L.warn(`Workspace "${t}" not found`),L.log()}return await(0,vt.prompt)({type:"list",name:"answer",loop:!1,pageSize:25,message:`Which workspace should "${r}" start from?`,choices:e.map(i=>i instanceof vt.Separator?i:{name:` ${i.name}`,value:i})})}async function lv({workspaceName:t,project:e,workspaceSource:r,showAllDependencies:n}){let i={dependencies:{},devDependencies:{},peerDependencies:{},optionalDependencies:{}},{answer:s}=await VM({message:`Add workspace dependencies to "${t}"?`});if(!s)return i;let{answer:o}=await(0,vt.prompt)({type:"checkbox",name:"answer",message:`Select all dependencies types to modify for "${t}"`,loop:!1,choices:[{name:"dependencies",value:"dependencies"},{name:"devDependencies",value:"devDependencies"},{name:"peerDependencies",value:"peerDependencies"},{name:"optionalDependencies",value:"optionalDependencies"}]}),a=Ju({project:e,type:"package",showAllDependencies:n}),u=r?(0,iv.readJsonSync)(r.paths.packageJson):void 0;for(let c of o){let{answer:l}=await(0,vt.prompt)({type:"checkbox",name:"answer",default:u&&Object.keys(u[c]||{}),pageSize:15,message:`Which packages should be added as ${c} to "${t}?`,loop:!1,choices:a.map(h=>h instanceof vt.Separator?h:{name:` ${h.name}`,value:h.name})}),f=(u==null?void 0:u[c])||{};if(Object.keys(f).length){let h=new Set(Object.keys(f));l.forEach(m=>{h.has(m)||(f[m]=e.packageManager==="pnpm"?"workspace:*":"*")}),i[c]=f}else i[c]=l.reduce((h,m)=>({...h,[m]:e.packageManager==="pnpm"?"workspace:*":"*"}),{})}return i}async function VM({message:t}){return(0,vt.prompt)({type:"confirm",name:"answer",message:t})}async function Xu({project:t,opts:e}){var u;let r,n=e.method==="copy"&&e.copy.type==="external"?((u=e.examplePath)==null?void 0:u.split("/").pop())||e.copy.source.split("/").pop():void 0,{answer:i}=await av({override:e.type,message:e.method==="copy"&&e.copy.source==="external"&&n?`What type of workspace should "${n}" be created as?`:void 0}),{answer:s}=await ov({override:e.name,workspaceType:i,suggestion:n});if(e.method==="copy"&&e.copy.type==="internal"){let{answer:c}=await cv({override:e.copy.source,workspaces:Ju({project:t,type:i}),workspaceName:s});r=c}let o=await uv({workspaceType:i,workspaceName:s,project:t,destination:e.destination}),a=await lv({workspaceName:s,project:t,workspaceSource:r,showAllDependencies:e.showAllDependencies});return{type:i,name:s,location:o,source:r,dependencies:a}}async function hm({project:t,opts:e}){let{name:r,location:n,dependencies:i}=await Xu({project:t,opts:e}),s={name:r,version:"0.0.0",private:!0,scripts:{dev:"echo 'Add dev script here'",build:"echo 'Add build script here'",test:"echo 'Add test script here'",lint:"echo 'Add lint script here'"}};Object.keys(i).forEach(o=>{let a=i[o];a&&Object.keys(a).length>0&&(s[o]=a)}),(0,Gs.mkdirSync)(n.absolute,{recursive:!0}),(0,Gs.writeFileSync)(fm.default.join(n.absolute,"package.json"),JSON.stringify(s,null,2)),(0,Gs.writeFileSync)(fm.default.join(n.absolute,"README.md"),`# \`${r}\``),L.log(),L.log(`${fv.default.bold(L.turboGradient(">>> Success!"))} Created ${r} at "${n.relative}"`)}var dm=X(require("path")),Rt=require("fs-extra"),hv=X(require("chalk"));async function pm({project:t,opts:e}){let{name:r,type:n,location:i,source:s,dependencies:o}=await Xu({project:t,opts:e}),a=dm.default.join(i.absolute,"package.json");if(e.copy.type==="external"){L.log(),L.warn("Some manual modifications may be required."),L.dimmed(`This ${n} may require local dependencies or a different package manager than what is available in this repo`),await rm({appPath:i.absolute,example:e.copy.source,examplePath:e.examplePath});try{if((0,Rt.existsSync)(a)){if((await(0,Rt.readJSON)(a)).workspaces)throw new Error("New workspace root detected - unexpected 'workspaces' field in package.json")}else throw new Error("New workspace is missing a package.json file");if((0,Rt.existsSync)(dm.default.join(i.absolute,"pnpm-workspace.yaml")))throw new Error("New workspace root detected - unexpected pnpm-workspace.yaml")}catch(c){let l="UNKNOWN_ERROR";c instanceof Error&&(l=c.message),L.error(l),await(0,Rt.rm)(i.absolute,{recursive:!0,force:!0});return}}else if(s){let c=async f=>Promise.resolve(!f.includes("node_modules")),l=L.turboLoader(`Creating "${r}" from "${s.name}"...`);l.start(),await(0,Rt.copy)(s.paths.root,i.absolute,{filter:c}),l.stop()}let u=await(0,Rt.readJSON)(a);u.name=r,Object.keys(o).forEach(c=>{let l=o[c];l&&Object.keys(l).length>0&&(u[c]=l)}),await(0,Rt.writeJSON)(a,u,{spaces:2}),L.log(),L.log(`${hv.default.bold(L.turboGradient(">>> Success!"))} Created ${r} at "${i.relative}"`)}function KM(t){let{copy:e,...r}=t,n=e===!0||typeof e=="string"?"copy":"empty",i=typeof e=="string"?e:"",s=typeof e=="string"&&e.startsWith("https://")?"external":"internal";return{method:n,copy:{type:s,source:i},...r}}async function Ws(t){let e=await Wu(t),r=KM(t);L.log();let n={project:e,opts:r};r.method==="copy"?(r.copy.type==="external"?L.info(`Copy a remote workspace from ${r.copy.source}`):L.info(`Copy an existing workspace from "${e.name}"`),L.log(),await pm(n)):(L.info(`Add an empty workspace to "${e.name}"`),L.log(),await hm(n))}async function zs(t,e){let r=await Wu(e);L.log(),L.info(`Modify "${r.name}" using custom generators`),L.log(),await am({generator:t,project:r,opts:e})}function dv(t){try{let e=JSON.parse(t),r={};for(let n in e){let i=nm(n,{to:"camel"});r[i]=e[n]}return r}catch(e){L.error("Error parsing arguments",e),process.exit(1)}}async function mm(t,e){var r;if(t==="workspace"){let n=dv(e.json);n.showAllDependencies=(r=n.showAllDependencies)!=null?r:!1;let i=!1,s=n.empty||!0;n.copy===""||n.copy===!0?(i=!0,s=!1):n.copy&&n.copy.length>0&&(i=n.copy,s=!1),n.copy=i,n.empty=s,await Ws(n)}else if(t==="run"){let n=dv(e.json),{generatorName:i,...s}=n;await zs(i,s)}else L.error(`Received unknown command - "${t}" (must be one of "workspace" | "run")`),process.exit(1)}var _v=new yv.ProxyAgent;pv.default.globalAgent=_v;mv.default.globalAgent=_v;var Vs=new qe.Command;Vs.name(gv.default.bold(L.turboGradient("@turbo/gen"))).description("Extend your Turborepo").version($s.version,"-v, --version","Output the current version").helpOption("-h, --help","Display help for command").showHelpAfterError(!1);Vs.command("run",{isDefault:!0}).alias("r").description("Run custom generators").addArgument(new qe.Argument("[generator-name]","The name of the generator to run")).addOption(new qe.Option("-c, --config <config>","Generator configuration file (default: turbo/generators/config.js")).addOption(new qe.Option("-r, --root <dir>","The root of your repository (default: directory with root turbo.json)")).addOption(new qe.Option("-a, --args <args...>","Arguments passed directly to generator").default([])).action(zs);Vs.command("workspace").aliases(["w"]).description("Add a new package or app to your project").addOption(new qe.Option("-n, --name <workspace-name>","Name for the new workspace")).addOption(new qe.Option("-b, --empty","Generate an empty workspace").conflicts("copy").default(!0)).addOption(new qe.Option("-c, --copy [source]",`Generate a workspace using an existing workspace as a template. Can be the name of a local workspace
67
+ Downloading files${r?"":` for example ${wr.default.cyan(e)}`}. This might take a moment.`),gt(),f.start(),await(0,tm.default)(()=>Qp(o,e),{retries:3}))}catch(p){throw new Gu(qM(p)?p.message:String(p))}finally{f.stop()}let h=Li.default.join(o,"package.json"),m=(0,Ni.existsSync)(h),_=[];if(m){let p;try{p=(0,Ni.readJsonSync)(h)}catch{}p&&_.push(...Object.keys(p.scripts||{}))}let y=t;return Li.default.join(l,a)===t&&(y=a),{cdPath:y,hasPackageJson:m,availableScripts:_,repoInfo:i}}function nm(t,e={to:"camel"}){switch(e.to){case"camel":return t.replace(/(?:[-_][a-z])/g,r=>r.toUpperCase().replace("-","").replace("_",""));default:throw new Error("Not implemented")}}var yv=require("proxy-agent");var $s={name:"@turbo/gen",version:"2.0.5-canary.0",description:"Extend a Turborepo",homepage:"https://turbo.build/repo",license:"MIT",repository:{type:"git",url:"https://github.com/vercel/turbo",directory:"packages/turbo-gen"},bugs:{url:"https://github.com/vercel/turbo/issues"},bin:"dist/cli.js",types:"dist/types.d.ts",scripts:{build:"tsup",test:"jest",lint:"eslint src/","check-types":"tsc --noEmit"},dependencies:{"@turbo/workspaces":"workspace:*",chalk:"2.4.2",commander:"^10.0.0","fs-extra":"^10.1.0",inquirer:"^8.2.4",minimatch:"^9.0.0","node-plop":"^0.26.3","proxy-agent":"^6.2.2","ts-node":"^10.9.1","update-check":"^1.5.4","validate-npm-package-name":"^5.0.0"},devDependencies:{"@turbo/eslint-config":"workspace:*","@turbo/test-utils":"workspace:*","@turbo/tsconfig":"workspace:*","@turbo/utils":"workspace:*","@types/fs-extra":"^9.0.13","@types/inquirer":"^8.2.5","@types/jest":"^27.4.0","@types/node":"^18.17.2","@types/validate-npm-package-name":"^4.0.0",jest:"^27.4.3","ts-jest":"^27.1.1",tsup:"^6.7.0",typescript:"5.3.3"},files:["dist"],publishConfig:{access:"public"}};var $C=X(require("chalk")),UC=X(require("update-check"));var jM=(0,UC.default)($s).catch(()=>null);async function im(){try{let t=await jM;t!=null&&t.latest&&(L.log(),L.log($C.default.yellow.bold(`A new version of \`${$s.name}\` is available!`)),L.log()),process.exit()}catch{}}var GC=require("@turbo/workspaces");async function Wu({root:t}){let e=t||process.cwd(),r=Wi(e);if(!r)L.error("Unable to infer repository root - override with --root");else try{return(0,GC.getWorkspaceDetails)({root:r})}catch{L.error(`Unable to determine workspace details. Make sure "${e}" is the root, or add "packageManager" to "package.json" or ensure a lockfile is present.`)}process.exit(1)}var Ar=X(require("path")),Vu=X(require("fs-extra")),zu=X(require("node-plop")),WC=require("ts-node"),zC=require("inquirer");var Me=class extends Error{constructor(r,n){var i;super(r);this.name="GenerateError",this.type=(i=n==null?void 0:n.type)!=null?i:"unknown",Error.captureStackTrace(this,Me)}};var VC=["ts","js","cjs"],$M=Ar.default.join("turbo","generators"),YC=VC.map(t=>Ar.default.join($M,`config.${t}`)),UM=[...YC,...VC.map(t=>Ar.default.join(`plopfile.${t}`))];function KC({project:t,configPath:e}){(0,WC.register)({transpileOnly:!0,cwd:t.paths.root,compilerOptions:{module:"nodenext",moduleResolution:"nodenext"}});let r=WM({project:t}),n;if(e){if(!Vu.default.existsSync(e))throw new Me(`No config at "${e}"`,{type:"plop_no_config"});try{n=(0,zu.default)(e,{destBasePath:e,force:!1})}catch(i){L.error(i)}}else{for(let i of UM){let s=Ar.default.join(t.paths.root,i);if(Vu.default.existsSync(s))try{n=(0,zu.default)(s,{destBasePath:t.paths.root,force:!1});break}catch(o){L.error(o)}}!n&&r.length>0&&(n=(0,zu.default)(r[0].config,{destBasePath:r[0].root,force:!1}),r.shift())}return n&&r.forEach(i=>{try{n==null||n.load(i.config,{destBasePath:i.root,force:!1})}catch(s){L.error(s)}}),n}function sm({project:t,configPath:e}){let r=KC({project:t,configPath:e});if(!r)return[];let i=r.getGeneratorList().map(a=>r.getGenerator(a.name)),s={};i.forEach(a=>{let u=a,c=t.workspaceData.workspaces.find(l=>{if(u.basePath===t.paths.root)return!1;let f=u.basePath.split(Ar.default.sep);return f.pop(),f.pop(),Ar.default.join("/",...f)===l.paths.root});c?(c.name in s||(s[c.name]=[]),s[c.name].push(u)):("root"in s||(s.root=[]),s.root.push(u))});let o=[];return Object.keys(s).forEach(a=>{o.push(new zC.Separator(a)),o.push(...s[a])}),o}function GM({project:t,generator:e}){let r={cwd:process.cwd(),root:t.paths.root,workspace:e.basePath?Gi({cwd:e.basePath,target:"package.json"}):void 0},n={};try{n=If(e.basePath)}catch{}return{turbo:{paths:r,configs:n}}}function WM({project:t}){let e=[];return t.workspaceData.workspaces.forEach(r=>{for(let n of YC)Vu.default.existsSync(Ar.default.join(r.paths.root,n))&&e.push({config:Ar.default.join(r.paths.root,n),root:r.paths.root})}),e}async function JC({project:t,generator:e,bypassArgs:r,configPath:n}){let i=KC({project:t,configPath:n});if(!i)throw new Me("Unable to load generators",{type:"plop_unable_to_load_config"});let s=i.getGenerator(e);if(!s)throw new Me(`Generator ${e} not found`,{type:"plop_generator_not_found"});let o=await s.runPrompts(r),a=await s.runActions({...o,...GM({project:t,generator:s})},{onComment:u=>{L.dimmed(u)}});if(a.failures.length>0)throw a.failures.forEach(u=>{u instanceof Error?L.error(`Error - ${u.message}`):L.error(`Error - ${u.error}. Unable to ${u.type} to "${u.path}"`)}),new Me(`Failed to run "${e}" generator`,{type:"plop_error_running_generator"});a.changes.length>0&&(L.info("Changes made:"),a.changes.forEach(u=>{u.path&&L.item(`${u.path} (${u.type})`)}))}var Rn=require("inquirer");async function XC({generators:t,generator:e}){if(e){if(t.find(n=>!(n instanceof Rn.Separator)&&n.name===e))return{selectedGenerator:e};L.warn(`Generator "${e}" not found`),L.log()}return await(0,Rn.prompt)({type:"list",name:"selectedGenerator",message:"Select generator to run",choices:t.map(n=>n instanceof Rn.Separator?n:{name:n.description?` ${n.name}: ${n.description}`:` ${n.name}`,value:n.name})})}async function ZC(){return(0,Rn.prompt)({type:"list",name:"answer",message:"Should the generator config be created with TS or JS?",default:"ts",choices:[{name:"JavaScript",value:"js"},{name:"TypeScript",value:"ts"}]})}async function QC({message:t}){return(0,Rn.prompt)({type:"confirm",name:"answer",message:t})}var om=X(require("path")),Yu=require("fs-extra");async function ev({project:t,template:e}){let r=om.default.join(t.paths.root,"turbo","generators"),n=`simple-${e}`;if(await(0,Yu.pathExists)(r))throw new Me(`Generator config directory already exists at ${r}`,{type:"config_directory_already_exists"});await(0,Yu.copy)(om.default.join(__dirname,"templates",n),r,{recursive:!0})}async function am({generator:t,project:e,opts:r}){let n=!1,i=sm({project:e,configPath:r.config});if(!i.length){L.error("No generators found."),L.log();let{answer:o}=await QC({message:`Would you like to add a config with a sample custom generator to ${e.name}?`});if(o){n=!0;let{answer:a}=await ZC();try{await ev({project:e,template:a})}catch(u){throw u instanceof Me||L.error("Failed to create generator config"),u}if(L.log(),L.info("Generator config successfully created!"),L.info("Loading generator config..."),L.log(),i=sm({project:e,configPath:r.config}),!i.length){L.error("Error loading generator");return}}else{L.log(),L.dimmed("Learn more about custom Turborepo generators - https://turbo.build/repo/docs/core-concepts/monorepos/code-generation#custom-generators");return}}let{selectedGenerator:s}=await XC({generators:i,generator:t});try{await JC({project:e,generator:s,bypassArgs:r.args,configPath:r.config})}catch(o){if(o instanceof Me)throw o;let a="Failed to run generator";throw o instanceof Error&&(a=o.message),new Me(a,{type:"plop_error_running_generator"})}finally{n&&(L.log(),L.info("Congrats! You just ran your first Turborepo generator"),L.dimmed("Learn more about custom Turborepo generators - https://turbo.build/repo/docs/core-concepts/monorepos/code-generation#custom-generators"))}L.log(),L.bold(L.turboGradient(">>> Success!"))}var fm=X(require("path")),Gs=require("fs-extra"),fv=X(require("chalk"));var Us=X(require("path")),iv=require("fs-extra"),vt=require("inquirer"),sv=require("minimatch"),lm=X(require("validate-npm-package-name"));var um=X(require("path"));var tv=X(require("path"));function rv({project:t}){let r=t.workspaceData.workspaces.map(i=>tv.default.relative(t.paths.root,i.paths.root)),n=new Set;return t.workspaceData.globs.forEach(i=>{if(!r.includes(i)){if(!i.startsWith("!")){let o=i.split("/")[0];n.add(o)}}}),Array.from(n)}function cm({project:t,workspace:e}){return um.default.relative(t.paths.root,e.paths.root).split(um.default.sep)[0]}function Ku({project:t}){let e=rv({project:t}),r=e.includes("apps"),n=e.includes("packages"),i={},s=[];return t.workspaceData.workspaces.forEach(o=>{let a=cm({project:t,workspace:o});a!=="apps"&&s.push(o),a in i||(i[a]=[]),i[a].push(o)}),{hasRootApps:r,hasRootPackages:n,workspacesByGroup:i,nonAppWorkspaces:s}}var nv=require("inquirer");function Ju({project:t,type:e,showAllDependencies:r}){let n=Ku({project:t}),i=[],s=t.workspaceData.workspaces;r||(e==="app"&&n.hasRootApps?s=n.workspacesByGroup.apps:e==="package"&&n.nonAppWorkspaces.length>0&&(s=n.nonAppWorkspaces));let o;return s.forEach(a=>{let u=cm({project:t,workspace:a});u!==o&&i.push(new nv.Separator(u)),o=u,i.push(a)}),i}async function ov({override:t,suggestion:e,workspaceType:r}){let{validForNewPackages:n}=(0,lm.default)(t||"");return t&&n?{answer:t}:(0,vt.prompt)({type:"input",name:"answer",default:e,validate:i=>{let{validForNewPackages:s}=(0,lm.default)(i);return s||`Invalid ${r} name`},message:`What is the name of the ${r}?`})}async function av({override:t,message:e}){return t?{answer:t}:(0,vt.prompt)({type:"list",name:"answer",message:e!=null?e:"What type of workspace should be added?",choices:[{name:"app",value:"app"},{name:"package",value:"package"}]})}async function uv({workspaceType:t,workspaceName:e,destination:r,project:n}){let i=e.includes("/")?e.split("/")[1]:e;if(r){let{valid:u,root:c}=ua(r);if(u)return{absolute:c,relative:Us.default.relative(n.paths.root,c)}}let s,o=Ku({project:n});t==="app"&&o.hasRootApps?s=`${n.paths.root}/apps/${i}`:t==="package"&&o.hasRootPackages&&(s=`${n.paths.root}/packages/${i}`);let{answer:a}=await(0,vt.prompt)({type:"input",name:"answer",message:`Where should "${e}" be added?`,default:s?Us.default.relative(n.paths.root,s):void 0,validate:u=>{let c=Us.default.join(n.paths.root,u),{valid:l,error:f}=ua(c),h=n.workspaceData.globs.some(m=>(0,sv.minimatch)(u,m));return l&&h?!0:h?f:`${u} is not a valid workspace location`}});return{absolute:Us.default.join(n.paths.root,a),relative:a}}async function cv({override:t,workspaces:e,workspaceName:r}){if(t){let i=e.find(s=>s instanceof vt.Separator?!1:s.name===t);if(i)return{answer:i};L.warn(`Workspace "${t}" not found`),L.log()}return await(0,vt.prompt)({type:"list",name:"answer",loop:!1,pageSize:25,message:`Which workspace should "${r}" start from?`,choices:e.map(i=>i instanceof vt.Separator?i:{name:` ${i.name}`,value:i})})}async function lv({workspaceName:t,project:e,workspaceSource:r,showAllDependencies:n}){let i={dependencies:{},devDependencies:{},peerDependencies:{},optionalDependencies:{}},{answer:s}=await VM({message:`Add workspace dependencies to "${t}"?`});if(!s)return i;let{answer:o}=await(0,vt.prompt)({type:"checkbox",name:"answer",message:`Select all dependencies types to modify for "${t}"`,loop:!1,choices:[{name:"dependencies",value:"dependencies"},{name:"devDependencies",value:"devDependencies"},{name:"peerDependencies",value:"peerDependencies"},{name:"optionalDependencies",value:"optionalDependencies"}]}),a=Ju({project:e,type:"package",showAllDependencies:n}),u=r?(0,iv.readJsonSync)(r.paths.packageJson):void 0;for(let c of o){let{answer:l}=await(0,vt.prompt)({type:"checkbox",name:"answer",default:u&&Object.keys(u[c]||{}),pageSize:15,message:`Which packages should be added as ${c} to "${t}?`,loop:!1,choices:a.map(h=>h instanceof vt.Separator?h:{name:` ${h.name}`,value:h.name})}),f=(u==null?void 0:u[c])||{};if(Object.keys(f).length){let h=new Set(Object.keys(f));l.forEach(m=>{h.has(m)||(f[m]=e.packageManager==="pnpm"?"workspace:*":"*")}),i[c]=f}else i[c]=l.reduce((h,m)=>({...h,[m]:e.packageManager==="pnpm"?"workspace:*":"*"}),{})}return i}async function VM({message:t}){return(0,vt.prompt)({type:"confirm",name:"answer",message:t})}async function Xu({project:t,opts:e}){var u;let r,n=e.method==="copy"&&e.copy.type==="external"?((u=e.examplePath)==null?void 0:u.split("/").pop())||e.copy.source.split("/").pop():void 0,{answer:i}=await av({override:e.type,message:e.method==="copy"&&e.copy.source==="external"&&n?`What type of workspace should "${n}" be created as?`:void 0}),{answer:s}=await ov({override:e.name,workspaceType:i,suggestion:n});if(e.method==="copy"&&e.copy.type==="internal"){let{answer:c}=await cv({override:e.copy.source,workspaces:Ju({project:t,type:i}),workspaceName:s});r=c}let o=await uv({workspaceType:i,workspaceName:s,project:t,destination:e.destination}),a=await lv({workspaceName:s,project:t,workspaceSource:r,showAllDependencies:e.showAllDependencies});return{type:i,name:s,location:o,source:r,dependencies:a}}async function hm({project:t,opts:e}){let{name:r,location:n,dependencies:i}=await Xu({project:t,opts:e}),s={name:r,version:"0.0.0",private:!0,scripts:{dev:"echo 'Add dev script here'",build:"echo 'Add build script here'",test:"echo 'Add test script here'",lint:"echo 'Add lint script here'"}};Object.keys(i).forEach(o=>{let a=i[o];a&&Object.keys(a).length>0&&(s[o]=a)}),(0,Gs.mkdirSync)(n.absolute,{recursive:!0}),(0,Gs.writeFileSync)(fm.default.join(n.absolute,"package.json"),JSON.stringify(s,null,2)),(0,Gs.writeFileSync)(fm.default.join(n.absolute,"README.md"),`# \`${r}\``),L.log(),L.log(`${fv.default.bold(L.turboGradient(">>> Success!"))} Created ${r} at "${n.relative}"`)}var dm=X(require("path")),Rt=require("fs-extra"),hv=X(require("chalk"));async function pm({project:t,opts:e}){let{name:r,type:n,location:i,source:s,dependencies:o}=await Xu({project:t,opts:e}),a=dm.default.join(i.absolute,"package.json");if(e.copy.type==="external"){L.log(),L.warn("Some manual modifications may be required."),L.dimmed(`This ${n} may require local dependencies or a different package manager than what is available in this repo`),await rm({appPath:i.absolute,example:e.copy.source,examplePath:e.examplePath});try{if((0,Rt.existsSync)(a)){if((await(0,Rt.readJSON)(a)).workspaces)throw new Error("New workspace root detected - unexpected 'workspaces' field in package.json")}else throw new Error("New workspace is missing a package.json file");if((0,Rt.existsSync)(dm.default.join(i.absolute,"pnpm-workspace.yaml")))throw new Error("New workspace root detected - unexpected pnpm-workspace.yaml")}catch(c){let l="UNKNOWN_ERROR";c instanceof Error&&(l=c.message),L.error(l),await(0,Rt.rm)(i.absolute,{recursive:!0,force:!0});return}}else if(s){let c=async f=>Promise.resolve(!f.includes("node_modules")),l=L.turboLoader(`Creating "${r}" from "${s.name}"...`);l.start(),await(0,Rt.copy)(s.paths.root,i.absolute,{filter:c}),l.stop()}let u=await(0,Rt.readJSON)(a);u.name=r,Object.keys(o).forEach(c=>{let l=o[c];l&&Object.keys(l).length>0&&(u[c]=l)}),await(0,Rt.writeJSON)(a,u,{spaces:2}),L.log(),L.log(`${hv.default.bold(L.turboGradient(">>> Success!"))} Created ${r} at "${i.relative}"`)}function KM(t){let{copy:e,...r}=t,n=e===!0||typeof e=="string"?"copy":"empty",i=typeof e=="string"?e:"",s=typeof e=="string"&&e.startsWith("https://")?"external":"internal";return{method:n,copy:{type:s,source:i},...r}}async function Ws(t){let e=await Wu(t),r=KM(t);L.log();let n={project:e,opts:r};r.method==="copy"?(r.copy.type==="external"?L.info(`Copy a remote workspace from ${r.copy.source}`):L.info(`Copy an existing workspace from "${e.name}"`),L.log(),await pm(n)):(L.info(`Add an empty workspace to "${e.name}"`),L.log(),await hm(n))}async function zs(t,e){let r=await Wu(e);L.log(),L.info(`Modify "${r.name}" using custom generators`),L.log(),await am({generator:t,project:r,opts:e})}function dv(t){try{let e=JSON.parse(t),r={};for(let n in e){let i=nm(n,{to:"camel"});r[i]=e[n]}return r}catch(e){L.error("Error parsing arguments",e),process.exit(1)}}async function mm(t,e){var r;if(t==="workspace"){let n=dv(e.json);n.showAllDependencies=(r=n.showAllDependencies)!=null?r:!1;let i=!1,s=n.empty||!0;n.copy===""||n.copy===!0?(i=!0,s=!1):n.copy&&n.copy.length>0&&(i=n.copy,s=!1),n.copy=i,n.empty=s,await Ws(n)}else if(t==="run"){let n=dv(e.json),{generatorName:i,...s}=n;await zs(i,s)}else L.error(`Received unknown command - "${t}" (must be one of "workspace" | "run")`),process.exit(1)}var _v=new yv.ProxyAgent;pv.default.globalAgent=_v;mv.default.globalAgent=_v;var Vs=new qe.Command;Vs.name(gv.default.bold(L.turboGradient("@turbo/gen"))).description("Extend your Turborepo").version($s.version,"-v, --version","Output the current version").helpOption("-h, --help","Display help for command").showHelpAfterError(!1);Vs.command("run",{isDefault:!0}).alias("r").description("Run custom generators").addArgument(new qe.Argument("[generator-name]","The name of the generator to run")).addOption(new qe.Option("-c, --config <config>","Generator configuration file (default: turbo/generators/config.js")).addOption(new qe.Option("-r, --root <dir>","The root of your repository (default: directory with root turbo.json)")).addOption(new qe.Option("-a, --args <args...>","Arguments passed directly to generator").default([])).action(zs);Vs.command("workspace").aliases(["w"]).description("Add a new package or app to your project").addOption(new qe.Option("-n, --name <workspace-name>","Name for the new workspace")).addOption(new qe.Option("-b, --empty","Generate an empty workspace").conflicts("copy").default(!0)).addOption(new qe.Option("-c, --copy [source]",`Generate a workspace using an existing workspace as a template. Can be the name of a local workspace
68
68
  within your monorepo, or a fully qualified GitHub URL with any branch and/or subdirectory.
69
69
  `).conflicts("empty")).addOption(new qe.Option("-d, --destination <dir>","Where the new workspace should be created")).addOption(new qe.Option("-t, --type <type>","The type of workspace to create").choices(["app","package"])).addOption(new qe.Option("-r, --root <dir>","The root of your repository (default: directory with root turbo.json)")).addOption(new qe.Option("-p, --example-path <path-to-example>",`In a rare case, your GitHub URL might contain a branch name with
70
70
  a slash (e.g. bug/fix-1) and the path to the example (e.g. foo/bar).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@turbo/gen",
3
- "version": "2.0.4",
3
+ "version": "2.0.5-canary.0",
4
4
  "description": "Extend a Turborepo",
5
5
  "homepage": "https://turbo.build/repo",
6
6
  "license": "MIT",
@@ -25,7 +25,7 @@
25
25
  "ts-node": "^10.9.1",
26
26
  "update-check": "^1.5.4",
27
27
  "validate-npm-package-name": "^5.0.0",
28
- "@turbo/workspaces": "2.0.4"
28
+ "@turbo/workspaces": "2.0.5-canary.0"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/fs-extra": "^9.0.13",
@@ -37,9 +37,9 @@
37
37
  "ts-jest": "^27.1.1",
38
38
  "tsup": "^6.7.0",
39
39
  "typescript": "5.3.3",
40
- "@turbo/eslint-config": "0.0.0",
41
40
  "@turbo/test-utils": "0.0.0",
42
41
  "@turbo/tsconfig": "0.0.0",
42
+ "@turbo/eslint-config": "0.0.0",
43
43
  "@turbo/utils": "0.0.0"
44
44
  },
45
45
  "files": [