startx 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -200,4 +200,4 @@ $&`).replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g,`$1$2`).replace(/\
|
|
|
200
200
|
`+t:``),o=Math.floor(n.length/i)-this.cursorPos.rows+(t?Oy(t):0);o>0&&(a+=Cy(o)),a+=Ty(this.cursorPos.cols),this.write(wy(this.extraLinesUnderPrompt)+Dy(this.height)+a),this.extraLinesUnderPrompt=o,this.height=Oy(a)}checkCursorPos(){let e=this.rl.getCursorPos();e.cols!==this.cursorPos.cols&&(this.write(Ty(e.cols)),this.cursorPos=e)}done({clearContent:e}){this.rl.setPrompt(``);let t=wy(this.extraLinesUnderPrompt);t+=e?Dy(this.height):`
|
|
201
201
|
`,t+=`\x1B[?25h`,this.write(t),this.rl.close()}},jy=class extends Promise{static withResolver(){let e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),resolve:e,reject:t}}},My=b(sy(),1);const Ny=globalThis.setImmediate;function Py(){let e=Error.prepareStackTrace,t=[];try{Error.prepareStackTrace=(e,n)=>{let r=n.slice(1);return t=r,r},Error().stack}catch{return t}return Error.prepareStackTrace=e,t}function Fy(e){let t=Py();return(n,r={})=>{let{input:i=process.stdin,signal:a}=r,o=new Set,c=new My.default;c.pipe(r.output??process.stdout),c.mute();let l=u.createInterface({terminal:!0,input:i,output:c}),d=new Ay(l),{promise:f,resolve:p,reject:m}=jy.withResolver(),h=()=>m(new tv);if(a){let e=()=>m(new ev({cause:a.reason}));if(a.aborted)return e(),Object.assign(f,{cancel:h});a.addEventListener(`abort`,e),o.add(()=>a.removeEventListener(`abort`,e))}o.add(yy((e,t)=>{m(new nv(`User force closed the prompt with ${e} ${t}`))}));let g=()=>m(new nv(`User force closed the prompt with SIGINT`));return l.on(`SIGINT`,g),o.add(()=>l.removeListener(`SIGINT`,g)),sv(l,a=>{let u=s.bind(()=>pv.clearAll());l.on(`close`,u),o.add(()=>l.removeListener(`close`,u));let g=()=>{let r=()=>d.checkCursorPos();l.input.on(`keypress`,r),o.add(()=>l.input.removeListener(`keypress`,r)),a(()=>{try{let r=e(n,e=>{setImmediate(()=>p(e))});if(r===void 0){let e=t[1]?.getFileName();throw Error(`Prompt functions must return a string.\n at ${e}`)}let[i,a]=typeof r==`string`?[r]:r;d.render(i,a),pv.run()}catch(e){m(e)}})};return`readableFlowing`in i?Ny(g):g(),Object.assign(f.then(e=>(pv.clearAll(),e),e=>{throw pv.clearAll(),e}).finally(()=>{o.forEach(e=>e()),d.done({clearContent:!!r.clearPromptOnDone}),c.end()}).then(()=>f),{cancel:h})})}}var $=class{separator=l(`dim`,Array.from({length:15}).join(xv.line));type=`separator`;constructor(e){e&&(this.separator=e)}static isSeparator(e){return!!(e&&typeof e==`object`&&`type`in e&&e.type===`separator`)}};const Iy={icon:{checked:l(`green`,xv.circleFilled),unchecked:xv.circle,cursor:xv.pointer,disabledChecked:l(`green`,xv.circleDouble),disabledUnchecked:`-`},style:{disabled:e=>l(`dim`,e),renderSelectedChoices:e=>e.map(e=>e.short).join(`, `),description:e=>l(`cyan`,e),keysHelpTip:e=>e.map(([e,t])=>`${l(`bold`,e)} ${l(`dim`,t)}`).join(l(`dim`,` • `))},i18n:{disabledError:`This option is disabled and cannot be toggled.`},keybindings:[]};function Ly(e){return!$.isSeparator(e)&&!e.disabled}function Ry(e){return!$.isSeparator(e)}function zy(e){return!$.isSeparator(e)&&e.checked}function By(e){return Ly(e)?{...e,checked:!e.checked}:e}function Vy(e){return function(t){return Ly(t)?{...t,checked:e}:t}}function Hy(e){return e.map(e=>{if($.isSeparator(e))return e;if(typeof e==`string`)return{value:e,name:e,short:e,checkedName:e,disabled:!1,checked:!1};let t=e.name??String(e.value),n={value:e.value,name:t,short:e.short??t,checkedName:e.checkedName??t,disabled:e.disabled??!1,checked:e.checked??!1};return e.description&&(n.description=e.description),n})}var Uy=Fy((e,t)=>{let{pageSize:n=7,loop:r=!0,required:i,validate:a=()=>!0}=e,o={all:`a`,invert:`i`,...e.shortcuts},s=Tv(Iy,e.theme),{keybindings:c}=s,[l,u]=Q(`idle`),d=Ev({status:l,theme:s}),[f,p]=Q(Hy(e.choices)),m=Dv(()=>{let e=f.findIndex(Ry),t=f.findLastIndex(Ry);if(e===-1)throw new iv(`[checkbox prompt] No selectable choices. All choices are disabled.`);return{first:e,last:t}},[f]),[h,g]=Q(m.first),[_,v]=Q();kv(async e=>{if($_(e)){let e=f.filter(zy),n=await a([...e]);i&&!e.length?v(`At least one choice must be selected`):n===!0?(u(`done`),t(e.map(e=>e.value))):v(n||`You must select a valid value`)}else if(q_(e,c)||J_(e,c)){if(_&&v(void 0),r||q_(e,c)&&h!==m.first||J_(e,c)&&h!==m.last){let t=q_(e,c)?-1:1,n=h;do n=(n+t+f.length)%f.length;while(!Ry(f[n]));g(n)}}else if(Y_(e)){let e=f[h];e&&!$.isSeparator(e)&&(e.disabled?v(s.i18n.disabledError):(v(void 0),p(f.map((e,t)=>t===h?By(e):e))))}else if(e.name===o.all){let e=f.some(e=>Ly(e)&&!e.checked);p(f.map(Vy(e)))}else if(e.name===o.invert)p(f.map(By));else if(Q_(e)){let t=Number(e.name)-1,n=-1,r=f.findIndex(e=>$.isSeparator(e)?!1:(n++,n===t)),i=f[r];i&&Ly(i)&&(g(r),p(f.map((e,t)=>t===r?By(e):e)))}});let y=s.style.message(e.message,l),b,x=oy({items:f,active:h,renderItem({item:e,isActive:t}){if($.isSeparator(e))return` ${e.separator}`;let n=t?s.icon.cursor:` `;if(e.disabled){let t=typeof e.disabled==`string`?e.disabled:`(disabled)`,r=e.checked?s.icon.disabledChecked:s.icon.disabledUnchecked;return s.style.disabled(`${n}${r} ${e.name} ${t}`)}t&&(b=e.description);let r=e.checked?s.icon.checked:s.icon.unchecked,i=e.checked?e.checkedName:e.name;return(t?s.style.highlight:e=>e)(`${n}${r} ${i}`)},pageSize:n,loop:r});if(l===`done`){let e=f.filter(zy);return[d,y,s.style.answer(s.style.renderSelectedChoices(e,f))].filter(Boolean).join(` `)}let S=[[`↑↓`,`navigate`],[`space`,`select`]];o.all&&S.push([o.all,`all`]),o.invert&&S.push([o.invert,`invert`]),S.push([`⏎`,`submit`]);let C=s.style.keysHelpTip(S);return`${[[d,y].filter(Boolean).join(` `),x,` `,b?s.style.description(b):``,_?s.style.error(_):``,C].filter(Boolean).join(`
|
|
202
202
|
`).trimEnd()}${Sy}`});const Wy={validationFailureMode:`keep`};var Gy=Fy((e,t)=>{let{prefill:n=`tab`}=e,r=Tv(Wy,e.theme),[i,a]=Q(`idle`),[o,s]=Q(String(e.default??``)),[c,l]=Q(),[u,d]=Q(``),f=Ev({status:i,theme:r});async function p(t){let{required:n,pattern:r,patternError:i=`Invalid input`}=e;return n&&!t?`You must provide a value`:r&&!r.test(t)?i:typeof e.validate==`function`?await e.validate(t)||`You must provide a valid value`:!0}kv(async(e,n)=>{if(i===`idle`)if($_(e)){let e=u||o;a(`loading`);let i=await p(e);i===!0?(d(e),a(`done`),t(e)):(r.validationFailureMode===`clear`?d(``):n.write(u),l(i),a(`idle`))}else X_(e)&&!u?s(``):Z_(e)&&!u?(s(``),n.clearLine(0),n.write(o),d(o)):(d(n.line),l(void 0))}),mv(e=>{n===`editable`&&o&&(e.write(o),d(o))},[]);let m=r.style.message(e.message,i),h=u;typeof e.transformer==`function`?h=e.transformer(u,{isFinal:i===`done`}):i===`done`&&(h=r.style.answer(u));let g;o&&i!==`done`&&!u&&(g=r.style.defaultAnswer(o));let _=``;return c&&(_=r.style.error(c)),[[f,m,g,h].filter(e=>e!==void 0).join(` `),_]});const Ky={icon:{cursor:xv.pointer},style:{disabled:e=>l(`dim`,e),description:e=>l(`cyan`,e),keysHelpTip:e=>e.map(([e,t])=>`${l(`bold`,e)} ${l(`dim`,t)}`).join(l(`dim`,` • `))},i18n:{disabledError:`This option is disabled and cannot be selected.`},indexMode:`hidden`,keybindings:[]};function qy(e){return!$.isSeparator(e)&&!e.disabled}function Jy(e){return!$.isSeparator(e)}function Yy(e){return e.map(e=>{if($.isSeparator(e))return e;if(typeof e!=`object`||!e||!(`value`in e)){let t=String(e);return{value:e,name:t,short:t,disabled:!1}}let t=e.name??String(e.value),n={value:e.value,name:t,short:e.short??t,disabled:e.disabled??!1};return e.description&&(n.description=e.description),n})}var Xy=Fy((e,t)=>{let{loop:n=!0,pageSize:r=7}=e,i=Tv(Ky,e.theme),{keybindings:a}=i,[o,s]=Q(`idle`),c=Ev({status:o,theme:i}),l=Ov(),u=!a.includes(`vim`),d=Dv(()=>Yy(e.choices),[e.choices]),f=Dv(()=>{let e=d.findIndex(Jy),t=d.findLastIndex(Jy);if(e===-1)throw new iv(`[select prompt] No selectable choices. All choices are disabled.`);return{first:e,last:t}},[d]),p=Dv(()=>`default`in e?d.findIndex(t=>qy(t)&&t.value===e.default):-1,[e.default,d]),[m,h]=Q(p===-1?f.first:p),g=d[m],[_,v]=Q();kv((e,r)=>{if(clearTimeout(l.current),_&&v(void 0),$_(e))g.disabled?v(i.i18n.disabledError):(s(`done`),t(g.value));else if(q_(e,a)||J_(e,a)){if(r.clearLine(0),n||q_(e,a)&&m!==f.first||J_(e,a)&&m!==f.last){let t=q_(e,a)?-1:1,n=m;do n=(n+t+d.length)%d.length;while(!Jy(d[n]));h(n)}}else if(Q_(e)&&!Number.isNaN(Number(r.line))){let e=Number(r.line)-1,t=-1,n=d.findIndex(n=>$.isSeparator(n)?!1:(t++,t===e)),i=d[n];i!=null&&qy(i)&&h(n),l.current=setTimeout(()=>{r.clearLine(0)},700)}else if(X_(e))r.clearLine(0);else if(u){let e=r.line.toLowerCase(),t=d.findIndex(t=>$.isSeparator(t)||!qy(t)?!1:t.name.toLowerCase().startsWith(e));t!==-1&&h(t),l.current=setTimeout(()=>{r.clearLine(0)},700)}}),mv(()=>()=>{clearTimeout(l.current)},[]);let y=i.style.message(e.message,o),b=i.style.keysHelpTip([[`↑↓`,`navigate`],[`⏎`,`select`]]),x=0,S=oy({items:d,active:m,renderItem({item:e,isActive:t,index:n}){if($.isSeparator(e))return x++,` ${e.separator}`;let r=t?i.icon.cursor:` `,a=i.indexMode===`number`?`${n+1-x}. `:``;if(e.disabled){let n=typeof e.disabled==`string`?e.disabled:`(disabled)`,r=t?i.icon.cursor:`-`;return i.style.disabled(`${r} ${a}${e.name} ${n}`)}return(t?i.style.highlight:e=>e)(`${r} ${a}${e.name}`)},pageSize:r,loop:n});if(o===`done`)return[c,y,i.style.answer(g.short)].filter(Boolean).join(` `);let{description:C}=g;return`${[[c,y].filter(Boolean).join(` `),S,` `,C?i.style.description(C):``,_?i.style.error(_):``,b].filter(Boolean).join(`
|
|
203
|
-
`).trimEnd()}${Sy}`}),Zy=class{static async getText(e){let{message:t,schema:n,default:r}=e,i;if(n&&r!==void 0){let e=n.safeParse(r);e.success&&(i=e.data)}else !n&&r!==void 0&&(i=r);if(n&&n instanceof Af)return await Xy({message:t,choices:n.options.map(e=>({value:e})),default:i});let a=await Gy({message:t,default:i,validate:e=>{if(!n)return!0;let t=e;if(n instanceof Dd){if(e.trim()===``)return`Input cannot be empty`;let n=Number(e);if(Number.isNaN(n))return`Please enter a valid number`;t=n}let r=n.safeParse(t);return r.success?!0:r.error.issues[0]?.message??`Invalid input`}});if(!n)return a;let o=n instanceof Dd?Number(a):a;return n.parse(o)}static async choose(e){let{message:t,options:n,mode:r=`single`,default:i,includeAllOption:a=!1,required:o=!1}=e,s=`__all__`,c=r===`single`?[i]:[...i||[]],l=[...r===`multiple`&&a?[{name:`All`,value:s,checked:c.includes(s)}]:[],...n.map(e=>({name:e,value:e,checked:c.includes(e)}))];if(r===`multiple`){let e=await Uy({message:t,choices:l,validate:e=>o&&e.length===0?`You must select at least one option.`:!0});return a&&e.includes(s)?n:e}return await Xy({message:t,choices:n.map(e=>({name:e,value:e})),default:typeof i==`string`?i:void 0})}},Qy=class e{static command=new vg(`init`).argument(`[projectName]`).option(`-d, --dir <path>`,`workspace directory`).action(e.run.bind(e));static async run(e,t){let n=await H_.getPackageList(),r=n.filter(e=>e.type===`apps`&&e.packageJson?.startx?.mode!==`silent`),i=await this.getPrefs({projectName:e,options:t,projects:r}),a=n.filter(e=>e.type!==`apps`),o=await this.getConfigPrefs({selectedApps:i.selectedApps,packages:a}),s=await this.getPackagesPrefs({selectedPackages:o.selectedConfigs,packages:a,tags:o.gTags}),c=[...s.gTags,`runnable`];await this.installWorkspace({name:i.projectName,tags:[...c,`runnable`],dir:i.directory});let l=[...s.selectedPackages,...i.selectedApps];await Promise.all(l.map(async e=>{let t={},n=new Set(s.gTags);e.packageJson?.startx?.mode===`standalone`&&n.add(`runnable`),e.type===`apps`&&(n.add(`runnable`),s.selectedPackages.filter(t=>t.type!==`packages`||t.packageJson?.startx?.mode===`standalone`?!1:t.packageJson?.startx?.iTags?.every(t=>e.packageJson?.startx?.gTags?.includes(t))).forEach(e=>{let n=e.packageJson?.name||e.name;t[n]=`workspace:^`})),await this.installPackage({pkg:e,directory:i.directory,tags:Array.from(n),dependencies:t})}))}static async getPrefs(e){let n=await Zy.getText({message:`Project name`,name:`projectName`,default:e.projectName,schema:Gp.string().min(1,`Package name is required`).max(214,`Package name too long`).regex(/^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,`Invalid package name`)});if(e.projects.length===0)throw Error(`No apps found to install.`);let r=H_.getDirectory(),i=e.options.dir?t.resolve(r.workspace,e.options.dir):t.join(r.workspace,n),a=await Zy.choose({message:`Select apps to install`,options:e.projects.map(e=>e.name),includeAllOption:!0,mode:`multiple`,required:!0});return{projectName:n,directory:{workspace:i,template:r.template},selectedApps:e.projects.filter(e=>a.includes(e.name))}}static async getConfigPrefs(e){let t=new Set([`common`]),n=new Map;this.getGlobalTags({pkgs:e.selectedApps}).forEach(e=>t.add(e)),this.getPackageDeps({allPkgs:e.packages,pkgs:e.selectedApps}).forEach(e=>n.set(e.name,e));let r=e.packages.filter(e=>e.type!==`configs`||e.packageJson?.startx?.mode===`silent`||n.has(e.name)?!1:e.packageJson?.startx?.iTags?.every(e=>t.has(e))??!0);if(r.length>0){let e=await Zy.choose({message:`Select configs to install`,options:r.map(e=>e.name),includeAllOption:!0,mode:`multiple`,required:!1});r.filter(t=>e.includes(t.name)).forEach(e=>n.set(e.name,e))}return t.has(`node`)&&(await Zy.choose({message:`Select formatter`,options:[`prettier + biome`,`prettier`],mode:`single`,default:`prettier`,required:!0})===`prettier`||t.add(`biome`),t.add(`prettier`)),this.getPackageDeps({allPkgs:e.packages,pkgs:Array.from(n.values())}).forEach(e=>n.set(e.name,e)),this.getGlobalTags({pkgs:Array.from(n.values())}).forEach(e=>t.add(e)),{gTags:Array.from(t),selectedConfigs:Array.from(n.values())}}static async getPackagesPrefs(e){let t=new Set(e.tags),n=new Map(e.selectedPackages.map(e=>[e.name,e])),r=e.packages.filter(e=>e.type!==`packages`||e.packageJson?.startx?.mode===`silent`||n.has(e.name)?!1:e.packageJson?.startx?.iTags?.every(e=>t.has(e))??!1);if(r.length>0){let e=await Zy.choose({message:`Select packages to install`,options:r.map(e=>e.name),includeAllOption:!0,mode:`multiple`,required:!1});r.filter(t=>e.includes(t.name)).forEach(e=>n.set(e.name,e))}return this.getPackageDeps({allPkgs:e.packages,pkgs:Array.from(n.values())}).forEach(e=>n.set(e.name,e)),this.getGlobalTags({pkgs:Array.from(n.values())}).forEach(e=>t.add(e)),{gTags:Array.from(t),selectedPackages:Array.from(n.values())}}static async installPackage(e){if(!e.pkg.packageJson)throw Error(`Missing package.json for ${e.pkg.name}`);let n=new Set([...e.tags,...e.pkg.packageJson.startx?.tags||[]]),r=e.pkg.packageJson.startx?.ignore||[];r.includes(`eslint-config`)&&n.delete(`eslint`),r.includes(`vitest-config`)&&n.delete(`vitest`);let{packageJson:i,isWorkspace:a}=K_.handlePackageJson({app:e.pkg.packageJson,tags:Array.from(n),name:e.packageName||e.pkg.packageJson.name||e.pkg.name,dependencies:e.dependencies});if(a)throw Error(`Cannot install workspace as a package: ${e.pkg.name}`);let o=t.join(e.directory.workspace,e.pkg.relativePath),s=t.join(e.pkg.path);await z_.writeJSONFile({dir:o,file:`package`,content:i}),await this.copyValidatedFilesFromFolder(s,o,n),await z_.copyDirectory({from:t.join(s,`src`),to:t.join(o,`src`),exclude:n.has(`vitest`)?void 0:/\.test\.tsx?$/}),ig.info(`Successfully installed ${e.pkg.name}`)}static async installWorkspace(e){let t=await H_.parsePackageJson({dir:e.dir.template}),n=await H_.parsePackageJson({dir:e.dir.template,file:`startx`});if(!t)throw Error(`Failed to parse root package.json`);t.dependencies={...t.dependencies,...n?.dependencies||{}},t.devDependencies={...t.devDependencies,...n?.devDependencies||{}};let{packageJson:r}=K_.handlePackageJson({app:t,tags:[`root`,...e.tags],name:e.name});await z_.writeJSONFile({dir:e.dir.workspace,file:`package`,content:r}),await this.copyValidatedFilesFromFolder(e.dir.template,e.dir.workspace,new Set([`root`,...e.tags]))}static getPackageDeps(e){let t=new Map(e.pkgs.map(e=>[e.name,e]));return Array.from(t.values()).forEach(n=>{[...n.packageJson?.startx?.requiredDeps||[],...n.packageJson?.startx?.requiredDevDeps||[]].forEach(n=>{let r=e.allPkgs.find(e=>e.packageJson?.name===n);r&&t.set(r.name,r)})}),e.pkgs.forEach(e=>t.delete(e.name)),Array.from(t.values())}static getGlobalTags(e){let t=new Set(e.gTags||[]);return e.pkgs.forEach(e=>{e.packageJson?.startx?.gTags?.forEach(e=>t.add(e))}),Array.from(t)}static async copyValidatedFilesFromFolder(e,n,r){let i=await z_.listFiles({dir:e}).catch(()=>[]);for(let a of i){let i=B_[a];if(!(i&&!i.tags.every(e=>r.has(e))))try{await z_.copyFile({from:t.join(e,a),to:t.join(n,a)})}catch(e){ig.error(`Failed to copy file ${a}:`,e)}}}},$y=`1.0.
|
|
203
|
+
`).trimEnd()}${Sy}`}),Zy=class{static async getText(e){let{message:t,schema:n,default:r}=e,i;if(n&&r!==void 0){let e=n.safeParse(r);e.success&&(i=e.data)}else !n&&r!==void 0&&(i=r);if(n&&n instanceof Af)return await Xy({message:t,choices:n.options.map(e=>({value:e})),default:i});let a=await Gy({message:t,default:i,validate:e=>{if(!n)return!0;let t=e;if(n instanceof Dd){if(e.trim()===``)return`Input cannot be empty`;let n=Number(e);if(Number.isNaN(n))return`Please enter a valid number`;t=n}let r=n.safeParse(t);return r.success?!0:r.error.issues[0]?.message??`Invalid input`}});if(!n)return a;let o=n instanceof Dd?Number(a):a;return n.parse(o)}static async choose(e){let{message:t,options:n,mode:r=`single`,default:i,includeAllOption:a=!1,required:o=!1}=e,s=`__all__`,c=r===`single`?[i]:[...i||[]],l=[...r===`multiple`&&a?[{name:`All`,value:s,checked:c.includes(s)}]:[],...n.map(e=>({name:e,value:e,checked:c.includes(e)}))];if(r===`multiple`){let e=await Uy({message:t,choices:l,validate:e=>o&&e.length===0?`You must select at least one option.`:!0});return a&&e.includes(s)?n:e}return await Xy({message:t,choices:n.map(e=>({name:e,value:e})),default:typeof i==`string`?i:void 0})}},Qy=class e{static command=new vg(`init`).argument(`[projectName]`).option(`-d, --dir <path>`,`workspace directory`).action(e.run.bind(e));static async run(e,t){let n=await H_.getPackageList(),r=n.filter(e=>e.type===`apps`&&e.packageJson?.startx?.mode!==`silent`),i=await this.getPrefs({projectName:e,options:t,projects:r}),a=n.filter(e=>e.type!==`apps`),o=await this.getConfigPrefs({selectedApps:i.selectedApps,packages:a}),s=await this.getPackagesPrefs({selectedPackages:o.selectedConfigs,packages:a,tags:o.gTags}),c=[...s.gTags,`runnable`];await this.installWorkspace({name:i.projectName,tags:[...c,`runnable`],dir:i.directory});let l=[...s.selectedPackages,...i.selectedApps];await Promise.all(l.map(async e=>{let t={},n=new Set(s.gTags);e.packageJson?.startx?.mode===`standalone`&&n.add(`runnable`),e.type===`apps`&&(n.add(`runnable`),s.selectedPackages.filter(t=>t.type!==`packages`||t.packageJson?.startx?.mode===`standalone`?!1:t.packageJson?.startx?.iTags?.every(t=>e.packageJson?.startx?.gTags?.includes(t))).forEach(e=>{let n=e.packageJson?.name||e.name;t[n]=`workspace:^`})),await this.installPackage({pkg:e,directory:i.directory,tags:Array.from(n),dependencies:t})}))}static async getPrefs(e){let n=await Zy.getText({message:`Project name`,name:`projectName`,default:e.projectName,schema:Gp.string().min(1,`Package name is required`).max(214,`Package name too long`).regex(/^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,`Invalid package name`)});if(e.projects.length===0)throw Error(`No apps found to install.`);let r=H_.getDirectory(),i=e.options.dir?t.resolve(r.workspace,e.options.dir):t.join(r.workspace,n),a=await Zy.choose({message:`Select apps to install`,options:e.projects.map(e=>e.name),includeAllOption:!0,mode:`multiple`,required:!0});return{projectName:n,directory:{workspace:i,template:r.template},selectedApps:e.projects.filter(e=>a.includes(e.name))}}static async getConfigPrefs(e){let t=new Set([`common`]),n=new Map;this.getGlobalTags({pkgs:e.selectedApps}).forEach(e=>t.add(e)),this.getPackageDeps({allPkgs:e.packages,pkgs:e.selectedApps}).forEach(e=>n.set(e.name,e));let r=e.packages.filter(e=>e.type!==`configs`||e.packageJson?.startx?.mode===`silent`||n.has(e.name)?!1:e.packageJson?.startx?.iTags?.every(e=>t.has(e))??!0);if(r.length>0){let e=await Zy.choose({message:`Select configs to install`,options:r.map(e=>e.name),includeAllOption:!0,mode:`multiple`,required:!1});r.filter(t=>e.includes(t.name)).forEach(e=>n.set(e.name,e))}return t.has(`node`)&&(await Zy.choose({message:`Select formatter`,options:[`prettier + biome`,`prettier`],mode:`single`,default:`prettier`,required:!0})===`prettier`||t.add(`biome`),t.add(`prettier`)),this.getPackageDeps({allPkgs:e.packages,pkgs:Array.from(n.values())}).forEach(e=>n.set(e.name,e)),this.getGlobalTags({pkgs:Array.from(n.values())}).forEach(e=>t.add(e)),{gTags:Array.from(t),selectedConfigs:Array.from(n.values())}}static async getPackagesPrefs(e){let t=new Set(e.tags),n=new Map(e.selectedPackages.map(e=>[e.name,e])),r=e.packages.filter(e=>e.type!==`packages`||e.packageJson?.startx?.mode===`silent`||n.has(e.name)?!1:e.packageJson?.startx?.iTags?.every(e=>t.has(e))??!1);if(r.length>0){let e=await Zy.choose({message:`Select packages to install`,options:r.map(e=>e.name),includeAllOption:!0,mode:`multiple`,required:!1});r.filter(t=>e.includes(t.name)).forEach(e=>n.set(e.name,e))}return this.getPackageDeps({allPkgs:e.packages,pkgs:Array.from(n.values())}).forEach(e=>n.set(e.name,e)),this.getGlobalTags({pkgs:Array.from(n.values())}).forEach(e=>t.add(e)),{gTags:Array.from(t),selectedPackages:Array.from(n.values())}}static async installPackage(e){if(!e.pkg.packageJson)throw Error(`Missing package.json for ${e.pkg.name}`);let n=new Set([...e.tags,...e.pkg.packageJson.startx?.tags||[]]),r=e.pkg.packageJson.startx?.ignore||[];r.includes(`eslint-config`)&&n.delete(`eslint`),r.includes(`vitest-config`)&&n.delete(`vitest`);let{packageJson:i,isWorkspace:a}=K_.handlePackageJson({app:e.pkg.packageJson,tags:Array.from(n),name:e.packageName||e.pkg.packageJson.name||e.pkg.name,dependencies:e.dependencies});if(a)throw Error(`Cannot install workspace as a package: ${e.pkg.name}`);let o=t.join(e.directory.workspace,e.pkg.relativePath),s=t.join(e.pkg.path);await z_.writeJSONFile({dir:o,file:`package`,content:i}),await this.copyValidatedFilesFromFolder(s,o,n),await z_.copyDirectory({from:t.join(s,`src`),to:t.join(o,`src`),exclude:n.has(`vitest`)?void 0:/\.test\.tsx?$/}),ig.info(`Successfully installed ${e.pkg.name}`)}static async installWorkspace(e){let t=await H_.parsePackageJson({dir:e.dir.template}),n=await H_.parsePackageJson({dir:e.dir.template,file:`startx`});if(!t)throw Error(`Failed to parse root package.json`);t.dependencies={...t.dependencies,...n?.dependencies||{}},t.devDependencies={...t.devDependencies,...n?.devDependencies||{}};let{packageJson:r}=K_.handlePackageJson({app:t,tags:[`root`,...e.tags],name:e.name});await z_.writeJSONFile({dir:e.dir.workspace,file:`package`,content:r}),await this.copyValidatedFilesFromFolder(e.dir.template,e.dir.workspace,new Set([`root`,...e.tags]))}static getPackageDeps(e){let t=new Map(e.pkgs.map(e=>[e.name,e]));return Array.from(t.values()).forEach(n=>{[...n.packageJson?.startx?.requiredDeps||[],...n.packageJson?.startx?.requiredDevDeps||[]].forEach(n=>{let r=e.allPkgs.find(e=>e.packageJson?.name===n);r&&t.set(r.name,r)})}),e.pkgs.forEach(e=>t.delete(e.name)),Array.from(t.values())}static getGlobalTags(e){let t=new Set(e.gTags||[]);return e.pkgs.forEach(e=>{e.packageJson?.startx?.gTags?.forEach(e=>t.add(e))}),Array.from(t)}static async copyValidatedFilesFromFolder(e,n,r){let i=await z_.listFiles({dir:e}).catch(()=>[]);for(let a of i){let i=B_[a];if(!(i&&!i.tags.every(e=>r.has(e))))try{await z_.copyFile({from:t.join(e,a),to:t.join(n,a)})}catch(e){ig.error(`Failed to copy file ${a}:`,e)}}}},$y=`1.0.2`;const eb=new vg;eb.name(`startx`).description(`StartX CLI - Your all in one monorepo startup tool.`).version($y),eb.command(`ping`).action(()=>{ig.info(`pong`)}),eb.addCommand(Qy.command),eb.parse(process.argv);export{};
|
package/package.json
CHANGED
package/pnpm-workspace.yaml
CHANGED
|
@@ -37,8 +37,8 @@ catalog:
|
|
|
37
37
|
react-dom: ^19.2.4
|
|
38
38
|
lucide-react: ^0.563.0
|
|
39
39
|
tailwindcss: ^4.1.18
|
|
40
|
-
react-email: ^5.2.
|
|
41
|
-
"@react-email/preview-server": ^5.2.
|
|
40
|
+
react-email: ^5.2.11
|
|
41
|
+
"@react-email/preview-server": ^5.2.11
|
|
42
42
|
"@react-email/components": ^1.0.8
|
|
43
43
|
"@react-email/tailwind": ^2.0.5
|
|
44
44
|
"@react-email/render": ^2.0.4
|