startx 1.0.4 → 1.0.5
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.
- package/_gitignore +40 -0
- package/apps/startx-cli/dist/index.mjs +1 -1
- package/apps/startx-cli/src/commands/init.ts +2 -1
- package/apps/web-client/react-router.config.ts +1 -0
- package/package.json +1 -1
- /package/apps/web-client/{app → src}/app.css +0 -0
- /package/apps/web-client/{app → src}/components.json +0 -0
- /package/apps/web-client/{app → src}/config/auth/auth-state.ts +0 -0
- /package/apps/web-client/{app → src}/config/axios-client.ts +0 -0
- /package/apps/web-client/{app → src}/config/env.ts +0 -0
- /package/apps/web-client/{app → src}/entry.client.tsx +0 -0
- /package/apps/web-client/{app → src}/eslint.config.ts +0 -0
- /package/apps/web-client/{app → src}/root.tsx +0 -0
- /package/apps/web-client/{app → src}/routes/home.tsx +0 -0
- /package/apps/web-client/{app → src}/routes.ts +0 -0
package/_gitignore
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
|
2
|
+
|
|
3
|
+
# Dependencies
|
|
4
|
+
node_modules
|
|
5
|
+
.pnp
|
|
6
|
+
.pnp.js
|
|
7
|
+
|
|
8
|
+
# Local env files
|
|
9
|
+
.env
|
|
10
|
+
.env.local
|
|
11
|
+
.env.development.local
|
|
12
|
+
.env.test.local
|
|
13
|
+
.env.production.local
|
|
14
|
+
|
|
15
|
+
# Testing
|
|
16
|
+
coverage
|
|
17
|
+
|
|
18
|
+
# Turbo
|
|
19
|
+
.turbo
|
|
20
|
+
|
|
21
|
+
# Vercel
|
|
22
|
+
.vercel
|
|
23
|
+
|
|
24
|
+
# Build Outputs
|
|
25
|
+
.next/
|
|
26
|
+
out/
|
|
27
|
+
build
|
|
28
|
+
dist
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# Debug
|
|
32
|
+
npm-debug.log*
|
|
33
|
+
yarn-debug.log*
|
|
34
|
+
yarn-error.log*
|
|
35
|
+
logs
|
|
36
|
+
|
|
37
|
+
# Misc
|
|
38
|
+
.DS_Store
|
|
39
|
+
*.pem
|
|
40
|
+
temp
|
|
@@ -215,4 +215,4 @@ $&`).replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g,`$1$2`).replace(/\
|
|
|
215
215
|
`+t:``),o=Math.floor(n.length/i)-this.cursorPos.rows+(t?Sx(t):0);o>0&&(a+=_x(o)),a+=yx(this.cursorPos.cols),this.write(vx(this.extraLinesUnderPrompt)+xx(this.height)+a),this.extraLinesUnderPrompt=o,this.height=Sx(a)}checkCursorPos(){let e=this.rl.getCursorPos();e.cols!==this.cursorPos.cols&&(this.write(yx(e.cols)),this.cursorPos=e)}done({clearContent:e}){this.rl.setPrompt(``);let t=vx(this.extraLinesUnderPrompt);t+=e?xx(this.height):`
|
|
216
216
|
`,t+=`\x1B[?25h`,this.write(t),this.rl.close()}},Tx=class extends Promise{static withResolver(){let e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),resolve:e,reject:t}}},Ex=b(tx(),1);const Dx=globalThis.setImmediate;function Ox(){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 kx(e){let t=Ox();return(n,r={})=>{let{input:i=process.stdin,signal:a}=r,o=new Set,c=new Ex.default;c.pipe(r.output??process.stdout),c.mute();let l=u.createInterface({terminal:!0,input:i,output:c}),d=new wx(l),{promise:f,resolve:p,reject:m}=Tx.withResolver(),h=()=>m(new Jy);if(a){let e=()=>m(new qy({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(px((e,t)=>{m(new Yy(`User force closed the prompt with ${e} ${t}`))}));let g=()=>m(new Yy(`User force closed the prompt with SIGINT`));return l.on(`SIGINT`,g),o.add(()=>l.removeListener(`SIGINT`,g)),eb(l,a=>{let u=s.bind(()=>ob.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),ob.run()}catch(e){m(e)}})};return`readableFlowing`in i?Dx(g):g(),Object.assign(f.then(e=>(ob.clearAll(),e),e=>{throw ob.clearAll(),e}).finally(()=>{o.forEach(e=>e()),d.done({clearContent:!!r.clearPromptOnDone}),c.end()}).then(()=>f),{cancel:h})})}}var Ax=class{separator=l(`dim`,Array.from({length:15}).join(hb.line));type=`separator`;constructor(e){e&&(this.separator=e)}static isSeparator(e){return!!(e&&typeof e==`object`&&`type`in e&&e.type===`separator`)}};const jx={icon:{checked:l(`green`,hb.circleFilled),unchecked:hb.circle,cursor:hb.pointer,disabledChecked:l(`green`,hb.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 Mx(e){return!Ax.isSeparator(e)&&!e.disabled}function Nx(e){return!Ax.isSeparator(e)}function Px(e){return!Ax.isSeparator(e)&&e.checked}function Fx(e){return Mx(e)?{...e,checked:!e.checked}:e}function Ix(e){return function(t){return Mx(t)?{...t,checked:e}:t}}function Lx(e){return e.map(e=>{if(Ax.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 Rx=kx((e,t)=>{let{pageSize:n=7,loop:r=!0,required:i,validate:a=()=>!0}=e,o={all:`a`,invert:`i`,...e.shortcuts},s=yb(jx,e.theme),{keybindings:c}=s,[l,u]=sb(`idle`),d=bb({status:l,theme:s}),[f,p]=sb(Lx(e.choices)),m=xb(()=>{let e=f.findIndex(Nx),t=f.findLastIndex(Nx);if(e===-1)throw new Zy(`[checkbox prompt] No selectable choices. All choices are disabled.`);return{first:e,last:t}},[f]),[h,g]=sb(m.first),[_,v]=sb();Cb(async e=>{if(Ky(e)){let e=f.filter(Px),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(By(e,c)||Vy(e,c)){if(_&&v(void 0),r||By(e,c)&&h!==m.first||Vy(e,c)&&h!==m.last){let t=By(e,c)?-1:1,n=h;do n=(n+t+f.length)%f.length;while(!Nx(f[n]));g(n)}}else if(Hy(e)){let e=f[h];e&&!Ax.isSeparator(e)&&(e.disabled?v(s.i18n.disabledError):(v(void 0),p(f.map((e,t)=>t===h?Fx(e):e))))}else if(e.name===o.all){let e=f.some(e=>Mx(e)&&!e.checked);p(f.map(Ix(e)))}else if(e.name===o.invert)p(f.map(Fx));else if(Gy(e)){let t=Number(e.name)-1,n=-1,r=f.findIndex(e=>Ax.isSeparator(e)?!1:(n++,n===t)),i=f[r];i&&Mx(i)&&(g(r),p(f.map((e,t)=>t===r?Fx(e):e)))}});let y=s.style.message(e.message,l),b,x=ex({items:f,active:h,renderItem({item:e,isActive:t}){if(Ax.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(Px);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(`
|
|
217
217
|
`).trimEnd()}${gx}`});function zx(e,t){let n=t!==!1;return/^(y|yes)/i.test(e)?n=!0:/^(n|no)/i.test(e)&&(n=!1),n}function Bx(e){return e?`Yes`:`No`}var Vx=kx((e,t)=>{let{transformer:n=Bx}=e,[r,i]=sb(`idle`),[a,o]=sb(``),s=yb(e.theme),c=bb({status:r,theme:s});Cb((s,c)=>{if(r===`idle`)if(Ky(s)){let r=zx(a,e.default);o(n(r)),i(`done`),t(r)}else if(Wy(s)){let t=Bx(!zx(a,e.default));c.clearLine(0),c.write(t),o(t)}else o(c.line)});let l=a,u=``;return r===`done`?l=s.style.answer(a):u=` ${s.style.defaultAnswer(e.default===!1?`y/N`:`Y/n`)}`,`${c} ${s.style.message(e.message,r)}${u} ${l}`});const Hx={validationFailureMode:`keep`};var Ux=kx((e,t)=>{let{prefill:n=`tab`}=e,r=yb(Hx,e.theme),[i,a]=sb(`idle`),[o,s]=sb(String(e.default??``)),[c,l]=sb(),[u,d]=sb(``),f=bb({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}Cb(async(e,n)=>{if(i===`idle`)if(Ky(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 Uy(e)&&!u?s(``):Wy(e)&&!u?(s(``),n.clearLine(0),n.write(o),d(o)):(d(n.line),l(void 0))}),cb(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 Wx={icon:{cursor:hb.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 Gx(e){return!Ax.isSeparator(e)&&!e.disabled}function Kx(e){return!Ax.isSeparator(e)}function qx(e){return e.map(e=>{if(Ax.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 Jx=kx((e,t)=>{let{loop:n=!0,pageSize:r=7}=e,i=yb(Wx,e.theme),{keybindings:a}=i,[o,s]=sb(`idle`),c=bb({status:o,theme:i}),l=Sb(),u=!a.includes(`vim`),d=xb(()=>qx(e.choices),[e.choices]),f=xb(()=>{let e=d.findIndex(Kx),t=d.findLastIndex(Kx);if(e===-1)throw new Zy(`[select prompt] No selectable choices. All choices are disabled.`);return{first:e,last:t}},[d]),p=xb(()=>`default`in e?d.findIndex(t=>Gx(t)&&t.value===e.default):-1,[e.default,d]),[m,h]=sb(p===-1?f.first:p),g=d[m],[_,v]=sb();Cb((e,r)=>{if(clearTimeout(l.current),_&&v(void 0),Ky(e))g.disabled?v(i.i18n.disabledError):(s(`done`),t(g.value));else if(By(e,a)||Vy(e,a)){if(r.clearLine(0),n||By(e,a)&&m!==f.first||Vy(e,a)&&m!==f.last){let t=By(e,a)?-1:1,n=m;do n=(n+t+d.length)%d.length;while(!Kx(d[n]));h(n)}}else if(Gy(e)&&!Number.isNaN(Number(r.line))){let e=Number(r.line)-1,t=-1,n=d.findIndex(n=>Ax.isSeparator(n)?!1:(t++,t===e)),i=d[n];i!=null&&Gx(i)&&h(n),l.current=setTimeout(()=>{r.clearLine(0)},700)}else if(Uy(e))r.clearLine(0);else if(u){let e=r.line.toLowerCase(),t=d.findIndex(t=>Ax.isSeparator(t)||!Gx(t)?!1:t.name.toLowerCase().startsWith(e));t!==-1&&h(t),l.current=setTimeout(()=>{r.clearLine(0)},700)}}),cb(()=>()=>{clearTimeout(l.current)},[]);let y=i.style.message(e.message,o),b=i.style.keysHelpTip([[`↑↓`,`navigate`],[`⏎`,`select`]]),x=0,S=ex({items:d,active:m,renderItem({item:e,isActive:t,index:n}){if(Ax.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(`
|
|
218
|
-
`).trimEnd()}${gx}`}),Yx=class{static async confirm(e){return await Vx({message:e.message,default:e.default})}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 wf)return await Jx({message:t,choices:n.options.map(e=>({value:e})),default:i});let a=await Ux({message:t,default:i,validate:e=>{if(!n)return!0;let t=e;if(n instanceof xd){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 xd?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 Rx({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 Jx({message:t,choices:n.map(e=>({name:e,value:e})),default:typeof i==`string`?i:void 0})}},Xx=class e{static command=new uv(`init`).argument(`[projectName]`).option(`-d, --dir <path>`,`workspace directory`).action(e.run.bind(e));static async run(e,t){let n=await Fy.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 Yx.getText({message:`Project name`,name:`projectName`,default:e.projectName,schema:Bp.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=Fy.getDirectory(),i=e.options.dir?t.resolve(r.workspace,e.options.dir):t.join(r.workspace,n),a=await Yx.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 Yx.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 Yx.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 Yx.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}=zy.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 My.writeJSONFile({dir:o,file:`package`,content:i}),await this.copyValidatedFilesFromFolder(s,o,n),await My.copyDirectory({from:t.join(s,`src`),to:t.join(o,`src`),exclude:n.has(`vitest`)?void 0:/\.test\.tsx?$/}),X_.info(`Successfully installed ${e.pkg.name}`)}static async installWorkspace(e){let t=await Fy.parsePackageJson({dir:e.dir.template}),n=await Fy.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}=zy.handlePackageJson({app:t,tags:[`root`,...e.tags],name:e.name});await My.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 My.listFiles({dir:e}).catch(()=>[]);for(let a of i){let i=Ny[a];if(
|
|
218
|
+
`).trimEnd()}${gx}`}),Yx=class{static async confirm(e){return await Vx({message:e.message,default:e.default})}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 wf)return await Jx({message:t,choices:n.options.map(e=>({value:e})),default:i});let a=await Ux({message:t,default:i,validate:e=>{if(!n)return!0;let t=e;if(n instanceof xd){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 xd?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 Rx({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 Jx({message:t,choices:n.map(e=>({name:e,value:e})),default:typeof i==`string`?i:void 0})}},Xx=class e{static command=new uv(`init`).argument(`[projectName]`).option(`-d, --dir <path>`,`workspace directory`).action(e.run.bind(e));static async run(e,t){let n=await Fy.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 Yx.getText({message:`Project name`,name:`projectName`,default:e.projectName,schema:Bp.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=Fy.getDirectory(),i=e.options.dir?t.resolve(r.workspace,e.options.dir):t.join(r.workspace,n),a=await Yx.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 Yx.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 Yx.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 Yx.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}=zy.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 My.writeJSONFile({dir:o,file:`package`,content:i}),await this.copyValidatedFilesFromFolder(s,o,n),await My.copyDirectory({from:t.join(s,`src`),to:t.join(o,`src`),exclude:n.has(`vitest`)?void 0:/\.test\.tsx?$/}),X_.info(`Successfully installed ${e.pkg.name}`)}static async installWorkspace(e){let t=await Fy.parsePackageJson({dir:e.dir.template}),n=await Fy.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}=zy.handlePackageJson({app:t,tags:[`root`,...e.tags],name:e.name});await My.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 My.listFiles({dir:e}).catch(()=>[]);for(let a of i){let i=Ny[a];if(i&&!i.tags.every(e=>r.has(e)))continue;let o=a===`_gitignore`?`.gitignore`:a;try{await My.copyFile({from:t.join(e,a),to:t.join(n,o)})}catch(e){X_.error(`Failed to copy file ${a}:`,e)}}}},Zx=`1.0.5`;const Qx=new uv;Qx.name(`startx`).description(`StartX CLI - Your all in one monorepo startup tool.`).version(Zx),Qx.command(`ping`).action(()=>{X_.info(`pong`)}),Qx.addCommand(Xx.command),Qx.parse(process.argv);export{};
|
|
@@ -329,10 +329,11 @@ export class InitCommand {
|
|
|
329
329
|
for (const file of files) {
|
|
330
330
|
const checked = FileCheck[file];
|
|
331
331
|
if (checked && !checked.tags.every(tag => tags.has(tag))) continue;
|
|
332
|
+
const destFileName = file === "_gitignore" ? ".gitignore" : file;
|
|
332
333
|
try {
|
|
333
334
|
await fsTool.copyFile({
|
|
334
335
|
from: path.join(source, file),
|
|
335
|
-
to: path.join(destination,
|
|
336
|
+
to: path.join(destination, destFileName),
|
|
336
337
|
});
|
|
337
338
|
} catch (error) {
|
|
338
339
|
logger.error(`Failed to copy file ${file}:`, error);
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|