@fnet/cli 0.128.5 → 0.129.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.
- package/dist/fbin/index.js +1 -1
- package/dist/fnet/index.C0YpfQ5j.js +1 -0
- package/dist/fnet/index.DkEl8VOr.js +1 -0
- package/dist/fnet/index.js +1 -1
- package/dist/fnode/{index.DBxLarjt.js → index.BTXKZRR5.js} +1 -1
- package/dist/fnode/index.Bi6l2DjU.js +1 -0
- package/dist/fnode/index.BrgASaOV.js +1 -0
- package/dist/fnode/index.N_a5FdgA.js +1 -0
- package/dist/fnode/index.UNoFg95r.js +1 -0
- package/dist/fnode/{index.De_RsTV6.js → index.e2SSlEgE.js} +1 -1
- package/dist/fnode/index.js +1 -1
- package/dist/fservice/index.js +1 -1
- package/package.json +1 -1
- package/template/fnet/node/package.json.njk +7 -7
- package/template/fnet/node/rollup.config.mjs.njk +4 -2
- package/template/fnode/bun/package.json.njk +57 -42
- package/template/fnode/node/package.json.njk +61 -48
- package/template/fnode/node/rollup.config.mjs.njk +4 -2
- package/dist/fnet/index.Bx5WAeSz.js +0 -1
- package/dist/fnet/index.DaKCw83b.js +0 -1
- package/dist/fnode/index.B_0ZxySP.js +0 -1
- package/dist/fnode/index.Bf4wwB0L.js +0 -1
- package/dist/fnode/index.BtvzsBtE.js +0 -1
- package/dist/fnode/index.xPP3GBoc.js +0 -1
package/dist/fbin/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import e from"node:path";import{fileURLToPath as o}from"node:url";import t from"chalk";import n from"yargs";import{hideBin as s}from"yargs/helpers";import l from"node:fs";import r from"node:os";import i from"@fnet/prompt";import a from"cli-table3";import{promisify as c}from"node:util";import m from"tree-kill";function d(){return e.join(r.homedir(),".fnet","bin")}function h(){return e.join(r.homedir(),".fnet","metadata")}function u(){return e.join(h(),"binaries.json")}function f(){try{if("win32"===process.platform)return process.env.PSModulePath&&process.env.PSModulePath.includes("PowerShell")?"powershell-core":process.env.PSModulePath?"powershell":"cmd";const o=process.env.SHELL||"";return o.includes("bash")?"bash":o.includes("zsh")?"zsh":o.includes("fish")?"fish":o.includes("ksh")?"ksh":o.includes("csh")||o.includes("tcsh")?"csh":l.existsSync(e.join(r.homedir(),".bashrc"))?"bash":l.existsSync(e.join(r.homedir(),".zshrc"))?"zsh":l.existsSync(e.join(r.homedir(),".config","fish","config.fish"))?"fish":"unknown"}catch(e){return"unknown"}}function p(o){const t=r.homedir(),n=[];switch(o){case"bash":n.push({name:".bashrc",path:e.join(t,".bashrc")}),n.push({name:".bash_profile",path:e.join(t,".bash_profile")}),n.push({name:".profile",path:e.join(t,".profile")});break;case"zsh":n.push({name:".zshrc",path:e.join(t,".zshrc")}),n.push({name:".zprofile",path:e.join(t,".zprofile")});break;case"fish":n.push({name:"config.fish",path:e.join(t,".config","fish","config.fish")});break;case"ksh":n.push({name:".kshrc",path:e.join(t,".kshrc")}),n.push({name:".profile",path:e.join(t,".profile")});break;case"csh":n.push({name:".cshrc",path:e.join(t,".cshrc")}),n.push({name:".tcshrc",path:e.join(t,".tcshrc")});break;case"powershell":n.push({name:"Microsoft.PowerShell_profile.ps1",path:e.join(t,"Documents","WindowsPowerShell","Microsoft.PowerShell_profile.ps1")}),n.push({name:"profile.ps1",path:e.join(t,"Documents","WindowsPowerShell","profile.ps1")});break;case"powershell-core":n.push({name:"Microsoft.PowerShell_profile.ps1",path:e.join(t,"Documents","PowerShell","Microsoft.PowerShell_profile.ps1")}),n.push({name:"profile.ps1",path:e.join(t,"Documents","PowerShell","profile.ps1")});break;case"cmd":n.push({name:"fnet-path.bat",path:e.join(t,"fnet-path.bat")})}return n}function y(e,o){switch(e){case"bash":case"zsh":case"ksh":default:return`export PATH="${o}:$PATH"`;case"fish":return`set -gx PATH ${o} $PATH`;case"csh":return`setenv PATH ${o}:$PATH`;case"powershell":case"powershell-core":return`$env:PATH = "${o};" + $env:PATH`;case"cmd":return`@echo off\nSETX PATH "%PATH%;${o}"\necho Path updated successfully`}}var g={getBinDirectory:d,getMetadataDirectory:h,getMetadataFilePath:u,checkIfInPath:function(o){return(process.env.PATH||"").split(e.delimiter).includes(o)},detectUserShell:f,getShellConfigPath:function(){const e=p(f());for(const o of e)if(l.existsSync(o.path))return o.path;return e.length>0?e[0].path:null},getAllShellConfigPaths:p,createBinDirectoryStructure:async function(){const e=d(),o=h(),t=u();l.existsSync(e)||l.mkdirSync(e,{recursive:!0}),l.existsSync(o)||l.mkdirSync(o,{recursive:!0}),l.existsSync(t)||l.writeFileSync(t,JSON.stringify({binaries:{},lastUpdated:(new Date).toISOString()},null,2))},getExportPathCommand:y,addBinToPath:async function(o,n,s){try{const r=y(o,s);if("cmd"===o)return l.writeFileSync(n,r),console.log(t.yellow(`Created batch file at ${n}`)),console.log(t.yellow("Run this file to add the bin directory to your PATH")),!0;if("powershell"!==o&&"powershell-core"!==o||l.existsSync(e.dirname(n))||l.mkdirSync(e.dirname(n),{recursive:!0}),!l.existsSync(n)){const e="fish"===o?"# Fish shell configuration\n\n":"powershell"===o||"powershell-core"===o?"# PowerShell profile\n\n":"# Shell configuration\n\n";l.writeFileSync(n,e),console.log(t.green(`Created config file at ${n}`))}const i=l.readFileSync(n,"utf8");if(i.includes(s))return!0;const a=`${i.trim()}\n\n# Added by @fnet/cli\n${r}\n`;return l.writeFileSync(n,a),"powershell"!==o&&"powershell-core"!==o||(console.log(t.yellow("You may need to set the PowerShell execution policy to run scripts:")),console.log(t.green("Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned"))),!0}catch(e){return console.error(t.red(`Failed to add bin directory to PATH: ${e.message}`)),!1}}};async function w(o){const t=function(){const o=r.homedir(),t=e.join(o,".fnet","bin");return l.existsSync(t)||l.mkdirSync(t,{recursive:!0}),t}(),n=function(){const o=r.homedir(),t=e.join(o,".fnet");return l.existsSync(t)||l.mkdirSync(t,{recursive:!0}),e.join(t,"bin-registry.json")}();let s={};if(l.existsSync(n))try{const e=l.readFileSync(n,"utf8");s=JSON.parse(e)}catch(e){console.warn(`Warning: Could not parse bin registry: ${e.message}`)}return{binDir:t,registryPath:n,registry:s,args:o}}e.dirname(o(import.meta.url));var b={command:"setup",describe:"Initialize the bin system",builder:{},handler:async o=>{try{await w(o);console.log(t.blue("Setting up the bin system...")),await g.createBinDirectoryStructure();const n=g.getBinDirectory();console.log(t.green(`Bin directory: ${n}`));if(g.checkIfInPath(n))console.log(t.green("Bin directory is already in PATH."));else{console.log(t.yellow("Bin directory is not in PATH."));const{confirmAddToPath:o}=await i({type:"confirm",name:"confirmAddToPath",message:`Would you like to add ${n} to your PATH?`,initial:!0});if(o){let o=g.detectUserShell();if("unknown"===o){const{selectedShell:e}=await i({type:"select",name:"selectedShell",message:"Select your shell:",choices:[{name:"bash",message:"Bash"},{name:"zsh",message:"Zsh"},{name:"fish",message:"Fish"},{name:"powershell",message:"PowerShell"},{name:"powershell-core",message:"PowerShell Core"},{name:"cmd",message:"Windows Command Prompt"},{name:"ksh",message:"Korn Shell (ksh)"},{name:"csh",message:"C Shell (csh/tcsh)"}]});o=e}else{const{confirmShell:e}=await i({type:"confirm",name:"confirmShell",message:`Detected shell: ${o}. Is this correct?`,initial:!0});if(!e){const{selectedShell:e}=await i({type:"select",name:"selectedShell",message:"Select your shell:",choices:[{name:"bash",message:"Bash"},{name:"zsh",message:"Zsh"},{name:"fish",message:"Fish"},{name:"powershell",message:"PowerShell"},{name:"powershell-core",message:"PowerShell Core"},{name:"cmd",message:"Windows Command Prompt"},{name:"ksh",message:"Korn Shell (ksh)"},{name:"csh",message:"C Shell (csh/tcsh)"}]});o=e}}const s=g.getAllShellConfigPaths(o);let a;if(s.length>1){const e=s.filter((e=>l.existsSync(e.path)));if(e.length>0){const{selectedConfigPath:o}=await i({type:"select",name:"selectedConfigPath",message:"Select the configuration file to modify:",choices:e.map((e=>({name:e.path,message:`${e.name} (${e.path})`})))});a=o}else{const{selectedConfigPath:e}=await i({type:"select",name:"selectedConfigPath",message:"Select the configuration file to create:",choices:s.map((e=>({name:e.path,message:`${e.name} (${e.path})`})))});a=e}}else if(1===s.length)a=s[0].path;else{const{enteredConfigPath:o}=await i({type:"input",name:"enteredConfigPath",message:"Enter the path to your shell configuration file:",initial:e.join(r.homedir(),".bashrc")});a=o}await g.addBinToPath(o,a,n)?(console.log(t.green(`Added bin directory to PATH in ${a}`)),console.log(t.yellow("Please restart your terminal or run the following command:")),console.log(t.green(`source ${a}`))):(console.log(t.red(`Failed to add bin directory to PATH in ${a}`)),console.log(t.yellow("You can add it manually by adding the following line to your shell configuration:")),console.log(t.green(g.getExportPathCommand(o,n))))}else console.log(t.yellow("You can add it manually by adding the following line to your shell configuration:")),console.log(t.green(`export PATH="${n}:$PATH"`)),console.log(t.yellow("Or run:")),console.log(t.green("fbin path"))}console.log(t.green("Bin system setup completed successfully."))}catch(e){console.error(t.red(`Failed to set up bin system: ${e.message}`)),process.exit(1)}}};var S={command:"path",describe:"Add bin directory to PATH",builder:{yes:{describe:"Automatically answer yes to all prompts",type:"boolean",default:!1,alias:"y"}},handler:async o=>{try{await w(o);const n=g.getBinDirectory();console.log(t.blue(`Adding ${n} to PATH...`)),g.createBinDirectoryStructure()||(console.log(t.yellow("Creating bin directory structure...")),await g.createBinDirectoryStructure());if(g.checkIfInPath(n))return void console.log(t.green("Bin directory is already in PATH."));let s=g.detectUserShell();if("unknown"===s)if(o.yes)s="win32"===process.platform?"powershell":"bash",console.log(t.yellow(`Auto-selecting ${s} shell due to --yes flag`));else{const{selectedShell:e}=await i({type:"select",name:"selectedShell",message:"Select your shell:",choices:[{name:"bash",message:"Bash"},{name:"zsh",message:"Zsh"},{name:"fish",message:"Fish"},{name:"powershell",message:"PowerShell"},{name:"powershell-core",message:"PowerShell Core"},{name:"cmd",message:"Windows Command Prompt"},{name:"ksh",message:"Korn Shell (ksh)"},{name:"csh",message:"C Shell (csh/tcsh)"}]});s=e}else if(o.yes)console.log(t.yellow(`Auto-confirming detected shell: ${s} due to --yes flag`));else{const{confirmShell:e}=await i({type:"confirm",name:"confirmShell",message:`Detected shell: ${s}. Is this correct?`,initial:!0});if(!e){const{selectedShell:e}=await i({type:"select",name:"selectedShell",message:"Select your shell:",choices:[{name:"bash",message:"Bash"},{name:"zsh",message:"Zsh"},{name:"fish",message:"Fish"},{name:"powershell",message:"PowerShell"},{name:"powershell-core",message:"PowerShell Core"},{name:"cmd",message:"Windows Command Prompt"},{name:"ksh",message:"Korn Shell (ksh)"},{name:"csh",message:"C Shell (csh/tcsh)"}]});s=e}}const a=g.getAllShellConfigPaths(s);let c;if(a.length>1){const e=a.filter((e=>l.existsSync(e.path)));if(e.length>0)if(o.yes)c=e[0].path,console.log(t.yellow(`Auto-selecting config file: ${c} due to --yes flag`));else{const{selectedConfigPath:o}=await i({type:"select",name:"selectedConfigPath",message:"Select the configuration file to modify:",choices:e.map((e=>({name:e.path,message:`${e.name} (${e.path})`})))});c=o}else if(o.yes)c=a[0].path,console.log(t.yellow(`Auto-selecting config file to create: ${c} due to --yes flag`));else{const{selectedConfigPath:e}=await i({type:"select",name:"selectedConfigPath",message:"Select the configuration file to create:",choices:a.map((e=>({name:e.path,message:`${e.name} (${e.path})`})))});c=e}}else if(1===a.length)c=a[0].path;else if(o.yes)c=e.join(r.homedir(),"win32"===process.platform?"_profile":".bashrc"),console.log(t.yellow(`Auto-selecting default config file: ${c} due to --yes flag`));else{const{enteredConfigPath:o}=await i({type:"input",name:"enteredConfigPath",message:"Enter the path to your shell configuration file:",initial:e.join(r.homedir(),".bashrc")});c=o}await g.addBinToPath(s,c,n)?(console.log(t.green(`Added bin directory to PATH in ${c}`)),console.log(t.yellow("Please restart your terminal or run the following command:")),console.log(t.green(`source ${c}`))):(console.log(t.red(`Failed to add bin directory to PATH in ${c}`)),console.log(t.yellow("You can add it manually by adding the following line to your shell configuration:")),console.log(t.green(g.getExportPathCommand(s,n))))}catch(e){console.error(t.red(`Failed to add bin directory to PATH: ${e.message}`)),process.exit(1)}}};var P={command:"compile [source] [options]",describe:"Compile a CLI project to a binary",builder:{source:{describe:"Source file to compile",type:"string",default:"./dist/cli/esm/index.js"},output:{describe:"Output file name",type:"string",alias:"o"},name:{describe:"Binary name",type:"string",alias:"n"},force:{describe:"Force overwrite if binary already exists",type:"boolean",default:!1,alias:"f"},target:{describe:"Target platform (auto, linux, macos, windows)",type:"string",choices:["auto","linux","macos","windows"],default:"auto"},minify:{describe:"Minify the output binary",type:"boolean",default:!0},external:{describe:"External packages to exclude from the bundle (comma-separated)",type:"string"}},handler:async o=>{try{await w(o);const n=process.cwd(),s=e.basename(n),r=o.name||s;let a;if(o.output)a=o.output;else{const o=e.join(n,".bin");l.existsSync(o)||l.mkdirSync(o,{recursive:!0}),a=e.join(o,r)}const c=e.resolve(process.cwd(),o.source);if(l.existsSync(c)||(console.error(t.red(`Source file not found: ${c}`)),console.error(t.yellow("Make sure to build your project first.")),process.exit(1)),l.existsSync(a)&&!o.force){const{confirmOverwrite:e}=await i({type:"confirm",name:"confirmOverwrite",message:`Binary already exists at ${a}. Overwrite?`,initial:!1});if(!e)return void console.log(t.yellow("Compilation cancelled."))}const m=process.platform;console.log(t.blue(`Detected platform: ${m}`)),"win32"!==m||a.endsWith(".exe")||(a=`${a}.exe`,console.log(t.blue(`Adjusted output path for Windows: ${a}`))),console.log(t.blue(`Compiling ${c} to ${a}...`));const{spawn:d}=await import("child_process");try{const e=d("bun",["--version"],{stdio:"pipe"});await new Promise(((o,t)=>{e.on("close",(e=>{0===e?o():t(new Error("Bun is not available. Please install Bun first."))})),e.on("error",(e=>{t(new Error(`Bun is not available: ${e.message}`))}))}))}catch(e){console.error(t.red(`Bun is not available: ${e.message}`)),console.error(t.yellow("Please install Bun first: https://bun.sh/")),process.exit(1)}const h=["build",c,"--compile",`--outfile=${a}`];if(o.target&&"auto"!==o.target&&h.push(`--target=${o.target}`),!1===o.minify&&h.push("--no-minify"),o.external){o.external.split(",").map((e=>e.trim())).forEach((e=>{h.push(`--external:${e}`)}))}console.log(t.blue(`Running: bun ${h.join(" ")}`));const u=d("bun",h,{stdio:"inherit"});await new Promise(((e,o)=>{u.on("close",(t=>{0===t?e():o(new Error(`Compilation failed with code ${t}`))})),u.on("error",(e=>{o(e)}))})),"win32"!==m&&l.chmodSync(a,493),console.log(t.green(`Binary compiled successfully: ${a}`)),"win32"===m?console.log(t.yellow("Note: On Windows, you may need to run the binary from a command prompt or PowerShell.")):"darwin"===m&&console.log(t.yellow("Note: On macOS, you may need to allow the binary to run in System Preferences > Security & Privacy."))}catch(e){console.error(t.red(`Failed to compile binary: ${e.message}`)),process.exit(1)}}};var $={command:"install [source] [options]",describe:"Install a binary to the bin directory",builder:{source:{describe:"Source binary to install",type:"string",demandOption:!0},name:{describe:"Name to use for the installed binary",type:"string",alias:"n"},force:{describe:"Force overwrite if binary already exists",type:"boolean",default:!1,alias:"f"},yes:{describe:"Automatically answer yes to all prompts",type:"boolean",default:!1,alias:"y"}},handler:async o=>{try{await w(o);const n=e.resolve(process.cwd(),o.source);l.existsSync(n)||(console.error(t.red(`Source file not found: ${n}`)),process.exit(1)),await g.createBinDirectoryStructure();const s=g.getBinDirectory();let r;r=o.name?o.name:e.basename(n),"win32"!==process.platform||r.endsWith(".exe")||(r=`${r}.exe`);const a=e.join(s,r);if(l.existsSync(a)&&!o.force&&!o.yes){const{confirmOverwrite:e}=await i({type:"confirm",name:"confirmOverwrite",message:`Binary already exists at ${a}. Overwrite?`,initial:!1});if(!e)return void console.log(t.yellow("Installation cancelled."))}console.log(t.blue(`Installing ${n} to ${a}...`)),l.copyFileSync(n,a),"win32"!==process.platform&&l.chmodSync(a,493);const c=g.getMetadataFilePath();let m={binaries:{},lastUpdated:(new Date).toISOString()};if(l.existsSync(c))try{m=JSON.parse(l.readFileSync(c,"utf8"))}catch(e){console.warn(t.yellow(`Failed to parse metadata file: ${e.message}`)),console.warn(t.yellow("Creating new metadata file."))}let d="0.0.0";try{const{execSync:e}=require("child_process"),o=e(`"${a}" --version`,{timeout:5e3,stdio:["ignore","pipe","ignore"]}).toString().trim(),n=o.match(/v?(\d+\.\d+\.\d+)/);n?(d=n[1],console.log(t.blue(`Detected binary version: ${d}`))):(console.log(t.yellow(`Could not parse version from output: ${o}`)),console.log(t.yellow(`Using default version: ${d}`)))}catch(e){console.log(t.yellow(`Could not detect binary version, using default: ${d}`))}m.binaries[r]={path:a,source:n,created:(new Date).toISOString(),platform:process.platform,version:d,project:e.basename(process.cwd())},m.lastUpdated=(new Date).toISOString(),l.writeFileSync(c,JSON.stringify(m,null,2)),console.log(t.green(`Binary installed successfully: ${a}`));g.checkIfInPath(s)?console.log(t.green(`You can now run '${r}' from anywhere.`)):console.log(t.yellow("Bin directory is not in PATH. Run 'fbin path' to add it."))}catch(e){console.error(t.red(`Failed to install binary: ${e.message}`)),process.exit(1)}}};var x={promptForSelection:async function(e){const{items:o,message:n,nameField:s="name",valueField:l="name",initialValue:r=null,allowAbort:a=!0}=e;if(!o||0===o.length)return console.log(t.yellow("No items available for selection.")),null;if(1===o.length&&!a){const e=o[0],n="string"==typeof e?e:e[l];return console.log(t.blue(`Only one option available: ${"string"==typeof e?e:e[s]}`)),n}let c=o.map((e=>"string"==typeof e?{name:e,value:e,message:e}:{name:e[l],value:e[l],message:e[s]||e[l]}));a&&c.push({name:"cancel",value:null,message:t.yellow("Cancel")});let m=null;if(r){const e=c.findIndex((e=>e.name===r));-1!==e&&(m=e)}const d="selectedItem",{[d]:h}=await i({type:"select",name:d,message:n,choices:c,initial:m});return"cancel"===h?null:h},promptForMultipleSelection:async function(e){const{items:o,message:n,nameField:s="name",valueField:l="name",initialValues:r=[],allowAbort:a=!0}=e;if(!o||0===o.length)return console.log(t.yellow("No items available for selection.")),null;let c=o.map((e=>"string"==typeof e?{name:e,value:e,message:e}:{name:e[l],value:e[l],message:e[s]||e[l]})),m=[];r&&r.length>0&&(m=c.map(((e,o)=>r.includes(e.name)?o:-1)).filter((e=>-1!==e)));const d="selectedItems",h=await i({type:"multiselect",name:d,message:n,choices:c,initial:m,hint:"(Use space to select, enter to confirm)",validate:e=>!(0===e.length&&!a)||"Please select at least one item"});return a&&0===h[d].length?null:h[d]}};var v={command:"uninstall [name] [options]",describe:"Uninstall a binary from the bin directory",builder:{name:{describe:"Name of the binary to uninstall",type:"string",demandOption:!1},force:{describe:"Skip confirmation prompt",type:"boolean",default:!1,alias:"f"},yes:{describe:"Automatically answer yes to all prompts",type:"boolean",default:!1,alias:"y"}},handler:async e=>{try{await w(e);const o=g.getBinDirectory(),n=g.getMetadataFilePath();let s;l.existsSync(o)||(console.error(t.red(`Bin directory not found: ${o}`)),console.error(t.yellow("Run fbin setup first.")),process.exit(1)),l.existsSync(n)||(console.error(t.red(`Metadata file not found: ${n}`)),console.error(t.yellow("Run fbin setup first.")),process.exit(1));try{s=JSON.parse(l.readFileSync(n,"utf8"))}catch(e){console.error(t.red(`Failed to parse metadata file: ${e.message}`)),process.exit(1)}if(!e.name&&!e.yes){const o=Object.keys(s.binaries);if(0===o.length)return void console.log(t.yellow("No binaries installed."));const n=await x.promptForSelection({items:o,message:"Select a binary to uninstall:",allowAbort:!0});if(null===n)return void console.log(t.yellow("Uninstallation cancelled."));e.name=n}const r=e.name;r||(console.error(t.red("Binary name is required.")),console.error(t.yellow("Use --name to specify a binary or run without --yes to select interactively.")),process.exit(1)),s.binaries[r]||(console.error(t.red(`Binary not found in metadata: ${r}`)),console.log(t.yellow("Use fbin list to see installed binaries.")),process.exit(1));const a=s.binaries[r].path;if(l.existsSync(a)||(console.warn(t.yellow(`Binary file not found: ${a}`)),console.warn(t.yellow("Metadata will be updated anyway."))),!e.force&&!e.yes){const{confirmUninstall:e}=await i({type:"confirm",name:"confirmUninstall",message:`Are you sure you want to uninstall ${r}?`,initial:!1});if(!e)return void console.log(t.yellow("Uninstallation cancelled."))}if(l.existsSync(a))try{l.unlinkSync(a),console.log(t.green(`Binary file removed: ${a}`))}catch(e){console.error(t.red(`Failed to remove binary file: ${e.message}`))}delete s.binaries[r],s.lastUpdated=(new Date).toISOString(),l.writeFileSync(n,JSON.stringify(s,null,2)),console.log(t.green(`Binary uninstalled successfully: ${r}`))}catch(e){console.error(t.red(`Failed to uninstall binary: ${e.message}`)),process.exit(1)}}};function A(e,o={}){const n={chars:{top:"─","top-mid":"─","top-left":" ","top-right":" ",bottom:"─","bottom-mid":"─","bottom-left":" ","bottom-right":" ",left:" ","left-mid":" ",mid:"─","mid-mid":"─",right:" ","right-mid":" ",middle:" "},style:{head:[],border:[],compact:!0},wordWrap:!0,...o,head:e.map((e=>t.bold(e)))};return new a(n)}var C={createTable:A,createTableWithData:function(e,o,t={}){const n=A(e,t);return Array.isArray(o)&&o.forEach((e=>{n.push(e)})),n.toString()},getStatusColor:function(e){switch(e){case"running":return t.green;case"stopped":return t.yellow;case"failed":return t.red;case"registered":return t.blue;default:return t.gray}}};var F={command:"list [options]",describe:"List installed binaries",builder:{json:{describe:"Output in JSON format",type:"boolean",default:!1,alias:"j"},filter:{describe:"Filter binaries by name",type:"string",alias:"f"}},handler:async e=>{try{await w(e);const o=g.getBinDirectory(),n=g.getMetadataFilePath();let s;l.existsSync(o)||(console.error(t.red(`Bin directory not found: ${o}`)),console.error(t.yellow("Run fbin setup first.")),process.exit(1)),l.existsSync(n)||(console.error(t.red(`Metadata file not found: ${n}`)),console.error(t.yellow("Run fbin setup first.")),process.exit(1));try{s=JSON.parse(l.readFileSync(n,"utf8"))}catch(e){console.error(t.red(`Failed to parse metadata file: ${e.message}`)),process.exit(1)}let r=s.binaries;if(e.filter){const o=e.filter.toLowerCase();r=Object.entries(r).filter((([e])=>e.toLowerCase().includes(o))).reduce(((e,[o,t])=>(e[o]=t,e)),{})}if(e.json)return void console.log(JSON.stringify(r,null,2));const i=Object.keys(r).length;if(0===i)return void console.log(t.yellow("No binaries installed."));console.log(t.blue(`Found ${i} installed binaries:`)),console.log();const a=["NAME","VERSION","PLATFORM","CREATED"],c=C.createTable(a,{chars:{mid:"","mid-mid":"","left-mid":"","right-mid":""}});Object.entries(r).forEach((([e,o])=>{const n=new Date(o.created).toLocaleString();c.push([t.white(e),o.version||"N/A",o.platform||"N/A",n])})),console.log(c.toString()),console.log(),console.log(t.blue(`Bin directory: ${o}`));g.checkIfInPath(o)||console.log(t.yellow("Bin directory is not in PATH. Run 'fbin path' to add it."))}catch(e){console.error(t.red(`Failed to list binaries: ${e.message}`)),process.exit(1)}}};c(m);let j=!1;process.on("uncaughtException",(e=>{j||(j=!0,setTimeout((()=>process.exit(1)),500))})),process.on("unhandledRejection",(e=>{j||(j=!0,setTimeout((()=>process.exit(1)),500))})),async function(){try{n(s(process.argv)).usage("Usage: $0 <command> [options]").command(b).command(S).command(P).command($).command(v).command(F).demandCommand(1,"You need to specify a command").help().version().argv}catch(e){console.error(t.red(`Fatal error: ${e.message}`)),process.exit(1)}}().catch((e=>{console.error(t.red(`Fatal error: ${e.message}`)),process.exit(1)}));
|
|
2
|
+
import e from"chalk";import o from"yargs";import{hideBin as t}from"yargs/helpers";import n from"node:path";import s from"node:fs";import l from"node:os";import r from"@fnet/prompt";import{fileURLToPath as i}from"node:url";import a from"cli-table3";import{promisify as c}from"node:util";import m from"tree-kill";function d(){return n.join(l.homedir(),".fnet","bin")}function h(){return n.join(l.homedir(),".fnet","metadata")}function u(){return n.join(h(),"binaries.json")}function f(){try{if("win32"===process.platform)return process.env.PSModulePath&&process.env.PSModulePath.includes("PowerShell")?"powershell-core":process.env.PSModulePath?"powershell":"cmd";const e=process.env.SHELL||"";return e.includes("bash")?"bash":e.includes("zsh")?"zsh":e.includes("fish")?"fish":e.includes("ksh")?"ksh":e.includes("csh")||e.includes("tcsh")?"csh":s.existsSync(n.join(l.homedir(),".bashrc"))?"bash":s.existsSync(n.join(l.homedir(),".zshrc"))?"zsh":s.existsSync(n.join(l.homedir(),".config","fish","config.fish"))?"fish":"unknown"}catch(e){return"unknown"}}function p(e){const o=l.homedir(),t=[];switch(e){case"bash":t.push({name:".bashrc",path:n.join(o,".bashrc")}),t.push({name:".bash_profile",path:n.join(o,".bash_profile")}),t.push({name:".profile",path:n.join(o,".profile")});break;case"zsh":t.push({name:".zshrc",path:n.join(o,".zshrc")}),t.push({name:".zprofile",path:n.join(o,".zprofile")});break;case"fish":t.push({name:"config.fish",path:n.join(o,".config","fish","config.fish")});break;case"ksh":t.push({name:".kshrc",path:n.join(o,".kshrc")}),t.push({name:".profile",path:n.join(o,".profile")});break;case"csh":t.push({name:".cshrc",path:n.join(o,".cshrc")}),t.push({name:".tcshrc",path:n.join(o,".tcshrc")});break;case"powershell":t.push({name:"Microsoft.PowerShell_profile.ps1",path:n.join(o,"Documents","WindowsPowerShell","Microsoft.PowerShell_profile.ps1")}),t.push({name:"profile.ps1",path:n.join(o,"Documents","WindowsPowerShell","profile.ps1")});break;case"powershell-core":t.push({name:"Microsoft.PowerShell_profile.ps1",path:n.join(o,"Documents","PowerShell","Microsoft.PowerShell_profile.ps1")}),t.push({name:"profile.ps1",path:n.join(o,"Documents","PowerShell","profile.ps1")});break;case"cmd":t.push({name:"fnet-path.bat",path:n.join(o,"fnet-path.bat")})}return t}function y(e,o){switch(e){case"bash":case"zsh":case"ksh":default:return`export PATH="${o}:$PATH"`;case"fish":return`set -gx PATH ${o} $PATH`;case"csh":return`setenv PATH ${o}:$PATH`;case"powershell":case"powershell-core":return`$env:PATH = "${o};" + $env:PATH`;case"cmd":return`@echo off\nSETX PATH "%PATH%;${o}"\necho Path updated successfully`}}var g={getBinDirectory:d,getMetadataDirectory:h,getMetadataFilePath:u,checkIfInPath:function(e){return(process.env.PATH||"").split(n.delimiter).includes(e)},detectUserShell:f,getShellConfigPath:function(){const e=p(f());for(const o of e)if(s.existsSync(o.path))return o.path;return e.length>0?e[0].path:null},getAllShellConfigPaths:p,createBinDirectoryStructure:async function(){const e=d(),o=h(),t=u();s.existsSync(e)||s.mkdirSync(e,{recursive:!0}),s.existsSync(o)||s.mkdirSync(o,{recursive:!0}),s.existsSync(t)||s.writeFileSync(t,JSON.stringify({binaries:{},lastUpdated:(new Date).toISOString()},null,2))},getExportPathCommand:y,addBinToPath:async function(o,t,l){try{const r=y(o,l);if("cmd"===o)return s.writeFileSync(t,r),console.log(e.yellow(`Created batch file at ${t}`)),console.log(e.yellow("Run this file to add the bin directory to your PATH")),!0;if("powershell"!==o&&"powershell-core"!==o||s.existsSync(n.dirname(t))||s.mkdirSync(n.dirname(t),{recursive:!0}),!s.existsSync(t)){const n="fish"===o?"# Fish shell configuration\n\n":"powershell"===o||"powershell-core"===o?"# PowerShell profile\n\n":"# Shell configuration\n\n";s.writeFileSync(t,n),console.log(e.green(`Created config file at ${t}`))}const i=s.readFileSync(t,"utf8");if(i.includes(l))return!0;const a=`${i.trim()}\n\n# Added by @fnet/cli\n${r}\n`;return s.writeFileSync(t,a),"powershell"!==o&&"powershell-core"!==o||(console.log(e.yellow("You may need to set the PowerShell execution policy to run scripts:")),console.log(e.green("Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned"))),!0}catch(o){return console.error(e.red(`Failed to add bin directory to PATH: ${o.message}`)),!1}}};async function w(e){const o=function(){const e=l.homedir(),o=n.join(e,".fnet","bin");return s.existsSync(o)||s.mkdirSync(o,{recursive:!0}),o}(),t=function(){const e=l.homedir(),o=n.join(e,".fnet");return s.existsSync(o)||s.mkdirSync(o,{recursive:!0}),n.join(o,"bin-registry.json")}();let r={};if(s.existsSync(t))try{const e=s.readFileSync(t,"utf8");r=JSON.parse(e)}catch(e){console.warn(`Warning: Could not parse bin registry: ${e.message}`)}return{binDir:o,registryPath:t,registry:r,args:e}}n.dirname(i(import.meta.url));var b={command:"setup",describe:"Initialize the bin system",builder:{},handler:async o=>{try{await w(o);console.log(e.blue("Setting up the bin system...")),await g.createBinDirectoryStructure();const t=g.getBinDirectory();console.log(e.green(`Bin directory: ${t}`));if(g.checkIfInPath(t))console.log(e.green("Bin directory is already in PATH."));else{console.log(e.yellow("Bin directory is not in PATH."));const{confirmAddToPath:o}=await r({type:"confirm",name:"confirmAddToPath",message:`Would you like to add ${t} to your PATH?`,initial:!0});if(o){let o=g.detectUserShell();if("unknown"===o){const{selectedShell:e}=await r({type:"select",name:"selectedShell",message:"Select your shell:",choices:[{name:"bash",message:"Bash"},{name:"zsh",message:"Zsh"},{name:"fish",message:"Fish"},{name:"powershell",message:"PowerShell"},{name:"powershell-core",message:"PowerShell Core"},{name:"cmd",message:"Windows Command Prompt"},{name:"ksh",message:"Korn Shell (ksh)"},{name:"csh",message:"C Shell (csh/tcsh)"}]});o=e}else{const{confirmShell:e}=await r({type:"confirm",name:"confirmShell",message:`Detected shell: ${o}. Is this correct?`,initial:!0});if(!e){const{selectedShell:e}=await r({type:"select",name:"selectedShell",message:"Select your shell:",choices:[{name:"bash",message:"Bash"},{name:"zsh",message:"Zsh"},{name:"fish",message:"Fish"},{name:"powershell",message:"PowerShell"},{name:"powershell-core",message:"PowerShell Core"},{name:"cmd",message:"Windows Command Prompt"},{name:"ksh",message:"Korn Shell (ksh)"},{name:"csh",message:"C Shell (csh/tcsh)"}]});o=e}}const i=g.getAllShellConfigPaths(o);let a;if(i.length>1){const e=i.filter((e=>s.existsSync(e.path)));if(e.length>0){const{selectedConfigPath:o}=await r({type:"select",name:"selectedConfigPath",message:"Select the configuration file to modify:",choices:e.map((e=>({name:e.path,message:`${e.name} (${e.path})`})))});a=o}else{const{selectedConfigPath:e}=await r({type:"select",name:"selectedConfigPath",message:"Select the configuration file to create:",choices:i.map((e=>({name:e.path,message:`${e.name} (${e.path})`})))});a=e}}else if(1===i.length)a=i[0].path;else{const{enteredConfigPath:e}=await r({type:"input",name:"enteredConfigPath",message:"Enter the path to your shell configuration file:",initial:n.join(l.homedir(),".bashrc")});a=e}await g.addBinToPath(o,a,t)?(console.log(e.green(`Added bin directory to PATH in ${a}`)),console.log(e.yellow("Please restart your terminal or run the following command:")),console.log(e.green(`source ${a}`))):(console.log(e.red(`Failed to add bin directory to PATH in ${a}`)),console.log(e.yellow("You can add it manually by adding the following line to your shell configuration:")),console.log(e.green(g.getExportPathCommand(o,t))))}else console.log(e.yellow("You can add it manually by adding the following line to your shell configuration:")),console.log(e.green(`export PATH="${t}:$PATH"`)),console.log(e.yellow("Or run:")),console.log(e.green("fbin path"))}console.log(e.green("Bin system setup completed successfully."))}catch(o){console.error(e.red(`Failed to set up bin system: ${o.message}`)),process.exit(1)}}};var S={command:"path",describe:"Add bin directory to PATH",builder:{yes:{describe:"Automatically answer yes to all prompts",type:"boolean",default:!1,alias:"y"}},handler:async o=>{try{await w(o);const t=g.getBinDirectory();console.log(e.blue(`Adding ${t} to PATH...`)),g.createBinDirectoryStructure()||(console.log(e.yellow("Creating bin directory structure...")),await g.createBinDirectoryStructure());if(g.checkIfInPath(t))return void console.log(e.green("Bin directory is already in PATH."));let i=g.detectUserShell();if("unknown"===i)if(o.yes)i="win32"===process.platform?"powershell":"bash",console.log(e.yellow(`Auto-selecting ${i} shell due to --yes flag`));else{const{selectedShell:e}=await r({type:"select",name:"selectedShell",message:"Select your shell:",choices:[{name:"bash",message:"Bash"},{name:"zsh",message:"Zsh"},{name:"fish",message:"Fish"},{name:"powershell",message:"PowerShell"},{name:"powershell-core",message:"PowerShell Core"},{name:"cmd",message:"Windows Command Prompt"},{name:"ksh",message:"Korn Shell (ksh)"},{name:"csh",message:"C Shell (csh/tcsh)"}]});i=e}else if(o.yes)console.log(e.yellow(`Auto-confirming detected shell: ${i} due to --yes flag`));else{const{confirmShell:e}=await r({type:"confirm",name:"confirmShell",message:`Detected shell: ${i}. Is this correct?`,initial:!0});if(!e){const{selectedShell:e}=await r({type:"select",name:"selectedShell",message:"Select your shell:",choices:[{name:"bash",message:"Bash"},{name:"zsh",message:"Zsh"},{name:"fish",message:"Fish"},{name:"powershell",message:"PowerShell"},{name:"powershell-core",message:"PowerShell Core"},{name:"cmd",message:"Windows Command Prompt"},{name:"ksh",message:"Korn Shell (ksh)"},{name:"csh",message:"C Shell (csh/tcsh)"}]});i=e}}const a=g.getAllShellConfigPaths(i);let c;if(a.length>1){const t=a.filter((e=>s.existsSync(e.path)));if(t.length>0)if(o.yes)c=t[0].path,console.log(e.yellow(`Auto-selecting config file: ${c} due to --yes flag`));else{const{selectedConfigPath:e}=await r({type:"select",name:"selectedConfigPath",message:"Select the configuration file to modify:",choices:t.map((e=>({name:e.path,message:`${e.name} (${e.path})`})))});c=e}else if(o.yes)c=a[0].path,console.log(e.yellow(`Auto-selecting config file to create: ${c} due to --yes flag`));else{const{selectedConfigPath:e}=await r({type:"select",name:"selectedConfigPath",message:"Select the configuration file to create:",choices:a.map((e=>({name:e.path,message:`${e.name} (${e.path})`})))});c=e}}else if(1===a.length)c=a[0].path;else if(o.yes)c=n.join(l.homedir(),"win32"===process.platform?"_profile":".bashrc"),console.log(e.yellow(`Auto-selecting default config file: ${c} due to --yes flag`));else{const{enteredConfigPath:e}=await r({type:"input",name:"enteredConfigPath",message:"Enter the path to your shell configuration file:",initial:n.join(l.homedir(),".bashrc")});c=e}await g.addBinToPath(i,c,t)?(console.log(e.green(`Added bin directory to PATH in ${c}`)),console.log(e.yellow("Please restart your terminal or run the following command:")),console.log(e.green(`source ${c}`))):(console.log(e.red(`Failed to add bin directory to PATH in ${c}`)),console.log(e.yellow("You can add it manually by adding the following line to your shell configuration:")),console.log(e.green(g.getExportPathCommand(i,t))))}catch(o){console.error(e.red(`Failed to add bin directory to PATH: ${o.message}`)),process.exit(1)}}};var P={command:"compile [source] [options]",describe:"Compile a CLI project to a binary",builder:{source:{describe:"Source file to compile",type:"string",default:"./dist/cli/esm/index.js"},output:{describe:"Output file name",type:"string",alias:"o"},name:{describe:"Binary name",type:"string",alias:"n"},force:{describe:"Force overwrite if binary already exists",type:"boolean",default:!1,alias:"f"},target:{describe:"Target platform (auto, linux, macos, windows)",type:"string",choices:["auto","linux","macos","windows"],default:"auto"},minify:{describe:"Minify the output binary",type:"boolean",default:!0},external:{describe:"External packages to exclude from the bundle (comma-separated)",type:"string"}},handler:async o=>{try{await w(o);const t=process.cwd(),l=n.basename(t),i=o.name||l;let a;if(o.output)a=o.output;else{const e=n.join(t,".bin");s.existsSync(e)||s.mkdirSync(e,{recursive:!0}),a=n.join(e,i)}const c=n.resolve(process.cwd(),o.source);if(s.existsSync(c)||(console.error(e.red(`Source file not found: ${c}`)),console.error(e.yellow("Make sure to build your project first.")),process.exit(1)),s.existsSync(a)&&!o.force){const{confirmOverwrite:o}=await r({type:"confirm",name:"confirmOverwrite",message:`Binary already exists at ${a}. Overwrite?`,initial:!1});if(!o)return void console.log(e.yellow("Compilation cancelled."))}const m=process.platform;console.log(e.blue(`Detected platform: ${m}`)),"win32"!==m||a.endsWith(".exe")||(a=`${a}.exe`,console.log(e.blue(`Adjusted output path for Windows: ${a}`))),console.log(e.blue(`Compiling ${c} to ${a}...`));const{spawn:d}=await import("child_process");try{const e=d("bun",["--version"],{stdio:"pipe"});await new Promise(((o,t)=>{e.on("close",(e=>{0===e?o():t(new Error("Bun is not available. Please install Bun first."))})),e.on("error",(e=>{t(new Error(`Bun is not available: ${e.message}`))}))}))}catch(o){console.error(e.red(`Bun is not available: ${o.message}`)),console.error(e.yellow("Please install Bun first: https://bun.sh/")),process.exit(1)}const h=["build",c,"--compile",`--outfile=${a}`];if(o.target&&"auto"!==o.target&&h.push(`--target=${o.target}`),!1===o.minify&&h.push("--no-minify"),o.external){o.external.split(",").map((e=>e.trim())).forEach((e=>{h.push(`--external:${e}`)}))}console.log(e.blue(`Running: bun ${h.join(" ")}`));const u=d("bun",h,{stdio:"inherit"});await new Promise(((e,o)=>{u.on("close",(t=>{0===t?e():o(new Error(`Compilation failed with code ${t}`))})),u.on("error",(e=>{o(e)}))})),"win32"!==m&&s.chmodSync(a,493),console.log(e.green(`Binary compiled successfully: ${a}`)),"win32"===m?console.log(e.yellow("Note: On Windows, you may need to run the binary from a command prompt or PowerShell.")):"darwin"===m&&console.log(e.yellow("Note: On macOS, you may need to allow the binary to run in System Preferences > Security & Privacy."))}catch(o){console.error(e.red(`Failed to compile binary: ${o.message}`)),process.exit(1)}}};var $={command:"install [source] [options]",describe:"Install a binary to the bin directory",builder:{source:{describe:"Source binary to install",type:"string",demandOption:!0},name:{describe:"Name to use for the installed binary",type:"string",alias:"n"},force:{describe:"Force overwrite if binary already exists",type:"boolean",default:!1,alias:"f"},yes:{describe:"Automatically answer yes to all prompts",type:"boolean",default:!1,alias:"y"}},handler:async o=>{try{await w(o);const t=n.resolve(process.cwd(),o.source);s.existsSync(t)||(console.error(e.red(`Source file not found: ${t}`)),process.exit(1)),await g.createBinDirectoryStructure();const l=g.getBinDirectory();let i;i=o.name?o.name:n.basename(t),"win32"!==process.platform||i.endsWith(".exe")||(i=`${i}.exe`);const a=n.join(l,i);if(s.existsSync(a)&&!o.force&&!o.yes){const{confirmOverwrite:o}=await r({type:"confirm",name:"confirmOverwrite",message:`Binary already exists at ${a}. Overwrite?`,initial:!1});if(!o)return void console.log(e.yellow("Installation cancelled."))}console.log(e.blue(`Installing ${t} to ${a}...`)),s.copyFileSync(t,a),"win32"!==process.platform&&s.chmodSync(a,493);const c=g.getMetadataFilePath();let m={binaries:{},lastUpdated:(new Date).toISOString()};if(s.existsSync(c))try{m=JSON.parse(s.readFileSync(c,"utf8"))}catch(o){console.warn(e.yellow(`Failed to parse metadata file: ${o.message}`)),console.warn(e.yellow("Creating new metadata file."))}let d="0.0.0";try{const{execSync:o}=require("child_process"),t=o(`"${a}" --version`,{timeout:5e3,stdio:["ignore","pipe","ignore"]}).toString().trim(),n=t.match(/v?(\d+\.\d+\.\d+)/);n?(d=n[1],console.log(e.blue(`Detected binary version: ${d}`))):(console.log(e.yellow(`Could not parse version from output: ${t}`)),console.log(e.yellow(`Using default version: ${d}`)))}catch(o){console.log(e.yellow(`Could not detect binary version, using default: ${d}`))}m.binaries[i]={path:a,source:t,created:(new Date).toISOString(),platform:process.platform,version:d,project:n.basename(process.cwd())},m.lastUpdated=(new Date).toISOString(),s.writeFileSync(c,JSON.stringify(m,null,2)),console.log(e.green(`Binary installed successfully: ${a}`));g.checkIfInPath(l)?console.log(e.green(`You can now run '${i}' from anywhere.`)):console.log(e.yellow("Bin directory is not in PATH. Run 'fbin path' to add it."))}catch(o){console.error(e.red(`Failed to install binary: ${o.message}`)),process.exit(1)}}};var x={promptForSelection:async function(o){const{items:t,message:n,nameField:s="name",valueField:l="name",initialValue:i=null,allowAbort:a=!0}=o;if(!t||0===t.length)return console.log(e.yellow("No items available for selection.")),null;if(1===t.length&&!a){const o=t[0],n="string"==typeof o?o:o[l];return console.log(e.blue(`Only one option available: ${"string"==typeof o?o:o[s]}`)),n}let c=t.map((e=>"string"==typeof e?{name:e,value:e,message:e}:{name:e[l],value:e[l],message:e[s]||e[l]}));a&&c.push({name:"cancel",value:null,message:e.yellow("Cancel")});let m=null;if(i){const e=c.findIndex((e=>e.name===i));-1!==e&&(m=e)}const d="selectedItem",{[d]:h}=await r({type:"select",name:d,message:n,choices:c,initial:m});return"cancel"===h?null:h},promptForMultipleSelection:async function(o){const{items:t,message:n,nameField:s="name",valueField:l="name",initialValues:i=[],allowAbort:a=!0}=o;if(!t||0===t.length)return console.log(e.yellow("No items available for selection.")),null;let c=t.map((e=>"string"==typeof e?{name:e,value:e,message:e}:{name:e[l],value:e[l],message:e[s]||e[l]})),m=[];i&&i.length>0&&(m=c.map(((e,o)=>i.includes(e.name)?o:-1)).filter((e=>-1!==e)));const d="selectedItems",h=await r({type:"multiselect",name:d,message:n,choices:c,initial:m,hint:"(Use space to select, enter to confirm)",validate:e=>!(0===e.length&&!a)||"Please select at least one item"});return a&&0===h[d].length?null:h[d]}};var v={command:"uninstall [name] [options]",describe:"Uninstall a binary from the bin directory",builder:{name:{describe:"Name of the binary to uninstall",type:"string",demandOption:!1},force:{describe:"Skip confirmation prompt",type:"boolean",default:!1,alias:"f"},yes:{describe:"Automatically answer yes to all prompts",type:"boolean",default:!1,alias:"y"}},handler:async o=>{try{await w(o);const t=g.getBinDirectory(),n=g.getMetadataFilePath();let l;s.existsSync(t)||(console.error(e.red(`Bin directory not found: ${t}`)),console.error(e.yellow("Run fbin setup first.")),process.exit(1)),s.existsSync(n)||(console.error(e.red(`Metadata file not found: ${n}`)),console.error(e.yellow("Run fbin setup first.")),process.exit(1));try{l=JSON.parse(s.readFileSync(n,"utf8"))}catch(o){console.error(e.red(`Failed to parse metadata file: ${o.message}`)),process.exit(1)}if(!o.name&&!o.yes){const t=Object.keys(l.binaries);if(0===t.length)return void console.log(e.yellow("No binaries installed."));const n=await x.promptForSelection({items:t,message:"Select a binary to uninstall:",allowAbort:!0});if(null===n)return void console.log(e.yellow("Uninstallation cancelled."));o.name=n}const i=o.name;i||(console.error(e.red("Binary name is required.")),console.error(e.yellow("Use --name to specify a binary or run without --yes to select interactively.")),process.exit(1)),l.binaries[i]||(console.error(e.red(`Binary not found in metadata: ${i}`)),console.log(e.yellow("Use fbin list to see installed binaries.")),process.exit(1));const a=l.binaries[i].path;if(s.existsSync(a)||(console.warn(e.yellow(`Binary file not found: ${a}`)),console.warn(e.yellow("Metadata will be updated anyway."))),!o.force&&!o.yes){const{confirmUninstall:o}=await r({type:"confirm",name:"confirmUninstall",message:`Are you sure you want to uninstall ${i}?`,initial:!1});if(!o)return void console.log(e.yellow("Uninstallation cancelled."))}if(s.existsSync(a))try{s.unlinkSync(a),console.log(e.green(`Binary file removed: ${a}`))}catch(o){console.error(e.red(`Failed to remove binary file: ${o.message}`))}delete l.binaries[i],l.lastUpdated=(new Date).toISOString(),s.writeFileSync(n,JSON.stringify(l,null,2)),console.log(e.green(`Binary uninstalled successfully: ${i}`))}catch(o){console.error(e.red(`Failed to uninstall binary: ${o.message}`)),process.exit(1)}}};function A(o,t={}){const n={chars:{top:"─","top-mid":"─","top-left":" ","top-right":" ",bottom:"─","bottom-mid":"─","bottom-left":" ","bottom-right":" ",left:" ","left-mid":" ",mid:"─","mid-mid":"─",right:" ","right-mid":" ",middle:" "},style:{head:[],border:[],compact:!0},wordWrap:!0,...t,head:o.map((o=>e.bold(o)))};return new a(n)}var C={createTable:A,createTableWithData:function(e,o,t={}){const n=A(e,t);return Array.isArray(o)&&o.forEach((e=>{n.push(e)})),n.toString()},getStatusColor:function(o){switch(o){case"running":return e.green;case"stopped":return e.yellow;case"failed":return e.red;case"registered":return e.blue;default:return e.gray}}};var F={command:"list [options]",describe:"List installed binaries",builder:{json:{describe:"Output in JSON format",type:"boolean",default:!1,alias:"j"},filter:{describe:"Filter binaries by name",type:"string",alias:"f"}},handler:async o=>{try{await w(o);const t=g.getBinDirectory(),n=g.getMetadataFilePath();let l;s.existsSync(t)||(console.error(e.red(`Bin directory not found: ${t}`)),console.error(e.yellow("Run fbin setup first.")),process.exit(1)),s.existsSync(n)||(console.error(e.red(`Metadata file not found: ${n}`)),console.error(e.yellow("Run fbin setup first.")),process.exit(1));try{l=JSON.parse(s.readFileSync(n,"utf8"))}catch(o){console.error(e.red(`Failed to parse metadata file: ${o.message}`)),process.exit(1)}let r=l.binaries;if(o.filter){const e=o.filter.toLowerCase();r=Object.entries(r).filter((([o])=>o.toLowerCase().includes(e))).reduce(((e,[o,t])=>(e[o]=t,e)),{})}if(o.json)return void console.log(JSON.stringify(r,null,2));const i=Object.keys(r).length;if(0===i)return void console.log(e.yellow("No binaries installed."));console.log(e.blue(`Found ${i} installed binaries:`)),console.log();const a=["NAME","VERSION","PLATFORM","CREATED"],c=C.createTable(a,{chars:{mid:"","mid-mid":"","left-mid":"","right-mid":""}});Object.entries(r).forEach((([o,t])=>{const n=new Date(t.created).toLocaleString();c.push([e.white(o),t.version||"N/A",t.platform||"N/A",n])})),console.log(c.toString()),console.log(),console.log(e.blue(`Bin directory: ${t}`));g.checkIfInPath(t)||console.log(e.yellow("Bin directory is not in PATH. Run 'fbin path' to add it."))}catch(o){console.error(e.red(`Failed to list binaries: ${o.message}`)),process.exit(1)}}};c(m);let j=!1;process.on("uncaughtException",(e=>{j||(j=!0,setTimeout((()=>process.exit(1)),500))})),process.on("unhandledRejection",(e=>{j||(j=!0,setTimeout((()=>process.exit(1)),500))})),async function(){try{o(t(process.argv)).usage("Usage: $0 <command> [options]").command(b).command(S).command(P).command($).command(v).command(F).demandCommand(1,"You need to specify a command").help().version().argv}catch(o){console.error(e.red(`Fatal error: ${o.message}`)),process.exit(1)}}().catch((o=>{console.error(e.red(`Fatal error: ${o.message}`)),process.exit(1)}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from"node:fs";import t from"node:path";import r from"semver";import o from"@fnet/shelljs";import i from"@fnet/config";import n from"@fnet/object-from-schema";import s from"yaml";import{r as p,w as m}from"./index.js";import{fileURLToPath as a}from"node:url";import"yargs";import"chalk";import"node:util";import"tree-kill";import"node:child_process";import"node:os";import"@flownet/lib-render-templates-dir";import"@fnet/yaml";import"nunjucks";import"lodash.clonedeep";import"isobject";import"redis";import"@flownet/lib-is-redis-online";import"node:crypto";import"@flownet/lib-atom-api-js";import"lodash.merge";import"@flownet/lib-parse-imports-js";import"@fnet/npm-list-versions";import"@fnet/npm-pick-versions";import"object-hash";import"ajv/dist/2020.js";import"ajv/dist/standalone/index.js";import"ajv-formats";import"@flownet/lib-parse-node-url";import"bpmn-moddle";import"dagre";import"@fnet/expression";import"@fnet/list-files";import"@fnet/key-value-transformer";import"@flownet/lib-parse-npm-path";import"@fnet/prompt";async function l({atom:a,setProgress:l,context:c,deploymentProject:d,deploymentProjectTarget:f,yamlTarget:y}){await l({message:"Deploying it as npm package."});const b=c.projectDir,w=t.resolve(b,"package.json"),j=e.readFileSync(w),u=JSON.parse(j);u.name=f.params.name,u.version=r.inc(f.version,"patch");const g=f.params.bin?.name||f.params.bin;!1!==f.params.bin?.enabled&&g&&"string"==typeof g&&(u.bin={[g]:"dist/cli/esm/index.js"}),delete u.scripts,delete u.devDependencies,u.scripts={serve:"npx serve ."},e.writeFileSync(w,JSON.stringify(u,null,"\t"));const v=f.config||"npm";let h=(await i({name:v,dir:c.projectDir,tags:c.tags,optional:!0}))?.data;if(!h){const r=p("./template/schemas/to-npm.yaml"),o=await n({schema:r,tags:c.tags}),i=c.project.projectDir,m=t.resolve(i,".fnet");e.existsSync(m)||e.mkdirSync(m),e.writeFileSync(t.resolve(m,`${v}.fnet`),s.stringify(o)),h=o}if(e.writeFileSync(t.resolve(b,".npmrc"),`//registry.npmjs.org/:_authToken=${h.env.NPM_TOKEN}`),!0!==f.dryRun){if(m("bun")){if(0!==(await o("bun publish --access public",{cwd:b})).code)throw new Error("Couldnt publish to npm")}else{if(0!==(await o("npm publish --access public",{cwd:b})).code)throw new Error("Couldnt publish to npm")}e.writeFileSync(w,j),d.isDirty=!0,f.version=u.version,y.set("version",u.version)}}t.dirname(a(import.meta.url)),process.cwd();export{l as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from"node:path";import t from"node:fs";import o from"@fnet/yaml";import r from"yaml";import{r as i}from"./index.js";import"yargs";import"chalk";import"node:util";import"tree-kill";import"node:url";import"node:child_process";import"@fnet/config";import"node:os";import"@flownet/lib-render-templates-dir";import"@fnet/shelljs";import"nunjucks";import"lodash.clonedeep";import"isobject";import"redis";import"@flownet/lib-is-redis-online";import"node:crypto";import"@flownet/lib-atom-api-js";import"lodash.merge";import"@flownet/lib-parse-imports-js";import"@fnet/npm-list-versions";import"@fnet/npm-pick-versions";import"object-hash";import"ajv/dist/2020.js";import"ajv/dist/standalone/index.js";import"ajv-formats";import"@flownet/lib-parse-node-url";import"bpmn-moddle";import"dagre";import"@fnet/expression";import"@fnet/list-files";import"@fnet/key-value-transformer";import"@flownet/lib-parse-npm-path";import"@fnet/prompt";async function n(n){if(n.id)return{id:n.id,buildId:n.buildId,mode:n.mode,protocol:n.protocol||"ac:",templateDir:i("./template/fnode/node"),projectDir:e.resolve(process.cwd(),`./.output/${n.id}`),tags:n.ftag,dev:n.dev};try{const s=await async function({tags:i}){let n=function(o){const r=e.resolve(o,"node.yaml"),i=e.resolve(o,"fnode.yaml");if(t.existsSync(i))return i;if(t.existsSync(r))try{const e=t.readFileSync(r,"utf8");return t.writeFileSync(i,e,"utf8"),t.unlinkSync(r),console.log(`Migrated node.yaml to fnode.yaml in ${o}`),i}catch(e){return console.error(`Error migrating node.yaml to fnode.yaml: ${e.message}`),r}return i}(process.cwd());if(!t.existsSync(n))throw new Error("fnode.yaml file not found in current directory.");const{raw:s,parsed:m}=await o({file:n,tags:i}),p=e.dirname(n);m.features=m.features||{};const l=m.features;l.runtime=l.runtime||{},l.runtime.type=l.runtime.type||"node","python"===l.runtime.type?l.runtime.template=l.runtime.template||"python":"bun"===l.runtime.type?l.runtime.template=l.runtime.template||"bun":l.runtime.template=l.runtime.template||"node";const a={libraryAtom:{doc:{...m},fileName:"index"},projectDir:p,projectFilePath:n,projectFileContent:s,projectFileParsed:m,runtime:l.runtime};let c=e.resolve(p,"fnet/targets.yaml");if(!t.existsSync(c)&&(c=e.resolve(p,"node.devops.yaml"),t.existsSync(c))){const o=e.resolve(p,"fnet");t.existsSync(o)||t.mkdirSync(o),t.copyFileSync(c,e.resolve(p,"fnet/targets.yaml")),t.unlinkSync(c)}if(t.existsSync(c)){const{raw:e,parsed:n}=await o({file:c,tags:i}),s=r.parseDocument(e);a.devops={filePath:c,fileContent:e,yamlDocument:s,doc:{...n},type:"library.deploy",save:async()=>{t.writeFileSync(a.devops.filePath,s.toString())}}}const d=e.resolve(p,"readme.md");if(t.existsSync(d)){const e=t.readFileSync(d,"utf8");a.readme={filePath:d,fileContent:e,doc:{content:e,"content-type":"markdown"},type:"wiki"}}return a}({tags:n.ftag});return{buildId:n.buildId,mode:n.mode,protocol:n.protocol||"local:",templateDir:i(`./template/fnode/${s.runtime.template}`),projectDir:e.resolve(s.projectDir,"./.workspace"),projectSrcDir:e.resolve(s.projectDir,"./src"),project:s,tags:n.ftag,dev:n.dev}}catch(e){return console.warn(`Warning: Could not load project: ${e.message}`),{projectDir:process.cwd(),tags:n.ftag}}}export{n as createContext};
|