@fnet/cli 0.2.10 → 0.3.1

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.
Files changed (110) hide show
  1. package/dist/fbin/index.js +16 -2
  2. package/dist/fnet/index.11tp336m.js +2 -0
  3. package/dist/fnet/index.3rmtt0x7.js +2 -0
  4. package/dist/fnet/index.44a1c2n0.js +2 -0
  5. package/dist/fnet/index.75sm2tte.js +2 -0
  6. package/dist/fnet/index.899ypy57.js +2 -0
  7. package/dist/fnet/index.8m14r891.js +2 -0
  8. package/dist/fnet/index.a203h4q3.js +2 -0
  9. package/dist/fnet/index.aqy4k3s3.js +3 -0
  10. package/dist/fnet/index.csbtwe06.js +2 -0
  11. package/dist/fnet/index.efd8jxdg.js +2 -0
  12. package/dist/fnet/index.exfvnegm.js +2 -0
  13. package/dist/fnet/index.f1f463rw.js +2 -0
  14. package/dist/fnet/index.h0bm9hcc.js +2 -0
  15. package/dist/fnet/index.jkdwz7zj.js +2 -0
  16. package/dist/fnet/index.js +15 -2
  17. package/dist/fnet/index.knj6ydvb.js +2 -0
  18. package/dist/fnet/index.mhsc3fmv.js +2 -0
  19. package/dist/fnet/index.nnfg65pt.js +2 -0
  20. package/dist/fnet/index.qt2n23jk.js +3 -0
  21. package/dist/fnet/index.t8b8gd46.js +2 -0
  22. package/dist/fnet/index.z27pg13j.js +2 -0
  23. package/dist/fnet/index.zna4hmc3.js +2 -0
  24. package/dist/fnode/index.1wdjbahr.js +2 -0
  25. package/dist/fnode/index.4yxsvz96.js +2 -0
  26. package/dist/fnode/index.5jg40ryx.js +2 -0
  27. package/dist/fnode/index.6gb58dbm.js +2 -0
  28. package/dist/fnode/index.aqwm90es.js +2 -0
  29. package/dist/fnode/index.cpemgmh3.js +2 -0
  30. package/dist/fnode/index.db23gkjb.js +3 -0
  31. package/dist/fnode/index.faf8snys.js +3 -0
  32. package/dist/fnode/index.fxaj7m36.js +2 -0
  33. package/dist/fnode/index.gg7xd5ds.js +2 -0
  34. package/dist/fnode/index.h1ff50eq.js +2 -0
  35. package/dist/fnode/index.js +11 -2
  36. package/dist/fnode/index.kmnw6drq.js +5 -0
  37. package/dist/fnode/index.macrngyn.js +4 -0
  38. package/dist/fnode/index.nxt9p59e.js +2 -0
  39. package/dist/fnode/index.qcv74vey.js +2 -0
  40. package/dist/fnode/index.qcwf1eeb.js +2 -0
  41. package/dist/fnode/index.rfxcs5xv.js +2 -0
  42. package/dist/fnode/index.rgzfnevb.js +3 -0
  43. package/dist/fnode/index.s7sg00yk.js +2 -0
  44. package/dist/fnode/index.w52p2w9f.js +2 -0
  45. package/dist/fnode/index.x373mns2.js +2 -0
  46. package/dist/fnode/index.xpj8mpeb.js +2 -0
  47. package/dist/fnode/index.y4t5xdxf.js +4 -0
  48. package/dist/fnode/index.y8tx9pad.js +2 -0
  49. package/dist/fnode/index.ywj1916c.js +2 -0
  50. package/dist/frun/index.js +3 -2
  51. package/dist/fservice/index.js +20 -2
  52. package/dist/fservice/index.teesee83.js +3 -0
  53. package/package.json +8 -8
  54. package/template/fnet/node/package.json.njk +2 -2
  55. package/template/fnet/node/src/cli/index.js.v1.njk +5 -6
  56. package/template/fnet/node/src/cli/v2/core/imports.njk +2 -4
  57. package/template/fnet/node/src/cli/v2/index.js.njk +4 -4
  58. package/template/fnet/node/src/default/input.args.js.njk +5 -2
  59. package/template/fnode/node/package.json.njk +2 -2
  60. package/template/fnode/node/src/cli/index.js.v1.njk +10 -14
  61. package/template/fnode/node/src/cli/v2/core/imports.njk +2 -4
  62. package/template/fnode/node/src/cli/v2/index.js.njk +4 -4
  63. package/template/fnode/node/src/default/input.args.js.njk +6 -2
  64. package/dist/fnet/index.-SGbq2cI.js +0 -1
  65. package/dist/fnet/index.B5XE4ChJ.js +0 -1
  66. package/dist/fnet/index.Bft2w7m3.js +0 -1
  67. package/dist/fnet/index.BuYxdKtK.js +0 -1
  68. package/dist/fnet/index.C2S9JYhS.js +0 -1
  69. package/dist/fnet/index.C7saWH6d.js +0 -1
  70. package/dist/fnet/index.CDct_kkF.js +0 -1
  71. package/dist/fnet/index.CMC8mlye.js +0 -1
  72. package/dist/fnet/index.CmMM-Ek9.js +0 -1
  73. package/dist/fnet/index.CuMyez3E.js +0 -1
  74. package/dist/fnet/index.CzAV0S36.js +0 -1
  75. package/dist/fnet/index.D2N9YZmA.js +0 -1
  76. package/dist/fnet/index.D3p7pncT.js +0 -1
  77. package/dist/fnet/index.DG8TqL-1.js +0 -1
  78. package/dist/fnet/index.DI3yyTtl.js +0 -1
  79. package/dist/fnet/index.DWpw12No.js +0 -1
  80. package/dist/fnet/index.DrwlOzAe.js +0 -1
  81. package/dist/fnet/index.M39aBK2r.js +0 -1
  82. package/dist/fnet/index.Q-CYRcna.js +0 -1
  83. package/dist/fnet/index.W6RYgypK.js +0 -1
  84. package/dist/fnet/index.rSKuKke7.js +0 -1
  85. package/dist/fnet/index.xd8c7XMr.js +0 -1
  86. package/dist/fnode/index.-SGbq2cI.js +0 -1
  87. package/dist/fnode/index.B5XE4ChJ.js +0 -1
  88. package/dist/fnode/index.Bft2w7m3.js +0 -1
  89. package/dist/fnode/index.BuYxdKtK.js +0 -1
  90. package/dist/fnode/index.C2S9JYhS.js +0 -1
  91. package/dist/fnode/index.C7saWH6d.js +0 -1
  92. package/dist/fnode/index.CDct_kkF.js +0 -1
  93. package/dist/fnode/index.CJof4wXN.js +0 -1
  94. package/dist/fnode/index.CMC8mlye.js +0 -1
  95. package/dist/fnode/index.CmMM-Ek9.js +0 -1
  96. package/dist/fnode/index.CuMyez3E.js +0 -1
  97. package/dist/fnode/index.CzAV0S36.js +0 -1
  98. package/dist/fnode/index.D2N9YZmA.js +0 -1
  99. package/dist/fnode/index.D3p7pncT.js +0 -1
  100. package/dist/fnode/index.DCuAwmrd.js +0 -1
  101. package/dist/fnode/index.DG8TqL-1.js +0 -1
  102. package/dist/fnode/index.DI3yyTtl.js +0 -1
  103. package/dist/fnode/index.DWpw12No.js +0 -1
  104. package/dist/fnode/index.DrwlOzAe.js +0 -1
  105. package/dist/fnode/index.N_a5FdgA.js +0 -1
  106. package/dist/fnode/index.Q-CYRcna.js +0 -1
  107. package/dist/fnode/index.Vs3L-_fp.js +0 -1
  108. package/dist/fnode/index.W6RYgypK.js +0 -1
  109. package/dist/fnode/index.iGlS_BAd.js +0 -1
  110. package/dist/fnode/index.xd8c7XMr.js +0 -1
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import"./index.rgzfnevb.js";import l from"@fnet/config";import d from"@flownet/lib-to-electron";import t from"lodash.clonedeep";import g from"semver";async function u({atom:a,target:e,onProgress:o,projectDir:n,dependencies:r,context:c,yamlTarget:f}){if(o)await o({message:"Deploying it as electron package."});let m=e?.config?await l({name:e.config,dir:n,optional:!0,transferEnv:!1,tags:c.tags}):void 0,s=g.inc(e.version||"0.1.0","patch");e.version=s,f.set("version",s);let i=t(e.params);i.dependencies=t(r);let p={atom:a,params:i,config:m?.config,src:n,dest:n};return{deployer:await d(p)}}export{u as default};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import"./index.rgzfnevb.js";import c from"@fnet/shelljs";import g from"@fnet/config";async function p({setProgress:e,context:r,deploymentProject:s,deploymentProjectTarget:i,buildId:m}){await e({message:"Deploying it as gitlab project."});let l=r.projectDir,a="fnet-to-gitlab",o=i.params.config||"gitlab",n=await g({name:o,dir:r.projectDir,tags:r.tags});if(!n)throw Error(`Couldnt load config ${o}`);let{data:t}=n.data;if(a+=` --projectGroupId=${t.projectGroupId}`,a+=` --projectPath='${l}'`,a+=` --projectName='${i.params.name}'`,a+=` --projectBranch='${i.params.branch||"main"}'`,a+=` --gitlabHost='${t.gitlabHost}'`,a+=` --gitlabToken='${t.gitlabToken}'`,a+=` --gitlabUsername='${t.gitlabUsername}'`,a+=` --gitlabUserEmail='${t.gitlabUserEmail}'`,i.dryRun===!0)return;await c(a),s.isDirty=!0}export{p as default};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import"./index.rgzfnevb.js";import d from"@fnet/config";import l from"@flownet/lib-to-docker";import a from"lodash.clonedeep";import u from"semver";async function y({atom:r,target:e,onProgress:s,projectDir:o,dependencies:c,context:t,yamlTarget:f}){if(s)await s({message:"Deploying it as docker package."});let p=e?.config?await d({name:e.config,dir:o,optional:!0,transferEnv:!1,tags:t.tags}):void 0,n=u.inc(e.version||"0.1.0","patch");e.params.version=n,e.version=n,f.set("version",n);let i=a(e.params);i.dependencies=a(c);let m={atom:r,params:i,config:p?.config,src:o,dest:o};return{deployer:await l(m)}}export{y as default};
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ var g=Object.create;var{getPrototypeOf:h,defineProperty:f,getOwnPropertyNames:i}=Object;var j=Object.prototype.hasOwnProperty;var k=(a,b,c)=>{c=a!=null?g(h(a)):{};let d=b||!a||!a.__esModule?f(c,"default",{value:a,enumerable:!0}):c;for(let e of i(a))if(!j.call(d,e))f(d,e,{get:()=>a[e],enumerable:!0});return d};var l=(a,b)=>()=>(b||a((b={exports:{}}).exports,b),b.exports);var m=import.meta.require;
3
+ export{k as g,l as h,m as i};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import"./index.rgzfnevb.js";import w from"semver";import d from"@fnet/config";async function T({setProgress:f,context:t,deploymentProject:p,deploymentProjectTarget:o,yamlTarget:A}){await f({message:"Deploying it as fnet form."});let{file:n,data:e}=await d({name:o.config||"fnet-form",dir:t.projectDir,tags:t.tags});if(!e.env.ATOM_API_URL)throw Error(`ATOM_API_URL is required in ${n}`);if(!e.env.ATOM_API_USERNAME)throw Error(`ATOM_API_USERNAME is required in ${n}`);if(!e.env.ATOM_API_PASSWORD)throw Error(`ATOM_API_PASSWORD is required in ${n}`);let a=`${e.env.ATOM_API_URL}/v1/auth/token`,m=e.env.ATOM_API_USERNAME,h=e.env.ATOM_API_PASSWORD,r=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:m,password:h})});if(!r.ok)throw Error(`Failed to fetch token: ${r.statusText}`);let c=(await r.json())?.access_token;if(!c)throw Error(`Invalid access_token from ${a}`);p.isDirty=!0;let s=w.inc(o.version,"patch");o.params.version=s,o.version=s,A.set("version",s);let _=`${e.env.ATOM_API_URL}/v1/service/fnet-form/publish`,i=await fetch(_,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${c}`},body:JSON.stringify({name:o.params.name,version:o.params.version,docs:o.params.docs,configs:o.params.configs})});if(!i.ok)throw Error(`Error publishing fnet form: ${i.statusText}`);if((await i.json())?.error)throw Error("Error publishing fnet form.")}export{T as default};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import"./index.rgzfnevb.js";import O from"semver";import P from"@fnet/config";import R from"fs";import S from"@fnet/shelljs";import D from"form-data";async function M({setProgress:u,context:n,deploymentProject:m,deploymentProjectTarget:e,yamlTarget:w}){await u({message:"Deploying it as fnet node."});let{file:t,data:o}=await P({name:e.config||"fnet-node",dir:n.project.projectDir,tags:n.tags});if(!o.env.ATOM_API_URL)throw Error(`ATOM_API_URL is required in ${t}`);if(!o.env.ATOM_API_USERNAME)throw Error(`ATOM_API_USERNAME is required in ${t}`);if(!o.env.ATOM_API_PASSWORD)throw Error(`ATOM_API_PASSWORD is required in ${t}`);let l=`${o.env.ATOM_API_URL}/v1/auth/token`,A=o.env.ATOM_API_USERNAME,_=o.env.ATOM_API_PASSWORD,s=await fetch(l,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:A,password:_})});if(!s.ok)throw Error(`Failed to fetch token: ${s.statusText}`);let i=(await s.json())?.access_token;if(!i)throw Error(`Invalid access_token from ${l}`);m.isDirty=!0;let a=O.inc(e.version,"patch");e.params.version=a,e.version=a,w.set("version",a);let T=`${o.env.ATOM_API_URL}/v1/service/fnet-node/publish`,p=await fetch(T,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify({name:e.params.name,version:e.params.version,docs:e.params.docs,configs:e.params.configs})});if(!p.ok)throw Error(`Error publishing fnet node: ${p.statusText}`);let h=await p.json();if(h?.error)throw Error("Error publishing fnet node.");let v=h?.upload.id,r="fnet-dir-zipper";r+=` --sourceDir='${n.project.projectDir}'`,r+=" --pattern=**/*",r+=" --stdout_format=json";let c=await S(r);if(c.code!==0)throw Error(c.stderr);let E=JSON.parse(c.stdout).path,d=new D;d.append("file",R.createReadStream(E));let f=await fetch(`${o.env.ATOM_API_URL}/v1/service/upload/single/${v}`,{method:"POST",headers:{...d.getHeaders(),Authorization:`Bearer ${i}`},body:d});if(!f.ok)throw Error(`Error uploading fnet node: ${f.statusText}`);if((await f.json())?.error)throw Error("Error uploading fnet node.")}export{M as default};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import"./index.rgzfnevb.js";import l from"@fnet/config";import d from"@fnet/to-pyip";import a from"lodash.clonedeep";import y from"semver";async function u({atom:p,target:e,onProgress:s,projectDir:n,dependencies:r,context:t,yamlTarget:f}){if(s)await s({message:"Deploying it as pypi package."});let c=e?.config?await l({name:e.config,dir:n,optional:!0,transferEnv:!1,tags:t.tags}):void 0,o=y.inc(e.version||"0.1.0","patch");e.params.version=o,e.version=o,f.set("version",o);let i=a(e.params);i.dependencies=a(r);let m={atom:p,params:i,config:c?.config,src:n,dest:n};return{deployer:await d(m)}}export{u as default};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import"./index.rgzfnevb.js";import O from"semver";import P from"@fnet/config";import R from"fs";import S from"@fnet/shelljs";import D from"form-data";async function M({setProgress:h,context:t,deploymentProject:u,deploymentProjectTarget:o,yamlTarget:m}){await h({message:"Deploying it as fnet flow."});let{file:n,data:e}=await P({name:o.config||"fnet-flow",dir:t.project.projectDir,tags:t.tags});if(!e.env.ATOM_API_URL)throw Error(`ATOM_API_URL is required in ${n}`);if(!e.env.ATOM_API_USERNAME)throw Error(`ATOM_API_USERNAME is required in ${n}`);if(!e.env.ATOM_API_PASSWORD)throw Error(`ATOM_API_PASSWORD is required in ${n}`);let d=`${e.env.ATOM_API_URL}/v1/auth/token`,A=e.env.ATOM_API_USERNAME,_=e.env.ATOM_API_PASSWORD,s=await fetch(d,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:A,password:_})});if(!s.ok)throw Error(`Failed to fetch token: ${s.statusText}`);let i=(await s.json())?.access_token;if(!i)throw Error(`Invalid access_token from ${d}`);u.isDirty=!0;let a=O.inc(o.version,"patch");o.params.version=a,o.version=a,m.set("version",a);let T=`${e.env.ATOM_API_URL}/v1/service/fnet-flow/publish`,p=await fetch(T,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify({name:o.params.name,version:o.params.version,docs:o.params.docs,configs:o.params.configs})});if(!p.ok)throw Error(`Error publishing fnet flow: ${p.statusText}`);let w=await p.json();if(w?.error)throw Error("Error publishing fnet flow.");let v=w?.upload.id,r="fnet-dir-zipper";r+=` --sourceDir='${t.project.projectDir}'`,r+=" --pattern=**/*",r+=" --stdout_format=json";let f=await S(r);if(f.code!==0)throw Error(f.stderr);let E=JSON.parse(f.stdout).path,c=new D;c.append("file",R.createReadStream(E));let l=await fetch(`${e.env.ATOM_API_URL}/v1/service/upload/single/${v}`,{method:"POST",headers:{...c.getHeaders(),Authorization:`Bearer ${i}`},body:c});if(!l.ok)throw Error(`Error uploading fnet flow: ${l.statusText}`);if((await l.json())?.error)throw Error("Error uploading fnet flow.")}export{M as default};
@@ -0,0 +1,4 @@
1
+ // @bun
2
+ import{b as CT,c as jT,d as lT}from"./index.kmnw6drq.js";import{f as j}from"./index.db23gkjb.js";import"./index.rgzfnevb.js";import F from"fs";import N from"path";import tT from"nunjucks";import aT from"@flownet/lib-parse-imports-js";import eT from"@flownet/lib-parse-node-url";import I from"lodash.merge";import l from"fs";import b from"path";import _ from"@flownet/lib-parse-imports-js";import wT from"lodash.merge";function S({feature:$,features:z,packageDevDependencies:O}){let{name:W,packages:T,options:K,extraCheck:Z,explicit:G}=$,Q=`${W}_enabled`,H=z.rollup_output||{},A=Object.keys(H),J=K||{},V=z[W]?.options;if(V)J=wT(J,V);let X=!z[W]||z[W]?.enabled===!1;A.forEach((Y)=>{let q=z.rollup_output[Y];if(!q)return;if(Reflect.has(q,W)){if(X||!q[W]||q[W]?.enabled===!1){delete q[W];return}if(q[W]===!0)q[W]={enabled:!0,options:J}}else if(!X&&!G&&z[Q]!==!1)q[W]={enabled:!0};else return;q[W]=q[W]||{},q[W].options={...J,...q[W].options}});let y=A.some((Y)=>z.rollup_output[Y][W]?.enabled===!0);if(Z)y=Z()&&y;if(z[Q]=y,y)T.forEach((Y)=>O.push({package:Y[0],version:Y[1]}))}function w($){let{atom:z,packageDevDependencies:O}=$,W=z.doc.features;S({feature:{name:"workbox",packages:[["rollup-plugin-workbox","^8"]],options:{generate:{swDest:"dist/app/esm/sw.js",globDirectory:"dist/app/esm",globPatterns:["**/*.{html,js,css,png,jpg}"],skipWaiting:!0,clientsClaim:!0}},explicit:!0},features:W,packageDevDependencies:O})}function P($){let{atom:z,packageDevDependencies:O}=$,W=z.doc.features;S({feature:{name:"gzip",packages:[["rollup-plugin-gzip","^4"]],explicit:!0},features:W,packageDevDependencies:O})}function v($){let{atom:z,packageDevDependencies:O}=$,W=z.doc.features;S({feature:{name:"nunjucks",packages:[["@fnet/rollup-plugin-nunjucks","0.1.8"]]},features:W,packageDevDependencies:O})}function m($){let{atom:z,packageDevDependencies:O}=$,W=z.doc.features;S({feature:{name:"polyfill",packages:[["rollup-plugin-node-polyfills","^0.2"]]},features:W,packageDevDependencies:O})}function k($){let{atom:z,packageDevDependencies:O}=$,W=z.doc.features;S({feature:{name:"visualizer",packages:[["rollup-plugin-visualizer","^5"]],expilicit:!0},features:W,packageDevDependencies:O})}function f($){let{atom:z,packageDevDependencies:O}=$,W=z.doc.features;S({feature:{name:"analyzer",packages:[["rollup-plugin-analyzer","^3"]],options:{summaryOnly:!0,limit:12},explicit:!0},features:W,packageDevDependencies:O})}function g($){let{atom:z,packageDevDependencies:O}=$,W=z.doc.features;S({feature:{name:"string",packages:[["rollup-plugin-string","^3"]]},features:W,packageDevDependencies:O})}function o($){let{atom:z,packageDevDependencies:O}=$,W=z.doc.features;S({feature:{name:"image",packages:[["@rollup/plugin-image","^3"]]},features:W,packageDevDependencies:O})}function i($){let{atom:z,packageDevDependencies:O}=$,W=z.doc.features;if(W.runtime.type==="bun")return;S({feature:{name:"json",packages:[["@rollup/plugin-json","^6"]]},features:W,packageDevDependencies:O})}function u($){let{atom:z,packageDevDependencies:O}=$,W=z.doc.features;S({feature:{name:"terser",packages:[["@rollup/plugin-terser","^0.4"]]},features:W,packageDevDependencies:O})}function d($){let{atom:z,packageDevDependencies:O}=$,W=z.doc.features;S({feature:{name:"wasm",packages:[["@rollup/plugin-wasm","^6"]]},features:W,packageDevDependencies:O})}function D($){let{atom:z,packageDevDependencies:O}=$,W=z.doc.features;if(W.runtime.type==="bun")return;let T={};if(W.app?.enabled===!0){if(T.targets=T.targets||[],T.targets.push({src:"./src/app/index.html",dest:W.app.dir}),!Reflect.has(W.app,"copy")){if(!Reflect.has(W,"copy"))W.copy=!0}}S({feature:{name:"copy",packages:[["rollup-plugin-copy","^3"],["chokidar","^3"]],options:T},features:W,packageDevDependencies:O})}function c($){let{atom:z,packageDevDependencies:O}=$,W=z.doc.features,T=W.css&&W.css.enabled!==!1,K=[];if(T)K.push(["rollup-plugin-postcss","^4"]),K.push(["sass","^1.66"]),(W.css?.options?.plugins||[]).forEach((G)=>{switch(G.name){case"postcss-import":K.push(["postcss-import","^15"]);break;case"postcss-url":K.push(["postcss-url","^10"]);break;case"postcss-preset-env":K.push(["postcss-preset-env","^9"]);break;case"autoprefixer":K.push(["autoprefixer","^10"]);break;case"cssnano":K.push(["cssnano","^6"]);break}});S({feature:{name:"css",packages:K},features:W,packageDevDependencies:O})}function r({dir:$,name:z="index"}){let O=b.resolve($,`./${z}.tsx`);if(!l.existsSync(O))O=b.resolve($,`./${z}.ts`);if(!l.existsSync(O))O=b.resolve($,`./${z}.jsx`);if(!l.existsSync(O))O=b.resolve($,`./${z}.js`);if(!l.existsSync(O))return{};let W=O,T=b.extname(O);return{file:W,ext:T,ts:T===".ts"||T===".tsx",name:z}}async function n($){let{atom:z,context:O,setProgress:W}=$;W("Initializing features..."),z.doc.features=z.doc.features||{};let T=z.doc.features;T.project=T.project||{},T.project.format=T.project.format||T.project_format||"esm",T.project_format=T.project.format,T.dts_enabled=T.dts===!0||typeof T.dts<"u"&&T.dts!==!1;let K=b.resolve(O.project.projectDir),Z=r({dir:b.resolve(K,"./app")});if(Z.file){W("Parsing app entry imports...");let Y=await _({file:Z.file,recursive:!0}),q=Y.all.some((M)=>M.usesJSX===!0&&M.type==="local");T.app_uses_jsx=q,T.app_has_entry=!0,Y=await _({file:Z.file}),q=Y.all.some((M)=>M.usesJSX===!0&&M.type==="local"),T.app_entry_uses_jsx=q,T.app_entry_is_ts=Z.ts,T.app_entry_ext=Z.ext}let G=r({dir:b.resolve(K,"./cli")});if(G.file){W("Parsing cli entry imports...");let Y=await _({file:G.file,recursive:!0}),q=Y.all.some((M)=>M.usesJSX===!0&&M.type==="local");T.cli_uses_jsx=q,T.cli_has_entry=!0,Y=await _({file:G.file}),q=Y.all.some((M)=>M.usesJSX===!0&&M.type==="local"),T.cli_entry_uses_jsx=q,T.cli_entry_is_ts=G.ts,T.cli_entry_ext=G.ext}if(z.type==="workflow.lib"){let Y=r({dir:b.resolve(K,"./src")});if(Y.file){W("Parsing src entry imports...");let q=await _({file:Y.file,recursive:!0}),M=q.all.some((U)=>U.usesJSX===!0&&U.type==="local");T.src_uses_jsx=M,T.src_has_entry=!0,q=await _({file:Y.file}),M=q.all.some((U)=>U.usesJSX===!0&&U.type==="local"),T.src_entry_uses_jsx=M,T.src_entry_is_ts=Y.ts,T.src_entry_ext=Y.ext}}let Q=Reflect.has(T,"app_entry_uses_jsx")?T.app_entry_uses_jsx===!0:T.src_entry_uses_jsx===!0,H=Reflect.has(T,"cli_entry_uses_jsx")?T.cli_entry_uses_jsx===!0:T.src_entry_uses_jsx===!0;if(T.form_enabled=Q||H||T.form===!0||T.form?.enabled===!0,T.multiple_enabled=T.multiple_enabled||T.multiple===!0||T.multiple?.enabled===!0,T.app===!1)T.app={enabled:!1};else if(T.app===!0)T.app={enabled:!0,extend:T.app_has_entry===!0,export:!0,react:Q};else T.app={enabled:!0,extend:T.app_has_entry===!0,export:!0,react:Q,...T.app||{}};if(T.app.enabled=T.app.enabled===!0&&(z.doc.features.form_enabled===!0||T.app.extend===!0||T.app.enabled===!0),T.app.format=T.app.format||"esm",T.app.folder=T.app.folder||T.app.format||"default",T.cli===!1)T.cli={enabled:!1};else if(T.cli===!0)T.cli={enabled:!0,extend:T.cli_has_entry===!0,export:!0,react:H};else T.cli={enabled:!0,extend:T.cli_has_entry===!0,export:!0,react:H,...T.cli||{}};if(T.cli.enabled=T.cli.enabled===!0&&(z.doc.features.form_enabled===!1||T.cli.extend===!0||T.cli.enabled===!0),T.cli.format=T.cli.format||"esm",T.cli.folder=T.cli.folder||T.cli.folder||"esm",T.cli.node_options=T.cli.node?.options||T.cli.node_options||"",T.cli.bin=T.cli.bin||z.doc.name,T.cli.installable=T.cli.installable===!0,T.cli.enabled)z.doc["npm::bin"]=T.cli.bin;T.json=T.cli.enabled||T.json;let A={cjs:{format:"cjs",context:T.form_enabled?"window":"global",babel:T.src_uses_jsx===!0||!1,browser:!1,replace:!0,terser:!0,enabled:T.cjs!==!1,copy:!1},esm:{format:"esm",context:T.form_enabled?"window":"global",babel:T.src_uses_jsx===!0||!1,browser:!1,replace:!0,terser:!1,enabled:T.esm!==!1,copy:!0},iife:{format:"iife",context:T.form_enabled?"window":"global",babel:!0,browser:!0,replace:!0,enabled:T.iife===!0,terser:!0,copy:!1}},J={targets:{browsers:"last 9 versions, not dead",node:"18"}},V={};if(T.webos===!0)A.webos={format:"iife",browser:!0,babel:!0,context:"window",replace:!0,terser:!0,input:"./src/app/index.js",output_dir:"./dist/app/webos",copy:!1,babel_options:{targets:{chrome:"79"}}};if(T.electron===!0)A.electron={format:"iife",browser:!0,babel:!0,context:"window",replace:!0,terser:!0,copy:!1,input:"./src/app/index.js",output_dir:"./dist/app/electron"};if(T.nextjs===!0)A.nextjs={format:"esm",browser:!0,babel:!0,context:"window",replace:!0,terser:!0,copy:!1,input:"./src/app/index.js",output_dir:"./dist/app/nextjs"};if(T.ios===!0)A.ios={format:"iife",browser:!0,babel:!0,context:"window",replace:!0,terser:!0,copy:!1,input:"./src/app/index.js",output_dir:"./dist/app/ios"};if(T.macos===!0)A.macos={format:"iife",browser:!0,babel:!0,context:"window",replace:!0,terser:!0,copy:!1,input:"./src/app/index.js",output_dir:"./dist/app/macos"};if(T.app.enabled===!0)T.app.dir=`./dist/app/${T.app.folder}`,T.app.output={file:`./dist/app/${T.app.folder}/index.js`,dir:`./dist/app/${T.app.folder}/`,...T.app.output||{}},T.app.input={file:"./src/app/index.js",dir:"./src/app/",...T.app.input||{}},A.app={format:T.app.format,browser:!0,babel:!0,context:"window",replace:!0,input:T.app.input.file,output_dir:T.app.dir,terser:!0,output_exports:T.app.export===!1?"none":"auto",browsersync:!0};if(T.cli.enabled===!0)T.cli.dir=`./dist/cli/${T.cli.folder}`,T.cli.output={file:`./dist/cli/${T.cli.folder}/index.js`,dir:`./dist/cli/${T.cli.folder}/`,...T.cli.output||{}},T.cli.input={file:"./src/cli/index.js",dir:"./src/cli/",...T.cli.input||{}},A.cli={format:T.cli.format,context:"global",babel:T.src_uses_jsx===!0||T.cli_uses_jsx===!0||!1,browser:!1,replace:!0,enabled:!0,input:T.cli.input.file,output_dir:T.cli.dir,banner:"#!/usr/bin/env bun",terser:!0,output_exports:T.cli.export===!1?"none":"auto"};let X={server:".",startPath:`${b.normalize(T.app.dir||".")}`,files:[b.normalize("./dist/**/*")],cors:!0,open:!1};if(T.babel_options=I(J,T.babel_options||T.babel?.options),T.browsersync_options=I(X,T.browsersync_options||T.browsersync?.options||{}),T.replace_options=I(V,T.replace_options||T.replace?.options||{}),Reflect.has(T.browsersync_options,"proxy"))delete T.browsersync_options.server;T.rollup=T.rollup||{},T.rollup_output=I(A,T.rollup_output||T.rollup?.output||{}),T.preact_enabled=T.preact===!0||T.preact&&T.preact?.enabled!==!1;let y=Object.keys(A);for(let Y of y){let q=A[Y];if(!q)continue;if(T.rollup[Y]===!1){delete T.rollup_output[Y];continue}if(q.babel_options=q.babel_options||T.babel_options,q.browsersync_options=I(T.browsersync_options,q.browsersync_options),q.replace_options=I(T.replace_options,q.replace_options),T.preact_enabled)q.alias_enabled=!0,q.alias=q.alias||{},q.alias.entries=q.alias.entries||{},q.alias.entries.react="preact/compat",q.alias.entries["react-dom"]="preact/compat";if(T.form_enabled||T.babel)q.babel=!0}y=Object.keys(T.rollup_output),T.babel_enabled=y.some((Y)=>T.rollup_output[Y].babel===!0),T.browser_enabled=y.some((Y)=>T.rollup_output[Y].babel===!0),T.browsersync_enabled=T.browsersync!==!1&&y.some((Y)=>T.rollup_output[Y].browsersync===!0),T.browsersync_enabled=T.browsersync_enabled&&T.app.enabled,T.dependency_auto_enabled=T.dependency_auto!==!1&&T.dependency_auto?.enabled!==!1,T.npm_install_flags=T.npm_install_flags||"",T.react_version=T.react_version||T.react?.version||18,c($),D($),d($),u($),i($),g($),o($),f($),k($),m($),v($),w($),P($)}import PT from"@fnet/npm-list-versions";async function p({atom:$,packageDependencies:z,packageDevDependencies:O,setProgress:W}){W("Initializing dependencies");let T=$.doc.dependencies||[];if(T.filter((K)=>!K.dev).forEach((K)=>z.push(K)),T.filter((K)=>K.dev).forEach((K)=>O.push(K)),$.type==="workflow")z.push({package:"get-value",version:"^3"}),z.push({package:"set-value",version:"^4"});if($.doc.features.form_enabled){if($.doc.features.dependency_auto_enabled){let K="^18.2";if(W("Fetching React versions"),K=`^${(await PT({name:"react",groupBy:{major:!0}})).find((Q)=>Q[0]===$.doc.features.react_version.toString())[0]}`,z.push({package:"react",version:K}),z.push({package:"react-dom",version:K}),$.type==="workflow")z.push({package:"@fnet/react-app",version:"^0.1"}),z.push({package:"@fnet/react-app-state",version:"^0.1"})}}if($.doc.features.preact_enabled)z.push({package:"preact",version:"^10"});if($.doc.features.cli.enabled===!0){if(z.push({package:"@fnet/args",version:"^0.1"}),$.doc.features.cli.fargs&&$.doc.features.cli.fargs?.enabled!==!1)z.push({package:"@fnet/config",version:"0.2.21"});if($.doc.features.cli.mcp&&$.doc.features.cli.mcp.enabled!==!1)z.push({package:"@modelcontextprotocol/sdk",version:"^1.10"}),z.push({package:"express",version:"^4.18"})}if($.doc.features.render&&$.doc.features.render.enabled!==!1)O.push({package:"@flownet/lib-render-templates-dir",version:"0.1.19"});if(O.push({package:"@babel/core",version:"^7"}),O.push({package:"@rollup/plugin-commonjs",version:"^28"}),O.push({package:"@rollup/plugin-node-resolve",version:"^16"}),O.push({package:"@rollup/plugin-replace",version:"^6"}),O.push({package:"rollup",version:"^4"}),$.doc.features.dts_enabled)O.push({package:"rollup-plugin-dts",version:"^6"});if(O.push({package:"rollup-plugin-peer-deps-external",version:"^2"}),O.push({package:"@rollup/plugin-alias",version:"^5"}),O.push({package:"fs-extra",version:"^11"}),$.doc.features.babel_enabled)O.push({package:"@rollup/plugin-babel",version:"^6"}),O.push({package:"@babel/preset-env",version:"^7"}),O.push({package:"@babel/preset-react",version:"^7"}),$.doc.features.babel?.options?.plugins?.forEach((K)=>{switch(K[0]){case"@babel/plugin-proposal-decorators":O.push({package:"@babel/plugin-proposal-decorators",version:"^7"});break;case"@babel/plugin-proposal-class-properties":O.push({package:"@babel/plugin-proposal-class-properties",version:"^7"});break;case"@babel/plugin-proposal-private-methods":O.push({package:"@babel/plugin-proposal-private-methods",version:"^7"});break;case"@babel/plugin-proposal-private-property-in-object":O.push({package:"@babel/plugin-proposal-private-property-in-object",version:"^7"});break;case"@babel/plugin-proposal-optional-chaining":O.push({package:"@babel/plugin-proposal-optional-chaining",version:"^7"});break}});if(O.push({package:"@fnet/rollup-plugin-delete",version:"0.1.10"}),$.doc.features.browsersync_enabled)O.push({package:"@fnet/rollup-plugin-browsersync",version:"0.1.11"})}import vT from"@fnet/npm-list-versions";async function s({atom:$,packageDependencies:z,packageDevDependencies:O,setProgress:W}){W("Initializing dependencies for Bun");let T=$.doc.dependencies||[];if(T.filter((K)=>!K.dev).forEach((K)=>z.push(K)),T.filter((K)=>K.dev).forEach((K)=>O.push(K)),$.type==="workflow")z.push({package:"get-value",version:"^3"}),z.push({package:"set-value",version:"^4"});if($.doc.features.form_enabled){if($.doc.features.dependency_auto_enabled){let K="^18.2";if(W("Fetching React versions"),K=`^${(await vT({name:"react",groupBy:{major:!0}})).find((Q)=>Q[0]===$.doc.features.react_version.toString())[0]}`,z.push({package:"react",version:K}),z.push({package:"react-dom",version:K}),$.type==="workflow")z.push({package:"@fnet/react-app",version:"^0.1"}),z.push({package:"@fnet/react-app-state",version:"^0.1"})}}if($.doc.features.preact_enabled)z.push({package:"preact",version:"^10"});if($.doc.features.cli.enabled===!0){if(z.push({package:"@fnet/args",version:"^0.1"}),$.doc.features.cli.fargs&&$.doc.features.cli.fargs?.enabled!==!1)z.push({package:"@fnet/config",version:"0.2.21"});if($.doc.features.cli.mcp&&$.doc.features.cli.mcp.enabled!==!1)z.push({package:"@modelcontextprotocol/sdk",version:"^1.10"}),z.push({package:"express",version:"^4.18"})}if($.doc.features.render&&$.doc.features.render.enabled!==!1)O.push({package:"@flownet/lib-render-templates-dir",version:"0.1.19"})}import AT from"fs";import ST from"path";import mT from"@flownet/lib-render-templates-dir";async function t({atom:$,setProgress:z,context:O,packageDependencies:W}){if($.doc.features.app.enabled!==!0)return;await z({message:"Creating app folder"});let T={atom:$,packageDependencies:W,ts:Date.now()},K=O.templateDir,Z=ST.resolve(O.projectDir,"src/app");if(!AT.existsSync(Z))AT.mkdirSync(Z,{recursive:!0});let G=["index.js.njk"];if($.doc.features.app.html!==!1)G.push("index.html.njk");await mT({pattern:G,dir:ST.resolve(K,"src/app"),outDir:Z,context:T})}import yT from"nunjucks";import B from"fs";import E from"path";import gT from"@flownet/lib-parse-imports-js";import kT from"@fnet/npm-pick-versions";import fT from"object-hash";import h from"fs";import UT from"path";async function C({projectDir:$,name:z,setProgress:O,count:W=1}){let T,Z=fT(["npm-pick-versions",z,W]),G=UT.join($,".cache"),Q=UT.join(G,Z+".json");if(h.existsSync(Q)){if(O)O(`Picking npm version of ${z} from cache ...`);T=JSON.parse(h.readFileSync(Q,"utf8"))}else{if(O)O(`Picking npm version of ${z} ...`);T=await kT({name:z,count:W}),h.mkdirSync(G,{recursive:!0}),h.writeFileSync(Q,JSON.stringify(T),"utf8")}return T}async function a({atom:$,context:z,packageDependencies:O,packageDevDependencies:W,setProgress:T}){await T({message:"Creating package.json."}),O.filter((q)=>q.dev===!0).forEach((q)=>{if(!W.find((U)=>U.package===q.package))W.push(q);let M=O.findIndex((U)=>U.package===q.package);O.splice(M,1)});let Z=O.find((q)=>q.package==="react"),G=O.find((q)=>q.package==="react-dom");if(Z&&!G)O.push({package:"react-dom",version:Z.version});else if(Z&&G)G.version=Z.version;if(Z&&$.doc.features.react_version>=17){if(!O.find((q)=>q.package==="@emotion/react"))O.push({package:"@emotion/react",version:"^11"});if(!O.find((q)=>q.package==="@emotion/styled"))O.push({package:"@emotion/styled",version:"^11"})}let Q=[];if($.doc.features.app.enabled===!0)Q.push({file:E.resolve(z.projectDir,"src/app/index.js"),dev:$.doc.features.app.dev!==!1});if($.doc.features.cli.enabled===!0)Q.push({file:E.resolve(z.projectDir,"src/cli/index.js"),dev:$.doc.features.cli.dev!==!1});for await(let q of Q){let M=q.file;if(!B.existsSync(M))throw Error(`App file not found: ${M}`);let R=(await gT({file:M,recursive:!0,verbose:!1})).all;for await(let L of R){if(L.type!=="npm")continue;if(O.find((x)=>x.package===L.package))continue;if(W.find((x)=>x.package===L.package))continue;let xT=await C({name:L.package,projectDir:z.projectDir,setProgress:T});(q.dev===!0?W:O).push({package:L.package,subpath:L.subpath,version:xT.minorRange,type:"npm"})}}let H={atom:$,packageDependencies:O,packageDevDependencies:W},A=z.templateDir,V=yT.compile(B.readFileSync(E.resolve(A,"package.json.njk"),"utf8"),yT.configure(A)).render(H),X=z.projectDir,y=E.resolve(X,"package.json");B.writeFileSync(y,V,"utf8");let Y=E.resolve(z.project.projectDir,"fnet");if(B.existsSync(Y)){let q=E.resolve(z.projectDir,"fnet");if(!B.existsSync(q))B.mkdirSync(q);let M=B.readdirSync(Y);for(let U of M){let R=E.resolve(Y,U);if(!B.lstatSync(R).isFile())continue;let L=E.resolve(q,U);B.copyFileSync(R,L)}}}import XT from"fs";import VT from"path";import oT from"@flownet/lib-render-templates-dir";async function e({atom:$,setProgress:z,context:O,packageDependencies:W}){if($.doc.features.cli.enabled!==!0)return;await z({message:"Creating cli."});let T={atom:$,packageDependencies:W},K=O.templateDir,Z=VT.resolve(O.projectDir,"src/cli");if(!XT.existsSync(Z))XT.mkdirSync(Z,{recursive:!0});await oT({pattern:["index.js.njk"],dir:VT.resolve(K,"src/cli"),outDir:Z,context:T})}import TT from"fs";import $T from"path";import JT from"nunjucks";import iT from"@flownet/lib-parse-imports-js";async function OT({atom:$,setProgress:z,context:O,packageDependencies:W}){await z({message:"Creating rollup file."});let T={atom:$,packageDependencies:W},K=$T.resolve(O.projectDir,"src","default/index.js");if(!TT.existsSync(K))throw Error(`Entry file not found: ${K}`);let G=(await iT({file:K,recursive:!0})).all.filter((Y)=>Y.type==="node").map((Y)=>Y.path),Q=$.doc.features.rollup_output,H=Object.keys(Q);for(let Y=0;Y<H.length;Y++){let q=H[Y],M=Q[q];if(M.browser===!0){if(G.length>0){M.globals_enabled=!0,M.globals=M.globals||[],M.globals=M.globals.concat(G.map((U)=>{return{key:U,value:U}})),M.alias_enabled=!0,M.alias=M.alias||{},M.alias.entries=M.alias.entries||{};for(let U=0;U<G.length;U++){let R=G[U];M.alias.entries[R]=`node:${R}`,M.alias.entries[`node:${R}`]=R}M.external_enabled=!0,M.external=M.external||[],M.external=M.external.concat(G)}}}let A=O.templateDir,V=JT.compile(TT.readFileSync($T.resolve(A,"rollup.config.mjs.njk"),"utf8"),JT.configure(A)).render(T),X=O.projectDir,y=$T.resolve(X,"rollup.config.mjs");TT.writeFileSync(y,V,"utf8")}import zT from"fs";import NT from"path";import bT from"nunjucks";async function WT({atom:$,setProgress:z,context:O,packageDependencies:W}){await z({message:"Creating build.js file."});let T={atom:$,packageDependencies:W},K=O.templateDir,G=bT.compile(zT.readFileSync(NT.resolve(K,"build.js.njk"),"utf8"),bT.configure(K)).render(T),Q=O.projectDir,H=NT.resolve(Q,"build.js");zT.writeFileSync(H,G,"utf8"),zT.chmodSync(H,"755")}import KT from"fs";import qT from"path";import uT from"nunjucks";import dT from"ajv/dist/2020.js";import DT from"ajv/dist/standalone/index.js";import cT from"ajv-formats";async function GT({atom:$,setProgress:z,context:O,njEnv:W}){if($.doc.features.cli.enabled!==!0)return;await z({message:"Creating input args."});let T={},K=[];if($.doc.input)T=$.doc.input;else T={type:"object",properties:{},required:[]};if($.doc.features.cli.fargs&&$.doc.features.cli.fargs?.enabled!==!1){let M=$.doc.features.cli.fargs,U={type:"string",description:"Config name to load args",hidden:!1},R={type:"array",description:"Tags to filter the config",hidden:!1};if(Reflect.has(M,"default"))U.default=M.default}let G={imports:K,atom:$},Q=O.templateDir,A=uT.compile(KT.readFileSync(qT.resolve(Q,"src/default/input.args.js.njk"),"utf8"),W).render(G),J=O.projectDir,V=qT.resolve(J,"src/default/input.args.js");KT.writeFileSync(V,A,"utf8");let X=new dT({allErrors:!0,useDefaults:!0,formats:{},strict:!1,code:{esm:!0,lines:!0,optimize:!1,source:!0}});cT(X);let y=X.compile(T),q=DT(X,y)+`
3
+ export { schema31 as schema };`;KT.writeFileSync(qT.resolve(J,"src/default/validate_input.js"),q,"utf8")}import RT from"fs";import BT from"path";import LT from"nunjucks";async function QT({atom:$,setProgress:z,context:O,packageDependencies:W}){await z({message:"Creating tsconfig.json."});let T={atom:$,packageDependencies:W},K=O.templateDir,G=LT.compile(RT.readFileSync(BT.resolve(K,"tsconfig.json.njk"),"utf8"),LT.configure(K)).render(T),Q=O.projectDir,H=BT.resolve(Q,"tsconfig.json");RT.writeFileSync(H,G,"utf8")}import rT from"path";import ET from"@fnet/shelljs";async function YT({setProgress:$,context:z}){let O=z.projectDir;await $({message:"Prettifiying source files."});let W=rT.join("src","**","*");if(j("bun")){let T=await ET(`prettier --write ${W} *.{js,cjs,mjs,json,yaml,html} --no-error-on-unmatched-pattern`,{cwd:O});if(T.code!==0)throw Error(T.stderr)}else{let T=await ET(`prettier --write ${W} *.{js,cjs,mjs,json,yaml,html} --no-error-on-unmatched-pattern`,{cwd:O});if(T.code!==0)throw Error(T.stderr)}}import nT from"@fnet/shelljs";async function ZT({atom:$,setProgress:z,context:O}){if(!$.doc.features.dts_enabled)return;let W=O.projectDir;if(await z({message:"Creating .d.ts"}),(await nT("tsc",{cwd:W})).code!==0)throw Error("Couldnt create .d.ts files.")}import IT from"@fnet/shelljs";async function MT({setProgress:$,atom:z,context:O}){let W=O.projectDir;if(await $({message:"Installing npm packages."}),j("bun")){if((await IT(`bun install ${z.doc.features.npm_install_flags}`,{cwd:W})).code!==0)throw Error("Couldnt install npm packages.")}else if((await IT(`npm install ${z.doc.features.npm_install_flags}`,{cwd:W})).code!==0)throw Error("Couldnt install npm packages.")}import _T from"fs";import pT from"path";import{spawn as sT}from"child_process";async function FT($){let{projectDir:z,scriptName:O,args:W=[],env:T=process.env,shell:K=!0,detached:Z=!0,onSpawn:G}=$;if(!z||!O)throw Error("projectDir and scriptName are required");let Q=pT.resolve(z,"package.json");if(!_T.existsSync(Q))throw Error(`package.json not found at ${Q}`);let H=JSON.parse(_T.readFileSync(Q,"utf8")),A=H.scripts?.[O];if(!A){let X=Object.keys(H.scripts||{}).join(", ");throw Error(`Script '${O}' not found. Available: ${X}`)}let J=W.length>0?`${A} ${W.join(" ")}`:A,V=sT(J,[],{cwd:z,shell:K,detached:Z,env:{...T}});if(G)G(V);return new Promise((X,y)=>{V.on("error",(Y)=>{y(Error(`Failed to start '${O}': ${Y.message}`))}),V.on("close",(Y)=>{X({subprocess:V,exitCode:Y})})})}async function HT({setProgress:$,context:z}){let O=z.projectDir;await $({message:"Building main project."});let W=z.dev?"build:dev":"build";await FT({projectDir:O,scriptName:W,shell:!0,detached:!0,env:{...process.env}})}class hT extends CT{async initRuntime(){if(await n(this.apiContext),this.apiContext.context.project.runtime.type==="bun")await s(this.apiContext);else await p(this.apiContext);await this.initLibraryDir(),await this.initNunjucks(),await this.initLibs()}async initLibs(){this.setProgress({message:"Initializing external libs."});let $=[{name:this.atom.doc.name,type:"atom",parent_id:this.atom.parent_id}];this.libs=$,await this.initAtomLibsAndDeps({libs:$,packageDependencies:this.apiContext.packageDependencies})}async initAtomLibsAndDeps({libs:$,packageDependencies:z}){let O=$.filter((W)=>W.type==="atom");for(let W=0;W<O.length;W++){let T=O[W],K=await this.findAtomLibrary({url:T.name});T.atom=K,K.doc.dependencies?.filter((G)=>typeof G.repo>"u"||G.repo==="npm")?.forEach((G)=>{let Q=z.find((H)=>H.package===G.package);if(Q){if(typeof G.path==="string"){if(!(Q.path||[]).some((H)=>H===G.path))Q.path=Q.path||[],Q.path.push(G.path)}else if(Array.isArray(G.path))G.path.forEach((H)=>{if(!(Q.path||[]).some((A)=>A===H))Q.path=Q.path||[],Q.path.push(H)})}else z.push(G)})}z.sort((W,T)=>W.package?.localeCompare(T.package))}async findAtomLibrary({url:$}){let z=eT({url:$});if(!z)throw Error(`Invalid package name: ${$}`);if(!z.protocol)z.protocol=this.context.protocol;if(z.protocol==="ac:"){let O=z.pathname.split("/");if(O.length===1)return await this.apiContext.Atom.first({where:{name:$,parent_id:this.atomConfig.env.ATOM_LIBRARIES_ID,type:"workflow.lib"}});if(O.length===2){let W=await this.apiContext.Atom.first({where:{name:O[0],parent_id:this.atomConfig.env.ATOM_LIBRARIES_ID,type:"folder"}});return await this.apiContext.Atom.first({where:{name:O[1],parent_id:W.id,type:"workflow.lib"}})}}else if(z.protocol==="src:"){let O=this.atom;O.protocol="src:",O.doc.dependencies=O.doc.dependencies||[],O.name=O.doc.name;let W=N.resolve(this.context.projectSrcDir,"index.js"),T=await aT({file:W,recursive:!0}),K=O.doc.dependencies,Z=T.all;for await(let G of Z){if(G.type!=="npm")continue;if(K.find((H)=>H.package===G.package))continue;let Q=await C({name:G.package,projectDir:this.context.projectDir,setProgress:this.apiContext.setProgress});K.push({package:G.package,subpath:G.subpath,version:Q.minorRange,type:"npm"})}return O}}async createAtomLibFiles({libs:$}){await this.setProgress({message:"Creating external lib files."}),this.atom.typesDir="./types";let z=$.filter((O)=>O.type==="atom");for(let O=0;O<z.length;O++){let T=z[O].atom,K=this.context.projectDir;if(T.protocol==="src:"){let Z=N.resolve(this.context.projectSrcDir,`${T.fileName||T.name}.js`),G=N.relative(N.join(this.context.projectDir,"src","default"),Z);if(!F.existsSync(Z)){F.mkdirSync(N.dirname(Z),{recursive:!0});let Q=`export default async (input)=>{
4
+ `;Q+="}",F.writeFileSync(Z,Q,"utf8")}T.relativePath=G.split(N.sep).join("/"),this.atom.typesDir=`./types/${N.basename(K)}/src`}else{let Z=N.join(K,"src","libs",`${T.id}.js`),G=T.doc.contents?.find((Q)=>Q.format==="esm")||T.doc;F.writeFileSync(Z,G.content,"utf8")}}}async createEngine(){await this.setProgress({message:"Creating engine file."});let z={libs:this.libs.filter((G)=>G.type==="atom"),libraryAtom:this.atom,atom:this.atom},O=this.context.templateDir,T=tT.compile(F.readFileSync(N.resolve(O,N.join("src","default","engine.js.njk")),"utf8"),this.apiContext.njEnv).render(z),K=this.context.projectDir,Z=N.resolve(K,N.join("src","default","index.js"));F.writeFileSync(Z,T,"utf8")}async build(){try{if(this.fileMode){let $=this.apiContext.context.project;if(await this.createAtomLibFiles({libs:this.libs}),await this.createEngine(),await this.createProjectYaml(),await lT(this.apiContext),await QT(this.apiContext),await jT(this.apiContext),await GT(this.apiContext),await e(this.apiContext),await t(this.apiContext),$.runtime.type==="bun")await WT(this.apiContext);else await OT(this.apiContext);if(await a(this.apiContext),await YT(this.apiContext),await ZT(this.apiContext),this.buildMode){if(await MT(this.apiContext),await HT(this.apiContext),this.deployMode)await this.deploy()}}await this._cache_set(this.buildKey,{status:"COMPLETED"})}catch($){throw await this._cache_set(this.buildKey,{status:"FAILED",message:$.message||$}),console.log($),$}}}var R1=hT;export{R1 as default};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import"./index.rgzfnevb.js";import E from"cli-table3";import j from"chalk";function B(q,x={}){let y={...{chars:{top:"\u2500","top-mid":"\u2500","top-left":" ","top-right":" ",bottom:"\u2500","bottom-mid":"\u2500","bottom-left":" ","bottom-right":" ",left:" ","left-mid":" ",mid:"\u2500","mid-mid":"\u2500",right:" ","right-mid":" ",middle:" "},style:{head:[],border:[],compact:!0},wordWrap:!0},...x,head:q.map((z)=>j.bold(z))};return new E(y)}function H(q,x,A={}){let y=B(q,A);if(Array.isArray(x))x.forEach((z)=>{y.push(z)});return y.toString()}function I(q){switch(q){case"running":return j.green;case"stopped":return j.yellow;case"failed":return j.red;case"registered":return j.blue;default:return j.gray}}var L={createTable:B,createTableWithData:H,getStatusColor:I};export{I as getStatusColor,L as default,H as createTableWithData,B as createTable};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import"./index.rgzfnevb.js";import d from"@fnet/config";import l from"@flownet/lib-to-webos";import a from"lodash.clonedeep";import u from"semver";async function g({atom:r,target:e,onProgress:s,projectDir:o,dependencies:t,context:f,yamlTarget:c}){if(s)await s({message:"Deploying it as webos package."});let m=e?.config?await d({name:e.config,dir:o,optional:!0,transferEnv:!1,tags:f.tags}):void 0,n=u.inc(e.version||"0.1.0","patch");e.params.version=n,e.version=n,c.set("version",n);let i=a(e.params);i.dependencies=a(t);let p={atom:r,params:i,config:m?.config,src:o,dest:o};return{deployer:await l(p)}}export{g as default};
@@ -1,2 +1,3 @@
1
- #!/usr/bin/env node
2
- import o from"yargs";import{hideBin as r}from"yargs/helpers";import{promisify as e}from"node:util";import t from"tree-kill";import a from"fs";import n from"path";import s from"@fnet/yaml";import c from"@fnet/shell-flow";e(t);let i=!1;async function m({projectType:o,group:r,tags:e,args:t,argv:i}){try{const o=await async function(){const o=process.cwd(),r=n.resolve(o,"fnode.yaml"),e=n.resolve(o,"fnet.yaml");if(a.existsSync(r))return{path:r,name:"fnode.yaml",type:"fnode"};if(a.existsSync(e))return{path:e,name:"fnet.yaml",type:"fnet"};throw new Error("No project file (fnode.yaml or fnet.yaml) found in current directory")}(),{parsed:m}=await s({file:o.path,tags:e}),p=m.commands;if(!p)throw new Error(`Commands section not found in ${o.name}`);const f=p[r];if(!f)throw new Error(`Command group '${r}' not found in ${o.name}`);await c({commands:f,context:{args:t,argv:i,projectType:o.type}})}catch(o){console.error(`Error: ${o.message}`),process.exit(1)}}const p={command:"$0 <group> [options..]",describe:"Run a command group from project file",builder:o=>o.positional("group",{type:"string",describe:"Command group to run"}).option("ftag",{type:"array",describe:"Tags for conditional configuration"}).example("$0 build","Run the build command group").example("$0 test --ftag dev","Run the test command group with dev tag"),handler:async o=>{try{await m({projectType:"auto",group:o.group,tags:o.ftag,args:o,argv:process.argv})}catch(o){console.error(`Error: ${o.message}`),process.exit(1)}}};process.on("uncaughtException",(o=>{i||(i=!0,setTimeout((()=>process.exit(1)),500))})),process.on("unhandledRejection",(o=>{i||(i=!0,setTimeout((()=>process.exit(1)),500))})),async function(){try{o(r(process.argv)).usage("Usage: $0 <command> [options]").command(p).help().version().argv}catch(o){console.error(`Fatal error: ${o.message}`),process.exit(1)}}().catch((o=>{console.error(`Fatal error: ${o.message}`),process.exit(1)}));
1
+ #!/usr/bin/env bun
2
+ // @bun
3
+ import k from"yargs";import{hideBin as G}from"yargs/helpers";import{promisify as V}from"util";import W from"tree-kill";var S=V(W),M=!1;function C(){process.on("uncaughtException",($)=>{if(!M)M=!0,setTimeout(()=>process.exit(1),500)}),process.on("unhandledRejection",($)=>{if(!M)M=!0,setTimeout(()=>process.exit(1),500)})}import U from"fs";import D from"path";import X from"@fnet/yaml";import Z from"@fnet/shell-flow";async function J({projectType:$,group:B,tags:H,args:I,argv:O}){try{let L=await _($),{parsed:Q}=await X({file:L.path,tags:H}),q=Q.commands;if(!q)throw Error(`Commands section not found in ${L.name}`);let z=q[B];if(!z)throw Error(`Command group '${B}' not found in ${L.name}`);await Z({commands:z,context:{args:I,argv:O,projectType:L.type}})}catch(L){console.error(`Error: ${L.message}`),process.exit(1)}}async function _($){let B=process.cwd(),H=D.resolve(B,"fnode.yaml"),I=D.resolve(B,"fnet.yaml");if($==="fnode"){if(U.existsSync(H))return{path:H,name:"fnode.yaml",type:"fnode"};throw Error("fnode.yaml file not found in current directory")}if($==="fnet"){if(U.existsSync(I))return{path:I,name:"fnet.yaml",type:"fnet"};throw Error("fnet.yaml file not found in current directory")}if(U.existsSync(H))return{path:H,name:"fnode.yaml",type:"fnode"};if(U.existsSync(I))return{path:I,name:"fnet.yaml",type:"fnet"};throw Error("No project file (fnode.yaml or fnet.yaml) found in current directory")}var R={command:"$0 <group> [options..]",describe:"Run a command group from project file",builder:($)=>{return $.positional("group",{type:"string",describe:"Command group to run"}).option("ftag",{type:"array",describe:"Tags for conditional configuration"}).example("$0 build","Run the build command group").example("$0 test --ftag dev","Run the test command group with dev tag")},handler:async($)=>{try{await J({projectType:"auto",group:$.group,tags:$.ftag,args:$,argv:process.argv})}catch(B){console.error(`Error: ${B.message}`),process.exit(1)}}},N=R;C();async function A(){try{let $=k(G(process.argv)).usage("Usage: $0 <command> [options]").command(N).help().version().argv}catch($){console.error(`Fatal error: ${$.message}`),process.exit(1)}}A().catch(($)=>{console.error(`Fatal error: ${$.message}`),process.exit(1)});
@@ -1,2 +1,20 @@
1
- #!/usr/bin/env node
2
- import e from"yargs";import{hideBin as t}from"yargs/helpers";import n from"chalk";import r from"@fnet/object-from-schema";import s from"@fnet/prompt";import i from"node:fs";import o from"node:path";import a from"node:os";import c from"yaml";import l from"@fnet/service";import m from"cli-table3";import{createRequire as d}from"module";function f(){return o.join(a.homedir(),".fnet","bin")}function u(){return o.join(a.homedir(),".fnet","metadata")}function p(){return o.join(u(),"binaries.json")}function g(){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":i.existsSync(o.join(a.homedir(),".bashrc"))?"bash":i.existsSync(o.join(a.homedir(),".zshrc"))?"zsh":i.existsSync(o.join(a.homedir(),".config","fish","config.fish"))?"fish":"unknown"}catch(e){return"unknown"}}function y(e){const t=a.homedir(),n=[];switch(e){case"bash":n.push({name:".bashrc",path:o.join(t,".bashrc")}),n.push({name:".bash_profile",path:o.join(t,".bash_profile")}),n.push({name:".profile",path:o.join(t,".profile")});break;case"zsh":n.push({name:".zshrc",path:o.join(t,".zshrc")}),n.push({name:".zprofile",path:o.join(t,".zprofile")});break;case"fish":n.push({name:"config.fish",path:o.join(t,".config","fish","config.fish")});break;case"ksh":n.push({name:".kshrc",path:o.join(t,".kshrc")}),n.push({name:".profile",path:o.join(t,".profile")});break;case"csh":n.push({name:".cshrc",path:o.join(t,".cshrc")}),n.push({name:".tcshrc",path:o.join(t,".tcshrc")});break;case"powershell":n.push({name:"Microsoft.PowerShell_profile.ps1",path:o.join(t,"Documents","WindowsPowerShell","Microsoft.PowerShell_profile.ps1")}),n.push({name:"profile.ps1",path:o.join(t,"Documents","WindowsPowerShell","profile.ps1")});break;case"powershell-core":n.push({name:"Microsoft.PowerShell_profile.ps1",path:o.join(t,"Documents","PowerShell","Microsoft.PowerShell_profile.ps1")}),n.push({name:"profile.ps1",path:o.join(t,"Documents","PowerShell","profile.ps1")});break;case"cmd":n.push({name:"fnet-path.bat",path:o.join(t,"fnet-path.bat")})}return n}function v(e,t){switch(e){case"bash":case"zsh":case"ksh":default:return`export PATH="${t}:$PATH"`;case"fish":return`set -gx PATH ${t} $PATH`;case"csh":return`setenv PATH ${t}:$PATH`;case"powershell":case"powershell-core":return`$env:PATH = "${t};" + $env:PATH`;case"cmd":return`@echo off\nSETX PATH "%PATH%;${t}"\necho Path updated successfully`}}function h(){return o.join(a.homedir(),".fnet","backups")}function S(){const e=(new Date).toISOString().replace(/:/g,"-").replace(/\..+/,""),t=o.join(h(),e);return i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),t}function b(e,t,r=null){try{if(!i.existsSync(e))return!1;const n=r||o.basename(e),s=o.join(t,n),a=o.dirname(s);return i.existsSync(a)||i.mkdirSync(a,{recursive:!0}),i.copyFileSync(e,s),!0}catch(t){return console.error(n.red(`Failed to backup file ${e}: ${t.message}`)),!1}}function w(e,t={}){const n={timestamp:(new Date).toISOString(),type:t.type||"manual",message:t.message||"",command:t.command||"",files:t.files||[],...t},r=o.join(e,"metadata.json");i.writeFileSync(r,JSON.stringify(n,null,2))}function $(e){const t=o.join(h(),"latest");try{i.existsSync(t)&&i.unlinkSync(t),"win32"===process.platform?i.writeFileSync(t+".txt",e):i.symlinkSync(e,t)}catch(e){console.warn(n.yellow(`Could not create latest symlink: ${e.message}`))}}var x={getBinDirectory:f,getMetadataDirectory:u,getMetadataFilePath:p,checkIfInPath:function(e){return(process.env.PATH||"").split(o.delimiter).includes(e)},detectUserShell:g,getShellConfigPath:function(){const e=y(g());for(const t of e)if(i.existsSync(t.path))return t.path;return e.length>0?e[0].path:null},getAllShellConfigPaths:y,createBinDirectoryStructure:async function(){const e=f(),t=u(),n=p();i.existsSync(e)||i.mkdirSync(e,{recursive:!0}),i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),i.existsSync(n)||i.writeFileSync(n,JSON.stringify({binaries:{},lastUpdated:(new Date).toISOString()},null,2))},getExportPathCommand:v,addBinToPath:async function(e,t,r,s={}){try{const{autoBackup:a=!0}=s,c=v(e,r);if("cmd"===e)return i.writeFileSync(t,c),console.log(n.yellow(`Created batch file at ${t}`)),console.log(n.yellow("Run this file to add the bin directory to your PATH")),!0;if("powershell"!==e&&"powershell-core"!==e||i.existsSync(o.dirname(t))||i.mkdirSync(o.dirname(t),{recursive:!0}),!i.existsSync(t)){const r="fish"===e?"# Fish shell configuration\n\n":"powershell"===e||"powershell-core"===e?"# PowerShell profile\n\n":"# Shell configuration\n\n";i.writeFileSync(t,r),console.log(n.green(`Created config file at ${t}`))}const l=i.readFileSync(t,"utf8");if(l.includes(r))return!0;if(a&&i.existsSync(t)){const e=S(),r=o.basename(t);b(t,o.join(e,"configs"),r)&&(w(e,{type:"auto",command:"addBinToPath",message:`Automatic backup before modifying ${r}`,files:[t]}),$(e),console.log(n.green(`✓ Backed up ${r} to ${e}`)))}const m=`${l.trim()}\n\n# Added by @fnet/cli\n${c}\n`;return i.writeFileSync(t,m),"powershell"!==e&&"powershell-core"!==e||(console.log(n.yellow("You may need to set the PowerShell execution policy to run scripts:")),console.log(n.green("Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned"))),!0}catch(e){return console.error(n.red(`Failed to add bin directory to PATH: ${e.message}`)),!1}},getBackupDirectory:h,createBackupDirectory:S,backupFile:b,createBackupMetadata:w,listBackups:function(){const e=h();if(!i.existsSync(e))return[];const t=[],n=i.readdirSync(e);for(const r of n){const n=o.join(e,r),s=i.statSync(n);if(s.isDirectory()&&"latest"!==r){const e=o.join(n,"metadata.json");let a={};if(i.existsSync(e))try{a=JSON.parse(i.readFileSync(e,"utf8"))}catch(e){}t.push({timestamp:r,path:n,created:s.mtime,...a})}}return t.sort(((e,t)=>new Date(t.created)-new Date(e.created))),t},updateLatestSymlink:$};function M(){return o.join(a.homedir(),".fnet","services")}function F(){return o.join(a.homedir(),".fnet","metadata")}function j(){return o.join(F(),"services.json")}function k(){const e=j();if(!i.existsSync(e))return{services:{},lastUpdated:(new Date).toISOString()};try{return JSON.parse(i.readFileSync(e,"utf8"))}catch(e){return console.warn(n.yellow(`Failed to parse service metadata file: ${e.message}`)),{services:{},lastUpdated:(new Date).toISOString()}}}function O(e){const t=j();e.lastUpdated=(new Date).toISOString(),i.writeFileSync(t,JSON.stringify(e,null,2))}function D(e){return o.join(M(),`${e}.yaml`)}function E(e){const t=D(e);if(!i.existsSync(t))return null;try{const e=i.readFileSync(t,"utf8");return c.parse(e)}catch(e){return console.warn(n.yellow(`Failed to parse service definition file: ${e.message}`)),null}}function P(e){const t=[];if(e.name||t.push("Service name is required"),e.binary||t.push("Binary name is required"),e.binary){const n=x.getBinDirectory(),r=o.join(n,e.binary);i.existsSync(r)||t.push(`Binary '${e.binary}' not found in bin directory`)}return{valid:0===t.length,errors:t}}var A={getServicesDirectory:M,getServiceMetadataDirectory:F,getServiceMetadataFilePath:j,createServiceDirectoryStructure:async function(){const e=M(),t=F(),n=j();i.existsSync(e)||i.mkdirSync(e,{recursive:!0}),i.existsSync(t)||i.mkdirSync(t,{recursive:!0}),i.existsSync(n)||i.writeFileSync(n,JSON.stringify({services:{},lastUpdated:(new Date).toISOString()},null,2))},loadServiceMetadata:k,saveServiceMetadata:O,getServiceManfifestPath:D,servicManifestExists:function(e){const t=D(e);return i.existsSync(t)},loadServiceManifest:E,saveServiceManifest:function(e,t){const r=D(e);try{const e=c.stringify(t);return i.writeFileSync(r,e),!0}catch(e){return console.error(n.red(`Failed to save service definition: ${e.message}`)),!1}},deleteServiceManifest:function(e){const t=D(e);if(!i.existsSync(t))return!1;try{return i.unlinkSync(t),!0}catch(e){return console.error(n.red(`Failed to delete service definition: ${e.message}`)),!1}},listServiceManifests:function(){const e=M();if(!i.existsSync(e))return[];try{return i.readdirSync(e).filter((e=>e.endsWith(".yaml"))).map((e=>e.replace(".yaml","")))}catch(e){return console.error(n.red(`Failed to list service definitions: ${e.message}`)),[]}},validateServiceManifest:P,registerService:async function(e,t={}){const n=E(e);if(!n)throw new Error(`Service definition '${e}' not found`);const r=P(n);if(!r.valid)throw new Error(`Invalid service definition: ${r.errors.join(", ")}`);const s=x.getBinDirectory(),i=o.join(s,n.binary);try{await l({action:"register",name:n.name,description:n.description||`Service for ${n.binary}`,command:[i,...n.args||[]],env:n.env||{},wdir:n.workingDir,system:!1!==n.system,autoStart:!0===n.autoStart,restartOnFailure:!1!==n.restartOnFailure,user:n.user});const t=k();return t.services[n.name]={definition:e,binary:n.binary,registered:(new Date).toISOString(),status:"registered"},O(t),{success:!0,name:n.name,definition:e}}catch(e){throw new Error(`Failed to register service: ${e.message}`)}}};async function N(e){await A.createServiceDirectoryStructure();return{servicesDir:A.getServicesDirectory(),metadataDir:A.getServiceMetadataDirectory(),metadata:A.loadServiceMetadata(),args:e}}var T={getServiceManifestSchema:function(e=!0){let t=[];if(e)try{const e=x.getBinDirectory(),n=x.getMetadataFilePath();if(i.existsSync(n)){const e=JSON.parse(i.readFileSync(n,"utf8"));t=Object.keys(e.binaries).map((t=>({name:t,message:`${t} (${e.binaries[t].version||"unknown"})`})))}else i.existsSync(e)&&(t=i.readdirSync(e).map((e=>({name:e,message:e}))))}catch(e){console.warn(`Failed to get binary choices: ${e.message}`)}return{type:"object",required:["name","binary"],properties:{name:{type:"string",description:"Service name","x-prompt":{type:"input",message:"Enter service name:"}},binary:{type:"string",description:"Binary name in the bin directory","x-prompt":{type:"select",message:"Select binary:",choices:t}},description:{type:"string",description:"Service description","x-prompt":{type:"input",message:"Enter service description:"}},args:{type:"array",items:{type:"string"},description:"Command line arguments","x-prompt":{type:"input",message:"Enter command line arguments (space-separated):",result:e=>e?e.split(" "):[]}},env:{type:"object",additionalProperties:{type:"string"},description:"Environment variables","x-prompt":{type:"input",message:"Enter environment variables (KEY=VALUE format, one per line):",result:e=>e?e.split("\n").filter((e=>e.includes("="))).reduce(((e,t)=>{const[n,...r]=t.split("=");return e[n.trim()]=r.join("=").trim(),e}),{}):{}}},workingDir:{type:"string",description:"Working directory","x-prompt":{type:"input",message:"Enter working directory (optional):"}},autoStart:{type:"boolean",description:"Start on boot",default:!1,"x-prompt":{type:"confirm",message:"Start service on boot?",initial:!1}},restartOnFailure:{type:"boolean",description:"Restart on failure",default:!0,"x-prompt":{type:"confirm",message:"Restart service on failure?",initial:!0}},system:{type:"boolean",description:"System service",default:!0,"x-prompt":{type:"confirm",message:"Register as system service?",initial:!0}},user:{type:"string",description:"User to run the service as","x-prompt":{type:"input",message:"Enter user to run the service as (optional):"}},instances:{type:"integer",description:"Number of instances to run",default:1,minimum:1,"x-prompt":{type:"number",message:"Enter number of instances to run:",initial:1}},metadata:{type:"object",additionalProperties:!0,description:"Custom metadata"}}}}};var I={promptForSelection:async function(e){const{items:t,message:r,nameField:i="name",valueField:o="name",initialValue:a=null,allowAbort:c=!0}=e;if(!t||0===t.length)return console.log(n.yellow("No items available for selection.")),null;if(1===t.length&&!c){const e=t[0],r="string"==typeof e?e:e[o];return console.log(n.blue(`Only one option available: ${"string"==typeof e?e:e[i]}`)),r}let l=t.map((e=>"string"==typeof e?{name:e,value:e,message:e}:{name:e[o],value:e[o],message:e[i]||e[o]}));c&&l.push({name:"cancel",value:null,message:n.yellow("Cancel")});let m=null;if(a){const e=l.findIndex((e=>e.name===a));-1!==e&&(m=e)}const d="selectedItem",{[d]:f}=await s({type:"select",name:d,message:r,choices:l,initial:m});return"cancel"===f?null:f},promptForMultipleSelection:async function(e){const{items:t,message:r,nameField:i="name",valueField:o="name",initialValues:a=[],allowAbort:c=!0}=e;if(!t||0===t.length)return console.log(n.yellow("No items available for selection.")),null;let l=t.map((e=>"string"==typeof e?{name:e,value:e,message:e}:{name:e[o],value:e[o],message:e[i]||e[o]})),m=[];a&&a.length>0&&(m=l.map(((e,t)=>a.includes(e.name)?t:-1)).filter((e=>-1!==e)));const d="selectedItems",f=await s({type:"multiselect",name:d,message:r,choices:l,initial:m,hint:"(Use space to select, enter to confirm)",validate:e=>!(0===e.length&&!c)||"Please select at least one item"});return c&&0===f[d].length?null:f[d]}};const B={command:"manifest <subcommand>",describe:"Manage service manifests",builder:e=>e.command({command:"create",describe:"Create a new service manifest",builder:e=>e.option("name",{describe:"Service manifest name",type:"string"}).option("output",{describe:"Output file path",type:"string",alias:"o"}),handler:C}).command({command:"list",describe:"List service manifests",builder:e=>e.option("format",{describe:"Output format",type:"string",choices:["json","text","table"],default:"table"}),handler:U}).command({command:"show [n]",describe:"Show service manifest details",builder:e=>e.positional("name",{describe:"Service manifest name",type:"string",demandOption:!1}).option("format",{describe:"Output format",type:"string",choices:["json","yaml"],default:"yaml"}),handler:R}).command({command:"edit [n]",describe:"Edit a service manifest",builder:e=>e.positional("name",{describe:"Service manifest name",type:"string",demandOption:!1}),handler:H}).command({command:"delete [n]",describe:"Delete a service manifest",builder:e=>e.positional("name",{describe:"Service manifest name",type:"string",demandOption:!1}).option("force",{describe:"Force deletion without confirmation",type:"boolean",default:!1,alias:"f"}),handler:z}).command({command:"validate [n]",describe:"Validate a service manifest",builder:e=>e.positional("name",{describe:"Service manifest name",type:"string",demandOption:!1}),handler:J}).demandCommand(1,"You need to specify a subcommand"),handler:()=>{}};async function C(e){try{await N(e);const t=T.getServiceManifestSchema(),i=await r({schema:t,format:"yaml"});let o;if(console.log("Result from fnetObjectFromSchema:",i),"string"==typeof i)try{o=(await import("yaml")).default.parse(i)}catch(e){console.warn(n.yellow(`Failed to parse YAML: ${e.message}`)),o={name:"service-"+Date.now()}}else o=i&&"object"==typeof i?i.data||i:{name:"service-"+Date.now()};console.log("Generated manifest:",o);const a=e.name||(o&&o.name?o.name:"service-"+Date.now());if(A.servicManifestExists(a)&&!e.force){const{confirmOverwrite:e}=await s({type:"confirm",name:"confirmOverwrite",message:`Service manifest '${a}' already exists. Overwrite?`,initial:!1});if(!e)return void console.log(n.yellow("Operation cancelled."))}A.saveServiceManifest(a,o)?(console.log(n.green(`Service manifest '${a}' created successfully.`)),console.log(n.blue(`Location: ${A.getServiceManfifestPath(a)}`))):console.error(n.red(`Failed to create service manifest '${a}'.`))}catch(e){console.error(n.red(`Error: ${e.message}`)),process.exit(1)}}async function U(e){try{await N(e);const t=A.listServiceManifests();if(0===t.length)return void console.log(n.yellow("No service manifests found."));if("json"===e.format)console.log(JSON.stringify(t,null,2));else if("text"===e.format)t.forEach((e=>console.log(e)));else{console.log(n.bold("\nService Definitions:"));const e=(await Promise.resolve().then((function(){return Z}))).default,r=["NAME","BINARY","DESCRIPTION"],s=e.createTable(r,{chars:{mid:"","mid-mid":"","left-mid":"","right-mid":""}});for(const e of t){const t=A.loadServiceManifest(e);t&&s.push([n.white(e),n.cyan(t.binary||"undefined"),t.description||""])}console.log(s.toString()),console.log(`Total: ${t.length} manifest(s)`)}}catch(e){console.error(n.red(`Error: ${e.message}`)),process.exit(1)}}async function R(e){try{await N(e);if(!e.name){const t=A.listServiceManifests();if(0===t.length)return void console.log(n.yellow("No service manifests found."));const r=await I.promptForSelection({items:t,message:"Select a service manifest to show:",allowAbort:!0});if(null===r)return void console.log(n.yellow("Operation cancelled."));e.name=r}const t=A.loadServiceManifest(e.name);if(t||(console.error(n.red(`Service manifest '${e.name}' not found.`)),process.exit(1)),"json"===e.format)console.log(JSON.stringify(t,null,2));else{const e=(await import("yaml")).default;console.log(e.stringify(t))}}catch(e){console.error(n.red(`Error: ${e.message}`)),process.exit(1)}}async function H(e){try{await N(e);if(!e.name){const t=A.listServiceManifests();if(0===t.length)return void console.log(n.yellow("No service manifests found."));const r=await I.promptForSelection({items:t,message:"Select a service manifest to edit:",allowAbort:!0});if(null===r)return void console.log(n.yellow("Operation cancelled."));e.name=r}const t=A.loadServiceManifest(e.name);t||(console.error(n.red(`Service manifest '${e.name}' not found.`)),process.exit(1));const s=T.getServiceManifestSchema(),i=(await r({schema:s,ref:t,format:"yaml"})).data;A.saveServiceManifest(e.name,i)?console.log(n.green(`Service manifest '${e.name}' updated successfully.`)):console.error(n.red(`Failed to update service manifest '${e.name}'.`))}catch(e){console.error(n.red(`Error: ${e.message}`)),process.exit(1)}}async function z(e){try{await N(e);if(!e.name){const t=A.listServiceManifests();if(0===t.length)return void console.log(n.yellow("No service manifests found."));const r=await I.promptForSelection({items:t,message:"Select a service manifest to delete:",allowAbort:!0});if(null===r)return void console.log(n.yellow("Operation cancelled."));e.name=r}if(A.servicManifestExists(e.name)||(console.error(n.red(`Service manifest '${e.name}' not found.`)),process.exit(1)),!e.force){const{confirmDelete:t}=await s({type:"confirm",name:"confirmDelete",message:`Are you sure you want to delete service manifest '${e.name}'?`,initial:!1});if(!t)return void console.log(n.yellow("Operation cancelled."))}A.deleteServiceManifest(e.name)?console.log(n.green(`Service manifest '${e.name}' deleted successfully.`)):console.error(n.red(`Failed to delete service manifest '${e.name}'.`))}catch(e){console.error(n.red(`Error: ${e.message}`)),process.exit(1)}}async function J(e){try{await N(e);if(!e.name){const t=A.listServiceManifests();if(0===t.length)return void console.log(n.yellow("No service manifests found."));const r=await I.promptForSelection({items:t,message:"Select a service manifest to validate:",allowAbort:!0});if(null===r)return void console.log(n.yellow("Operation cancelled."));e.name=r}const t=A.loadServiceManifest(e.name);t||(console.error(n.red(`Service manifest '${e.name}' not found.`)),process.exit(1));const r=A.validateServiceManifest(t);r.valid?console.log(n.green(`Service manifest '${e.name}' is valid.`)):(console.error(n.red(`Service manifest '${e.name}' is invalid:`)),r.errors.forEach((e=>{console.error(n.red(`- ${e}`))})),process.exit(1))}catch(e){console.error(n.red(`Error: ${e.message}`)),process.exit(1)}}const _={command:"register",describe:"Register a service manifest as a system service",builder:e=>e.option("manifest",{describe:"Service manifest name",type:"string",demandOption:!0,alias:"d"}).option("start",{describe:"Start the service after registration",type:"boolean",default:!1}),handler:async e=>{try{await N(e);A.servicManifestExists(e.manifest)||(console.error(n.red(`Service manifest '${e.manifest}' not found.`)),process.exit(1)),console.log(n.blue(`Registering service from manifest '${e.manifest}'...`));const t=await A.registerService(e.manifest);if(console.log(n.green(`Service '${t.name}' registered successfully.`)),e.start){console.log(n.blue(`Starting service '${t.name}'...`));const e=(await import("@fnet/service")).default;try{await e({action:"start",name:t.name}),console.log(n.green(`Service '${t.name}' started successfully.`));const r=A.loadServiceMetadata();r.services[t.name]&&(r.services[t.name].status="running",r.services[t.name].lastStarted=(new Date).toISOString(),A.saveServiceMetadata(r))}catch(e){console.error(n.red(`Failed to start service: ${e.message}`))}}}catch(e){console.error(n.red(`Error: ${e.message}`)),process.exit(1)}}},W={command:"unregister",describe:"Unregister a service from the system",builder:e=>e.option("name",{describe:"Service name",type:"string",demandOption:!0,alias:"n"}).option("keep-manifest",{describe:"Keep the service manifest",type:"boolean",default:!0}).option("force",{describe:"Force unregistration without confirmation",type:"boolean",default:!1,alias:"f"}),handler:async e=>{try{await N(e);const t=A.loadServiceMetadata();if(t.services[e.name]||(console.error(n.red(`Service '${e.name}' not found in metadata.`)),process.exit(1)),!e.force){const{confirmUnregister:t}=await s({type:"confirm",name:"confirmUnregister",message:`Are you sure you want to unregister service '${e.name}'?`,initial:!1});if(!t)return void console.log(n.yellow("Operation cancelled."))}console.log(n.blue(`Unregistering service '${e.name}'...`));const r=(await import("@fnet/service")).default;try{const s=t.services[e.name].manifest,i=A.loadServiceManifest(s);if(!i)throw new Error(`Service manifest '${s}' not found`);const o=!1!==i.system;try{await r({action:"stop",name:e.name,system:o}),console.log(n.blue(`Service '${e.name}' stopped.`))}catch(e){console.warn(n.yellow(`Warning: Failed to stop service: ${e.message}`))}if(await r({action:"unregister",name:e.name,system:o}),console.log(n.green(`Service '${e.name}' unregistered successfully.`)),delete t.services[e.name],A.saveServiceMetadata(t),!e.keepDefinition&&s&&A.servicManifestExists(s)){A.deleteServiceManifest(s)?console.log(n.green(`Service manifest '${s}' deleted.`)):console.warn(n.yellow(`Warning: Failed to delete service manifest '${s}'.`))}}catch(e){console.error(n.red(`Failed to unregister service: ${e.message}`)),process.exit(1)}}catch(e){console.error(n.red(`Error: ${e.message}`)),process.exit(1)}}},L={command:"start",describe:"Start a registered service",builder:e=>e.option("name",{describe:"Service name",type:"string",demandOption:!0,alias:"n"}),handler:async e=>{try{await N(e);const t=A.loadServiceMetadata();t.services[e.name]||(console.error(n.red(`Service '${e.name}' not found in metadata.`)),process.exit(1)),console.log(n.blue(`Starting service '${e.name}'...`));const r=(await import("@fnet/service")).default;try{const s=t.services[e.name].manifest,i=A.loadServiceManifest(s);if(!i)throw new Error(`Service manifest '${s}' not found`);await r({action:"start",name:e.name,system:!1!==i.system}),console.log(n.green(`Service '${e.name}' started successfully.`)),t.services[e.name].status="running",t.services[e.name].lastStarted=(new Date).toISOString(),A.saveServiceMetadata(t)}catch(e){console.error(n.red(`Failed to start service: ${e.message}`)),process.exit(1)}}catch(e){console.error(n.red(`Error: ${e.message}`)),process.exit(1)}}},Y={command:"stop",describe:"Stop a running service",builder:e=>e.option("name",{describe:"Service name",type:"string",demandOption:!0,alias:"n"}),handler:async e=>{try{await N(e);const t=A.loadServiceMetadata();t.services[e.name]||(console.error(n.red(`Service '${e.name}' not found in metadata.`)),process.exit(1)),console.log(n.blue(`Stopping service '${e.name}'...`));const r=(await import("@fnet/service")).default;try{const s=t.services[e.name].manifest,i=A.loadServiceManifest(s);if(!i)throw new Error(`Service manifest '${s}' not found`);await r({action:"stop",name:e.name,system:!1!==i.system}),console.log(n.green(`Service '${e.name}' stopped successfully.`)),t.services[e.name].status="stopped",t.services[e.name].lastStopped=(new Date).toISOString(),A.saveServiceMetadata(t)}catch(e){console.error(n.red(`Failed to stop service: ${e.message}`)),process.exit(1)}}catch(e){console.error(n.red(`Error: ${e.message}`)),process.exit(1)}}},V={command:"restart",describe:"Restart a service",builder:e=>e.option("name",{describe:"Service name",type:"string",demandOption:!0,alias:"n"}),handler:async e=>{try{await N(e);const t=A.loadServiceMetadata();t.services[e.name]||(console.error(n.red(`Service '${e.name}' not found in metadata.`)),process.exit(1)),console.log(n.blue(`Restarting service '${e.name}'...`));const r=(await import("@fnet/service")).default;try{await r({action:"stop",name:e.name}),console.log(n.blue(`Service '${e.name}' stopped.`)),await r({action:"start",name:e.name}),console.log(n.green(`Service '${e.name}' restarted successfully.`)),t.services[e.name].status="running",t.services[e.name].lastRestarted=(new Date).toISOString(),A.saveServiceMetadata(t)}catch(e){console.error(n.red(`Failed to restart service: ${e.message}`)),process.exit(1)}}catch(e){console.error(n.red(`Error: ${e.message}`)),process.exit(1)}}},q={command:"status",describe:"Check the status of a service",builder:e=>e.option("name",{describe:"Service name",type:"string",demandOption:!0,alias:"n"}).option("format",{describe:"Output format",type:"string",choices:["json","text","table"],default:"table"}),handler:async e=>{try{await N(e);const t=A.loadServiceMetadata();t.services[e.name]||(console.error(n.red(`Service '${e.name}' not found in metadata.`)),process.exit(1)),console.log(n.blue(`Checking status of service '${e.name}'...`));const r=(await import("@fnet/service")).default;try{const s=t.services[e.name].manifest,i=A.loadServiceManifest(s);if(!i)throw new Error(`Service manifest '${s}' not found`);const o=await r({action:"status",name:e.name,system:!1!==i.system});console.log(n.green(`Service '${e.name}' status: ${o}`)),t.services[e.name].status=o||"unknown",t.services[e.name].lastChecked=(new Date).toISOString(),A.saveServiceMetadata(t),"json"===e.format?console.log(JSON.stringify({name:e.name,status:o||"unknown",manifest:t.services[e.name].manifest,binary:t.services[e.name].binary},null,2)):"text"===e.format?(console.log(`Name: ${e.name}`),console.log(`Status: ${o||"unknown"}`),console.log(`Definition: ${t.services[e.name].manifest}`),console.log(`Binary: ${t.services[e.name].binary}`)):(console.log(n.bold("\nService Status:")),console.log(n.bold("─".repeat(50))),console.log(`${n.bold("Name:")} ${e.name}`),console.log(`${n.bold("Status:")} ${function(e){switch(e){case"running":return n.green;case"stopped":return n.yellow;case"failed":return n.red;default:return n.gray}}(o)(o||"unknown")}`),console.log(`${n.bold("Definition:")} ${t.services[e.name].manifest}`),console.log(`${n.bold("Binary:")} ${t.services[e.name].binary}`),console.log(n.bold("─".repeat(50))))}catch(e){console.error(n.red(`Failed to check service status: ${e.message}`)),process.exit(1)}}catch(e){console.error(n.red(`Error: ${e.message}`)),process.exit(1)}}};function K(e,t={}){const r={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:e.map((e=>n.bold(e)))};return new m(r)}function G(e,t,n={}){const r=K(e,n);return Array.isArray(t)&&t.forEach((e=>{r.push(e)})),r.toString()}function X(e){switch(e){case"running":return n.green;case"stopped":return n.yellow;case"failed":return n.red;case"registered":return n.blue;default:return n.gray}}var Q={createTable:K,createTableWithData:G,getStatusColor:X},Z=Object.freeze({__proto__:null,createTable:K,createTableWithData:G,default:Q,getStatusColor:X});const ee={command:"list",describe:"List all registered services",builder:e=>e.option("binary",{describe:"Filter by binary name",type:"string",alias:"b"}).option("status",{describe:"Filter by status",type:"string",choices:["running","stopped","failed","unknown"],alias:"s"}).option("format",{describe:"Output format",type:"string",choices:["json","text","table"],default:"table"}),handler:async e=>{try{await N(e);const t=A.loadServiceMetadata();let r=Object.entries(t.services).map((([e,t])=>({name:e,...t})));if(e.binary&&(r=r.filter((t=>t.binary===e.binary))),e.status&&(r=r.filter((t=>t.status===e.status))),0===r.length)return void console.log(n.yellow("No services found."));if("json"===e.format)console.log(JSON.stringify(r,null,2));else if("text"===e.format)r.forEach((e=>{console.log(`${e.name} (${e.status||"unknown"})`)}));else{const e=["NAME","STATUS","BINARY","DEFINITION"],t=Q.createTable(e,{chars:{mid:"","mid-mid":"","left-mid":"","right-mid":""}});r.forEach((e=>{const r=Q.getStatusColor(e.status);t.push([n.white(e.name),r(e.status||"unknown"),n.cyan(e.binary),e.manifest])})),console.log(n.bold("\nRegistered Services:")),console.log(t.toString()),console.log(`Total: ${r.length} service(s)`)}}catch(e){console.error(n.red(`Error: ${e.message}`)),process.exit(1)}}},te=d(import.meta.url),{version:ne}=te("../../package.json");e(t(process.argv)).scriptName("fservice").usage("Usage: $0 <command> [options]").version(ne).command(B).command(_).command(W).command(L).command(Y).command(V).command(q).command(ee).demandCommand(1,"You need to specify a command").strict().help().alias("h","help").alias("v","version").fail(((e,t,r)=>{t?(console.error(n.red(`Error: ${t.message}`)),console.error(t)):console.error(n.red(`Error: ${e}`)),console.error(n.yellow("\nUsage:"),r.help()),process.exit(1)})).parse();
1
+ #!/usr/bin/env bun
2
+ // @bun
3
+ import{a as V,b as A,c as o}from"./index.teesee83.js";import rz from"yargs";import{hideBin as sz}from"yargs/helpers";import l from"chalk";import T from"chalk";import Zz from"@fnet/object-from-schema";import _z from"@fnet/prompt";import H from"fs";import P from"path";import zz from"os";import S from"chalk";import Jz from"yaml";import Bz from"@fnet/service";import q from"fs";import $ from"path";import F from"os";import B from"chalk";function n(){return $.join(F.homedir(),".fnet","bin")}function f(){return $.join(F.homedir(),".fnet","metadata")}function c(){return $.join(f(),"binaries.json")}function Lz(z){return(process.env.PATH||"").split($.delimiter).includes(z)}function m(){try{if(process.platform==="win32"){if(process.env.PSModulePath&&process.env.PSModulePath.includes("PowerShell"))return"powershell-core";if(process.env.PSModulePath)return"powershell";return"cmd"}let z=process.env.SHELL||"";if(z.includes("bash"))return"bash";if(z.includes("zsh"))return"zsh";if(z.includes("fish"))return"fish";if(z.includes("ksh"))return"ksh";if(z.includes("csh")||z.includes("tcsh"))return"csh";if(q.existsSync($.join(F.homedir(),".bashrc")))return"bash";if(q.existsSync($.join(F.homedir(),".zshrc")))return"zsh";if(q.existsSync($.join(F.homedir(),".config","fish","config.fish")))return"fish";return"unknown"}catch(z){return"unknown"}}function r(z){let J=F.homedir(),Q=[];switch(z){case"bash":Q.push({name:".bashrc",path:$.join(J,".bashrc")}),Q.push({name:".bash_profile",path:$.join(J,".bash_profile")}),Q.push({name:".profile",path:$.join(J,".profile")});break;case"zsh":Q.push({name:".zshrc",path:$.join(J,".zshrc")}),Q.push({name:".zprofile",path:$.join(J,".zprofile")});break;case"fish":Q.push({name:"config.fish",path:$.join(J,".config","fish","config.fish")});break;case"ksh":Q.push({name:".kshrc",path:$.join(J,".kshrc")}),Q.push({name:".profile",path:$.join(J,".profile")});break;case"csh":Q.push({name:".cshrc",path:$.join(J,".cshrc")}),Q.push({name:".tcshrc",path:$.join(J,".tcshrc")});break;case"powershell":Q.push({name:"Microsoft.PowerShell_profile.ps1",path:$.join(J,"Documents","WindowsPowerShell","Microsoft.PowerShell_profile.ps1")}),Q.push({name:"profile.ps1",path:$.join(J,"Documents","WindowsPowerShell","profile.ps1")});break;case"powershell-core":Q.push({name:"Microsoft.PowerShell_profile.ps1",path:$.join(J,"Documents","PowerShell","Microsoft.PowerShell_profile.ps1")}),Q.push({name:"profile.ps1",path:$.join(J,"Documents","PowerShell","profile.ps1")});break;case"cmd":Q.push({name:"fnet-path.bat",path:$.join(J,"fnet-path.bat")});break;default:break}return Q}function Oz(){let z=m(),J=r(z);for(let Q of J)if(q.existsSync(Q.path))return Q.path;return J.length>0?J[0].path:null}async function wz(){let z=n(),J=f(),Q=c();if(!q.existsSync(z))q.mkdirSync(z,{recursive:!0});if(!q.existsSync(J))q.mkdirSync(J,{recursive:!0});if(!q.existsSync(Q))q.writeFileSync(Q,JSON.stringify({binaries:{},lastUpdated:new Date().toISOString()},null,2))}function s(z,J){switch(z){case"bash":case"zsh":case"ksh":return`export PATH="${J}:$PATH"`;case"fish":return`set -gx PATH ${J} $PATH`;case"csh":return`setenv PATH ${J}:$PATH`;case"powershell":case"powershell-core":return`$env:PATH = "${J};" + $env:PATH`;case"cmd":return`@echo off
4
+ SETX PATH "%PATH%;${J}"
5
+ echo Path updated successfully`;default:return`export PATH="${J}:$PATH"`}}async function Vz(z,J,Q,K={}){try{let{autoBackup:X=!0}=K,W=s(z,Q);if(z==="cmd")return q.writeFileSync(J,W),console.log(B.yellow(`Created batch file at ${J}`)),console.log(B.yellow("Run this file to add the bin directory to your PATH")),!0;if((z==="powershell"||z==="powershell-core")&&!q.existsSync($.dirname(J)))q.mkdirSync($.dirname(J),{recursive:!0});if(!q.existsSync(J)){let R=z==="fish"?`# Fish shell configuration
6
+
7
+ `:z==="powershell"||z==="powershell-core"?`# PowerShell profile
8
+
9
+ `:`# Shell configuration
10
+
11
+ `;q.writeFileSync(J,R),console.log(B.green(`Created config file at ${J}`))}let Z=q.readFileSync(J,"utf8");if(Z.includes(Q))return!0;if(X&&q.existsSync(J)){let R=i(),w=$.basename(J);if(t(J,$.join(R,"configs"),w))a(R,{type:"auto",command:"addBinToPath",message:`Automatic backup before modifying ${w}`,files:[J]}),e(R),console.log(B.green(`\u2713 Backed up ${w} to ${R}`))}let _=`${Z.trim()}
12
+
13
+ # Added by @fnet/cli
14
+ ${W}
15
+ `;if(q.writeFileSync(J,_),z==="powershell"||z==="powershell-core")console.log(B.yellow("You may need to set the PowerShell execution policy to run scripts:")),console.log(B.green("Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned"));return!0}catch(X){return console.error(B.red(`Failed to add bin directory to PATH: ${X.message}`)),!1}}function u(){return $.join(F.homedir(),".fnet","backups")}function i(){let z=new Date().toISOString().replace(/:/g,"-").replace(/\..+/,""),J=$.join(u(),z);if(!q.existsSync(J))q.mkdirSync(J,{recursive:!0});return J}function t(z,J,Q=null){try{if(!q.existsSync(z))return!1;let K=Q||$.basename(z),X=$.join(J,K),W=$.dirname(X);if(!q.existsSync(W))q.mkdirSync(W,{recursive:!0});return q.copyFileSync(z,X),!0}catch(K){return console.error(B.red(`Failed to backup file ${z}: ${K.message}`)),!1}}function a(z,J={}){let Q={timestamp:new Date().toISOString(),type:J.type||"manual",message:J.message||"",command:J.command||"",files:J.files||[],...J},K=$.join(z,"metadata.json");q.writeFileSync(K,JSON.stringify(Q,null,2))}function Az(){let z=u();if(!q.existsSync(z))return[];let J=[],Q=q.readdirSync(z);for(let K of Q){let X=$.join(z,K),W=q.statSync(X);if(W.isDirectory()&&K!=="latest"){let Z=$.join(X,"metadata.json"),_={};if(q.existsSync(Z))try{_=JSON.parse(q.readFileSync(Z,"utf8"))}catch(R){}J.push({timestamp:K,path:X,created:W.mtime,..._})}}return J.sort((K,X)=>new Date(X.created)-new Date(K.created)),J}function e(z){let J=$.join(u(),"latest");try{if(q.existsSync(J))q.unlinkSync(J);if(process.platform==="win32")q.writeFileSync(J+".txt",z);else q.symlinkSync(z,J)}catch(Q){console.warn(B.yellow(`Could not create latest symlink: ${Q.message}`))}}var D={getBinDirectory:n,getMetadataDirectory:f,getMetadataFilePath:c,checkIfInPath:Lz,detectUserShell:m,getShellConfigPath:Oz,getAllShellConfigPaths:r,createBinDirectoryStructure:wz,getExportPathCommand:s,addBinToPath:Vz,getBackupDirectory:u,createBackupDirectory:i,backupFile:t,createBackupMetadata:a,listBackups:Az,updateLatestSymlink:e};function k(){return P.join(zz.homedir(),".fnet","services")}function h(){return P.join(zz.homedir(),".fnet","metadata")}function p(){return P.join(h(),"services.json")}async function Uz(){let z=k(),J=h(),Q=p();if(!H.existsSync(z))H.mkdirSync(z,{recursive:!0});if(!H.existsSync(J))H.mkdirSync(J,{recursive:!0});if(!H.existsSync(Q))H.writeFileSync(Q,JSON.stringify({services:{},lastUpdated:new Date().toISOString()},null,2))}function Kz(){let z=p();if(!H.existsSync(z))return{services:{},lastUpdated:new Date().toISOString()};try{return JSON.parse(H.readFileSync(z,"utf8"))}catch(J){return console.warn(S.yellow(`Failed to parse service metadata file: ${J.message}`)),{services:{},lastUpdated:new Date().toISOString()}}}function Qz(z){let J=p();z.lastUpdated=new Date().toISOString(),H.writeFileSync(J,JSON.stringify(z,null,2))}function N(z){return P.join(k(),`${z}.yaml`)}function xz(z){let J=N(z);return H.existsSync(J)}function Wz(z){let J=N(z);if(!H.existsSync(J))return null;try{let Q=H.readFileSync(J,"utf8");return Jz.parse(Q)}catch(Q){return console.warn(S.yellow(`Failed to parse service manifest file: ${Q.message}`)),null}}function Fz(z,J){let Q=N(z);try{let K=Jz.stringify(J);return H.writeFileSync(Q,K),!0}catch(K){return console.error(S.red(`Failed to save service manifest: ${K.message}`)),!1}}function Mz(z){let J=N(z);if(!H.existsSync(J))return!1;try{return H.unlinkSync(J),!0}catch(Q){return console.error(S.red(`Failed to delete service manifest: ${Q.message}`)),!1}}function Cz(){let z=k();if(!H.existsSync(z))return[];try{return H.readdirSync(z).filter((J)=>J.endsWith(".yaml")).map((J)=>J.replace(".yaml",""))}catch(J){return console.error(S.red(`Failed to list service definitions: ${J.message}`)),[]}}function Xz(z){let J=[];if(!z.name)J.push("Service name is required");if(!z.binary)J.push("Binary name is required");if(z.binary){let Q=D.getBinDirectory(),K=P.join(Q,z.binary);if(!H.existsSync(K))J.push(`Binary '${z.binary}' not found in bin directory`)}return{valid:J.length===0,errors:J}}async function jz(z,J={}){let Q=Wz(z);if(!Q)throw Error(`Service manifest '${z}' not found`);let K=Xz(Q);if(!K.valid)throw Error(`Invalid service manifest: ${K.errors.join(", ")}`);let X=D.getBinDirectory(),W=P.join(X,Q.binary);try{await Bz({action:"register",name:Q.name,description:Q.description||`Service for ${Q.binary}`,command:[W,...Q.args||[]],env:Q.env||{},wdir:Q.workingDir,system:Q.system!==!1,autoStart:Q.autoStart===!0,restartOnFailure:Q.restartOnFailure!==!1,user:Q.user});let Z=Kz();return Z.services[Q.name]={manifest:z,binary:Q.binary,registered:new Date().toISOString(),status:"registered"},Qz(Z),{success:!0,name:Q.name,manifest:z}}catch(Z){throw Error(`Failed to register service: ${Z.message}`)}}var Y={getServicesDirectory:k,getServiceMetadataDirectory:h,getServiceMetadataFilePath:p,createServiceDirectoryStructure:Uz,loadServiceMetadata:Kz,saveServiceMetadata:Qz,getServiceManifestPath:N,servicManifestExists:xz,loadServiceManifest:Wz,saveServiceManifest:Fz,deleteServiceManifest:Mz,listServiceManifests:Cz,validateServiceManifest:Xz,registerService:jz};async function E(z){await Y.createServiceDirectoryStructure();let J=Y.getServicesDirectory(),Q=Y.getServiceMetadataDirectory(),K=Y.loadServiceMetadata();return{servicesDir:J,metadataDir:Q,metadata:K,args:z}}import d from"fs";function Dz(z=!0){let J=[];if(z)try{let Q=D.getBinDirectory(),K=D.getMetadataFilePath();if(d.existsSync(K)){let X=JSON.parse(d.readFileSync(K,"utf8"));J=Object.keys(X.binaries).map((W)=>({name:W,message:`${W} (${X.binaries[W].version||"unknown"})`}))}else if(d.existsSync(Q))J=d.readdirSync(Q).map((X)=>({name:X,message:X}))}catch(Q){console.warn(`Failed to get binary choices: ${Q.message}`)}return{type:"object",required:["name","binary"],properties:{name:{type:"string",description:"Service name","x-prompt":{type:"input",message:"Enter service name:"}},binary:{type:"string",description:"Binary name in the bin directory","x-prompt":{type:"select",message:"Select binary:",choices:J}},description:{type:"string",description:"Service description","x-prompt":{type:"input",message:"Enter service description:"}},args:{type:"array",items:{type:"string"},description:"Command line arguments","x-prompt":{type:"input",message:"Enter command line arguments (space-separated):",result:(Q)=>Q?Q.split(" "):[]}},env:{type:"object",additionalProperties:{type:"string"},description:"Environment variables","x-prompt":{type:"input",message:"Enter environment variables (KEY=VALUE format, one per line):",result:(Q)=>{if(!Q)return{};return Q.split(`
16
+ `).filter((K)=>K.includes("=")).reduce((K,X)=>{let[W,...Z]=X.split("=");return K[W.trim()]=Z.join("=").trim(),K},{})}}},workingDir:{type:"string",description:"Working directory","x-prompt":{type:"input",message:"Enter working directory (optional):"}},autoStart:{type:"boolean",description:"Start on boot",default:!1,"x-prompt":{type:"confirm",message:"Start service on boot?",initial:!1}},restartOnFailure:{type:"boolean",description:"Restart on failure",default:!0,"x-prompt":{type:"confirm",message:"Restart service on failure?",initial:!0}},system:{type:"boolean",description:"System service",default:!0,"x-prompt":{type:"confirm",message:"Register as system service?",initial:!0}},user:{type:"string",description:"User to run the service as","x-prompt":{type:"input",message:"Enter user to run the service as (optional):"}},instances:{type:"integer",description:"Number of instances to run",default:1,minimum:1,"x-prompt":{type:"number",message:"Enter number of instances to run:",initial:1}},metadata:{type:"object",additionalProperties:!0,description:"Custom metadata"}}}}var v={getServiceManifestSchema:Dz};import g from"chalk";import Yz from"@fnet/prompt";async function Pz(z){let{items:J,message:Q,nameField:K="name",valueField:X="name",initialValue:W=null,allowAbort:Z=!0}=z;if(!J||J.length===0)return console.log(g.yellow("No items available for selection.")),null;if(J.length===1&&!Z){let G=J[0],b=typeof G==="string"?G:G[X];return console.log(g.blue(`Only one option available: ${typeof G==="string"?G:G[K]}`)),b}let _=J.map((G)=>{if(typeof G==="string")return{name:G,value:G,message:G};else return{name:G[X],value:G[X],message:G[K]||G[X]}});if(Z)_.push({name:"cancel",value:null,message:g.yellow("Cancel")});let R=null;if(W){let G=_.findIndex((b)=>b.name===W);if(G!==-1)R=G}let w="selectedItem",{[w]:j}=await Yz({type:"select",name:w,message:Q,choices:_,initial:R});if(j==="cancel")return null;return j}async function bz(z){let{items:J,message:Q,nameField:K="name",valueField:X="name",initialValues:W=[],allowAbort:Z=!0}=z;if(!J||J.length===0)return console.log(g.yellow("No items available for selection.")),null;let _=J.map((G)=>{if(typeof G==="string")return{name:G,value:G,message:G};else return{name:G[X],value:G[X],message:G[K]||G[X]}}),R=[];if(W&&W.length>0)R=_.map((G,b)=>W.includes(G.name)?b:-1).filter((G)=>G!==-1);let w="selectedItems",j=await Yz({type:"multiselect",name:w,message:Q,choices:_,initial:R,hint:"(Use space to select, enter to confirm)",validate:(G)=>{if(G.length===0&&!Z)return"Please select at least one item";return!0}});if(Z&&j[w].length===0)return null;return j[w]}var L={promptForSelection:Pz,promptForMultipleSelection:bz};var Sz={command:"manifest <subcommand>",describe:"Manage service manifests",builder:(z)=>{return z.command({command:"create",describe:"Create a new service manifest",builder:(J)=>{return J.option("name",{describe:"Service manifest name",type:"string"}).option("output",{describe:"Output file path",type:"string",alias:"o"})},handler:Nz}).command({command:"list",describe:"List service manifests",builder:(J)=>{return J.option("format",{describe:"Output format",type:"string",choices:["json","text","table"],default:"table"})},handler:yz}).command({command:"show [n]",describe:"Show service manifest details",builder:(J)=>{return J.positional("name",{describe:"Service manifest name",type:"string",demandOption:!1}).option("format",{describe:"Output format",type:"string",choices:["json","yaml"],default:"yaml"})},handler:uz}).command({command:"edit [n]",describe:"Edit a service manifest",builder:(J)=>{return J.positional("name",{describe:"Service manifest name",type:"string",demandOption:!1})},handler:kz}).command({command:"delete [n]",describe:"Delete a service manifest",builder:(J)=>{return J.positional("name",{describe:"Service manifest name",type:"string",demandOption:!1}).option("force",{describe:"Force deletion without confirmation",type:"boolean",default:!1,alias:"f"})},handler:pz}).command({command:"validate [n]",describe:"Validate a service manifest",builder:(J)=>{return J.positional("name",{describe:"Service manifest name",type:"string",demandOption:!1})},handler:dz}).demandCommand(1,"You need to specify a subcommand")},handler:()=>{}};async function Nz(z){try{let J=await E(z),Q=v.getServiceManifestSchema(),K=await Zz({schema:Q,format:"yaml"});console.log("Result from fnetObjectFromSchema:",K);let X;if(typeof K==="string")try{X=(await import("yaml")).default.parse(K)}catch(_){console.warn(T.yellow(`Failed to parse YAML: ${_.message}`)),X={name:"service-"+Date.now()}}else if(K&&typeof K==="object")X=K.data||K;else X={name:"service-"+Date.now()};console.log("Generated manifest:",X);let W=z.name||(X&&X.name?X.name:"service-"+Date.now());if(Y.servicManifestExists(W)&&!z.force){let{confirmOverwrite:_}=await _z({type:"confirm",name:"confirmOverwrite",message:`Service manifest '${W}' already exists. Overwrite?`,initial:!1});if(!_){console.log(T.yellow("Operation cancelled."));return}}if(Y.saveServiceManifest(W,X))console.log(T.green(`Service manifest '${W}' created successfully.`)),console.log(T.blue(`Location: ${Y.getServiceManifestPath(W)}`));else console.error(T.red(`Failed to create service manifest '${W}'.`))}catch(J){console.error(T.red(`Error: ${J.message}`)),process.exit(1)}}async function yz(z){try{let J=await E(z),Q=Y.listServiceManifests();if(Q.length===0){console.log(T.yellow("No service manifests found."));return}if(z.format==="json")console.log(JSON.stringify(Q,null,2));else if(z.format==="text")Q.forEach((K)=>console.log(K));else{console.log(T.bold(`
17
+ Service Definitions:`));let K=(await import("./index.teesee83.js")).default,X=["NAME","BINARY","DESCRIPTION"],W=K.createTable(X,{chars:{mid:"","mid-mid":"","left-mid":"","right-mid":""}});for(let Z of Q){let _=Y.loadServiceManifest(Z);if(_)W.push([T.white(Z),T.cyan(_.binary||"undefined"),_.description||""])}console.log(W.toString()),console.log(`Total: ${Q.length} manifest(s)`)}}catch(J){console.error(T.red(`Error: ${J.message}`)),process.exit(1)}}async function uz(z){try{let J=await E(z);if(!z.name){let K=Y.listServiceManifests();if(K.length===0){console.log(T.yellow("No service manifests found."));return}let X=await L.promptForSelection({items:K,message:"Select a service manifest to show:",allowAbort:!0});if(X===null){console.log(T.yellow("Operation cancelled."));return}z.name=X}let Q=Y.loadServiceManifest(z.name);if(!Q)console.error(T.red(`Service manifest '${z.name}' not found.`)),process.exit(1);if(z.format==="json")console.log(JSON.stringify(Q,null,2));else{let K=(await import("yaml")).default;console.log(K.stringify(Q))}}catch(J){console.error(T.red(`Error: ${J.message}`)),process.exit(1)}}async function kz(z){try{let J=await E(z);if(!z.name){let _=Y.listServiceManifests();if(_.length===0){console.log(T.yellow("No service manifests found."));return}let R=await L.promptForSelection({items:_,message:"Select a service manifest to edit:",allowAbort:!0});if(R===null){console.log(T.yellow("Operation cancelled."));return}z.name=R}let Q=Y.loadServiceManifest(z.name);if(!Q)console.error(T.red(`Service manifest '${z.name}' not found.`)),process.exit(1);let K=v.getServiceManifestSchema(),W=(await Zz({schema:K,ref:Q,format:"yaml"})).data;if(Y.saveServiceManifest(z.name,W))console.log(T.green(`Service manifest '${z.name}' updated successfully.`));else console.error(T.red(`Failed to update service manifest '${z.name}'.`))}catch(J){console.error(T.red(`Error: ${J.message}`)),process.exit(1)}}async function pz(z){try{let J=await E(z);if(!z.name){let K=Y.listServiceManifests();if(K.length===0){console.log(T.yellow("No service manifests found."));return}let X=await L.promptForSelection({items:K,message:"Select a service manifest to delete:",allowAbort:!0});if(X===null){console.log(T.yellow("Operation cancelled."));return}z.name=X}if(!Y.servicManifestExists(z.name))console.error(T.red(`Service manifest '${z.name}' not found.`)),process.exit(1);if(!z.force){let{confirmDelete:K}=await _z({type:"confirm",name:"confirmDelete",message:`Are you sure you want to delete service manifest '${z.name}'?`,initial:!1});if(!K){console.log(T.yellow("Operation cancelled."));return}}if(Y.deleteServiceManifest(z.name))console.log(T.green(`Service manifest '${z.name}' deleted successfully.`));else console.error(T.red(`Failed to delete service manifest '${z.name}'.`))}catch(J){console.error(T.red(`Error: ${J.message}`)),process.exit(1)}}async function dz(z){try{let J=await E(z);if(!z.name){let X=Y.listServiceManifests();if(X.length===0){console.log(T.yellow("No service manifests found."));return}let W=await L.promptForSelection({items:X,message:"Select a service manifest to validate:",allowAbort:!0});if(W===null){console.log(T.yellow("Operation cancelled."));return}z.name=W}let Q=Y.loadServiceManifest(z.name);if(!Q)console.error(T.red(`Service manifest '${z.name}' not found.`)),process.exit(1);let K=Y.validateServiceManifest(Q);if(K.valid)console.log(T.green(`Service manifest '${z.name}' is valid.`));else console.error(T.red(`Service manifest '${z.name}' is invalid:`)),K.errors.forEach((X)=>{console.error(T.red(`- ${X}`))}),process.exit(1)}catch(J){console.error(T.red(`Error: ${J.message}`)),process.exit(1)}}var $z=Sz;import U from"chalk";var gz={command:"register",describe:"Register a service manifest as a system service",builder:(z)=>{return z.option("manifest",{describe:"Service manifest name",type:"string",demandOption:!1,alias:"d"}).option("start",{describe:"Start the service after registration",type:"boolean",default:!1})},handler:async(z)=>{try{let J=await E(z),Q=z.manifest;if(!Q){let X=Y.listServiceManifests();if(X.length===0)console.log(U.yellow('No service manifests found. Create one first using "fservice manifest create".')),process.exit(1);if(Q=await L.promptForSelection({items:X,message:"Select a service manifest to register:",allowAbort:!0}),!Q){console.log(U.yellow("Operation cancelled."));return}}if(!Y.servicManifestExists(Q))console.error(U.red(`Service manifest '${Q}' not found.`)),process.exit(1);console.log(U.blue(`Registering service from manifest '${Q}'...`));let K=await Y.registerService(Q);if(console.log(U.green(`Service '${K.name}' registered successfully.`)),z.start){console.log(U.blue(`Starting service '${K.name}'...`));let X=(await import("@fnet/service")).default;try{await X({action:"start",name:K.name}),console.log(U.green(`Service '${K.name}' started successfully.`));let W=Y.loadServiceMetadata();if(W.services[K.name])W.services[K.name].status="running",W.services[K.name].lastStarted=new Date().toISOString(),Y.saveServiceMetadata(W)}catch(W){console.error(U.red(`Failed to start service: ${W.message}`))}}}catch(J){console.error(U.red(`Error: ${J.message}`)),process.exit(1)}}},Tz=gz;import O from"chalk";import fz from"@fnet/prompt";var hz={command:"unregister",describe:"Unregister a service from the system",builder:(z)=>{return z.option("name",{describe:"Service name",type:"string",demandOption:!1,alias:"n"}).option("keep-manifest",{describe:"Keep the service manifest",type:"boolean",default:!0}).option("force",{describe:"Force unregistration without confirmation",type:"boolean",default:!1,alias:"f"})},handler:async(z)=>{try{let J=await E(z),Q=Y.loadServiceMetadata(),K=z.name;if(!K){let W=Object.keys(Q.services);if(W.length===0)console.log(O.yellow("No registered services found.")),process.exit(1);if(K=await L.promptForSelection({items:W,message:"Select a service to unregister:",allowAbort:!0}),!K){console.log(O.yellow("Operation cancelled."));return}}if(!Q.services[K])console.error(O.red(`Service '${K}' not found in metadata.`)),process.exit(1);if(!z.force){let{confirmUnregister:W}=await fz({type:"confirm",name:"confirmUnregister",message:`Are you sure you want to unregister service '${K}'?`,initial:!1});if(!W){console.log(O.yellow("Operation cancelled."));return}}console.log(O.blue(`Unregistering service '${K}'...`));let X=(await import("@fnet/service")).default;try{let W=Q.services[K].manifest,Z=Y.loadServiceManifest(W);if(!Z)throw Error(`Service manifest '${W}' not found`);let _=Z.system!==!1;try{await X({action:"stop",name:K,system:_}),console.log(O.blue(`Service '${K}' stopped.`))}catch(R){console.warn(O.yellow(`Warning: Failed to stop service: ${R.message}`))}if(await X({action:"unregister",name:K,system:_}),console.log(O.green(`Service '${K}' unregistered successfully.`)),delete Q.services[K],Y.saveServiceMetadata(Q),!z.keepDefinition&&W){if(Y.servicManifestExists(W))if(Y.deleteServiceManifest(W))console.log(O.green(`Service manifest '${W}' deleted.`));else console.warn(O.yellow(`Warning: Failed to delete service manifest '${W}'.`))}}catch(W){console.error(O.red(`Failed to unregister service: ${W.message}`)),process.exit(1)}}catch(J){console.error(O.red(`Error: ${J.message}`)),process.exit(1)}}},qz=hz;import M from"chalk";var vz={command:"start",describe:"Start a registered service",builder:(z)=>{return z.option("name",{describe:"Service name",type:"string",demandOption:!1,alias:"n"})},handler:async(z)=>{try{let J=await E(z),Q=Y.loadServiceMetadata(),K=z.name;if(!K){let W=Object.keys(Q.services);if(W.length===0)console.log(M.yellow("No registered services found.")),process.exit(1);if(K=await L.promptForSelection({items:W,message:"Select a service to start:",allowAbort:!0}),!K){console.log(M.yellow("Operation cancelled."));return}}if(!Q.services[K])console.error(M.red(`Service '${K}' not found in metadata.`)),process.exit(1);console.log(M.blue(`Starting service '${K}'...`));let X=(await import("@fnet/service")).default;try{let W=Q.services[K].manifest,Z=Y.loadServiceManifest(W);if(!Z)throw Error(`Service manifest '${W}' not found`);await X({action:"start",name:K,system:Z.system!==!1}),console.log(M.green(`Service '${K}' started successfully.`)),Q.services[K].status="running",Q.services[K].lastStarted=new Date().toISOString(),Y.saveServiceMetadata(Q)}catch(W){console.error(M.red(`Failed to start service: ${W.message}`)),process.exit(1)}}catch(J){console.error(M.red(`Error: ${J.message}`)),process.exit(1)}}},Gz=vz;import C from"chalk";var oz={command:"stop",describe:"Stop a running service",builder:(z)=>{return z.option("name",{describe:"Service name",type:"string",demandOption:!1,alias:"n"})},handler:async(z)=>{try{let J=await E(z),Q=Y.loadServiceMetadata(),K=z.name;if(!K){let W=Object.keys(Q.services);if(W.length===0)console.log(C.yellow("No registered services found.")),process.exit(1);if(K=await L.promptForSelection({items:W,message:"Select a service to stop:",allowAbort:!0}),!K){console.log(C.yellow("Operation cancelled."));return}}if(!Q.services[K])console.error(C.red(`Service '${K}' not found in metadata.`)),process.exit(1);console.log(C.blue(`Stopping service '${K}'...`));let X=(await import("@fnet/service")).default;try{let W=Q.services[K].manifest,Z=Y.loadServiceManifest(W);if(!Z)throw Error(`Service manifest '${W}' not found`);await X({action:"stop",name:K,system:Z.system!==!1}),console.log(C.green(`Service '${K}' stopped successfully.`)),Q.services[K].status="stopped",Q.services[K].lastStopped=new Date().toISOString(),Y.saveServiceMetadata(Q)}catch(W){console.error(C.red(`Failed to stop service: ${W.message}`)),process.exit(1)}}catch(J){console.error(C.red(`Error: ${J.message}`)),process.exit(1)}}},Ez=oz;import x from"chalk";var lz={command:"restart",describe:"Restart a service",builder:(z)=>{return z.option("name",{describe:"Service name",type:"string",demandOption:!1,alias:"n"})},handler:async(z)=>{try{let J=await E(z),Q=Y.loadServiceMetadata(),K=z.name;if(!K){let W=Object.keys(Q.services);if(W.length===0)console.log(x.yellow("No registered services found.")),process.exit(1);if(K=await L.promptForSelection({items:W,message:"Select a service to restart:",allowAbort:!0}),!K){console.log(x.yellow("Operation cancelled."));return}}if(!Q.services[K])console.error(x.red(`Service '${K}' not found in metadata.`)),process.exit(1);console.log(x.blue(`Restarting service '${K}'...`));let X=(await import("@fnet/service")).default;try{await X({action:"stop",name:K}),console.log(x.blue(`Service '${K}' stopped.`)),await X({action:"start",name:K}),console.log(x.green(`Service '${K}' restarted successfully.`)),Q.services[K].status="running",Q.services[K].lastRestarted=new Date().toISOString(),Y.saveServiceMetadata(Q)}catch(W){console.error(x.red(`Failed to restart service: ${W.message}`)),process.exit(1)}}catch(J){console.error(x.red(`Error: ${J.message}`)),process.exit(1)}}},Rz=lz;import I from"chalk";var nz={command:"status",describe:"Check the status of a service",builder:(z)=>{return z.option("name",{describe:"Service name",type:"string",demandOption:!1,alias:"n"}).option("format",{describe:"Output format",type:"string",choices:["json","text","table"],default:"table"})},handler:async(z)=>{try{let J=await E(z),Q=Y.loadServiceMetadata(),K=z.name;if(!K){let W=Object.keys(Q.services);if(W.length===0)console.log(I.yellow("No registered services found.")),process.exit(1);if(K=await L.promptForSelection({items:W,message:"Select a service to check status:",allowAbort:!0}),!K){console.log(I.yellow("Operation cancelled."));return}}if(!Q.services[K])console.error(I.red(`Service '${K}' not found in metadata.`)),process.exit(1);console.log(I.blue(`Checking status of service '${K}'...`));let X=(await import("@fnet/service")).default;try{let W=Q.services[K].manifest,Z=Y.loadServiceManifest(W);if(!Z)throw Error(`Service manifest '${W}' not found`);let _=await X({action:"status",name:K,system:Z.system!==!1});if(console.log(I.green(`Service '${K}' status: ${_}`)),Q.services[K].status=_||"unknown",Q.services[K].lastChecked=new Date().toISOString(),Y.saveServiceMetadata(Q),z.format==="json")console.log(JSON.stringify({name:K,status:_||"unknown",manifest:W,binary:Q.services[K].binary},null,2));else if(z.format==="text")console.log(`Name: ${K}`),console.log(`Status: ${_||"unknown"}`),console.log(`Definition: ${W}`),console.log(`Binary: ${Q.services[K].binary}`);else console.log(I.bold(`
18
+ Service Status:`)),console.log(I.bold("\u2500".repeat(50))),console.log(`${I.bold("Name:")} ${K}`),console.log(`${I.bold("Status:")} ${cz(_)(_||"unknown")}`),console.log(`${I.bold("Definition:")} ${W}`),console.log(`${I.bold("Binary:")} ${Q.services[K].binary}`),console.log(I.bold("\u2500".repeat(50)))}catch(W){console.error(I.red(`Failed to check service status: ${W.message}`)),process.exit(1)}}catch(J){console.error(I.red(`Error: ${J.message}`)),process.exit(1)}}};function cz(z){switch(z){case"running":return I.green;case"stopped":return I.yellow;case"failed":return I.red;default:return I.gray}}var Hz=nz;import y from"chalk";var mz={command:"list",describe:"List all registered services",builder:(z)=>{return z.option("binary",{describe:"Filter by binary name",type:"string",alias:"b"}).option("status",{describe:"Filter by status",type:"string",choices:["running","stopped","failed","unknown"],alias:"s"}).option("format",{describe:"Output format",type:"string",choices:["json","text","table"],default:"table"})},handler:async(z)=>{try{let J=await E(z),Q=Y.loadServiceMetadata(),K=Object.entries(Q.services).map(([X,W])=>({name:X,...W}));if(z.binary)K=K.filter((X)=>X.binary===z.binary);if(z.status)K=K.filter((X)=>X.status===z.status);if(K.length===0){console.log(y.yellow("No services found."));return}if(z.format==="json")console.log(JSON.stringify(K,null,2));else if(z.format==="text")K.forEach((X)=>{console.log(`${X.name} (${X.status||"unknown"})`)});else{let X=["NAME","STATUS","BINARY","DEFINITION"],W=o.createTable(X,{chars:{mid:"","mid-mid":"","left-mid":"","right-mid":""}});K.forEach((Z)=>{let _=o.getStatusColor(Z.status);W.push([y.white(Z.name),_(Z.status||"unknown"),y.cyan(Z.binary),Z.manifest])}),console.log(y.bold(`
19
+ Registered Services:`)),console.log(W.toString()),console.log(`Total: ${K.length} service(s)`)}}catch(J){console.error(y.red(`Error: ${J.message}`)),process.exit(1)}}},Iz=mz;import{createRequire as iz}from"module";var tz=iz(import.meta.url),{version:az}=tz("../../package.json"),BK=rz(sz(process.argv)).scriptName("fservice").usage("Usage: $0 <command> [options]").version(az).command($z).command(Tz).command(qz).command(Gz).command(Ez).command(Rz).command(Hz).command(Iz).demandCommand(1,"You need to specify a command").strict().help().alias("h","help").alias("v","version").fail((z,J,Q)=>{if(J)console.error(l.red(`Error: ${J.message}`)),console.error(J);else console.error(l.red(`Error: ${z}`));console.error(l.yellow(`
20
+ Usage:`),Q.help()),process.exit(1)}).parse();
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ var H=Object.create;var{getPrototypeOf:I,defineProperty:B,getOwnPropertyNames:J}=Object;var K=Object.prototype.hasOwnProperty;var P=(j,y,z)=>{z=j!=null?H(I(j)):{};let q=y||!j||!j.__esModule?B(z,"default",{value:j,enumerable:!0}):z;for(let x of J(j))if(!K.call(q,x))B(q,x,{get:()=>j[x],enumerable:!0});return q};var Q=import.meta.require;import L from"cli-table3";import A from"chalk";function E(j,y={}){let q={...{chars:{top:"\u2500","top-mid":"\u2500","top-left":" ","top-right":" ",bottom:"\u2500","bottom-mid":"\u2500","bottom-left":" ","bottom-right":" ",left:" ","left-mid":" ",mid:"\u2500","mid-mid":"\u2500",right:" ","right-mid":" ",middle:" "},style:{head:[],border:[],compact:!0},wordWrap:!0},...y,head:j.map((x)=>A.bold(x))};return new L(q)}function M(j,y,z={}){let q=E(j,z);if(Array.isArray(y))y.forEach((x)=>{q.push(x)});return q.toString()}function N(j){switch(j){case"running":return A.green;case"stopped":return A.yellow;case"failed":return A.red;case"registered":return A.blue;default:return A.gray}}var X={createTable:E,createTableWithData:M,getStatusColor:N};export{N as getStatusColor,X as default,M as createTableWithData,E as createTable};
3
+ export{P as a,Q as b,X as c};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fnet/cli",
3
- "version": "0.2.10",
3
+ "version": "0.3.1",
4
4
  "files": [
5
5
  "dist",
6
6
  "template"
@@ -8,10 +8,10 @@
8
8
  "type": "module",
9
9
  "description": "CLI for Flownet",
10
10
  "scripts": {
11
- "build": "rollup --config",
12
- "build:dev": "rollup --config --sourcemap --environment DEVELOPMENT",
11
+ "build": "bun run build.js",
12
+ "build:dev": "DEVELOPMENT=1 bun run build.js",
13
13
  "deploy": "bun publish --access public",
14
- "watch": "rollup --config --watch --sourcemap --environment DEVELOPMENT"
14
+ "watch": "DEVELOPMENT=1 bun run build.js --watch"
15
15
  },
16
16
  "repository": {
17
17
  "type": "git",
@@ -31,7 +31,7 @@
31
31
  "@flownet/lib-to-nextjs": "^0.3.10",
32
32
  "@flownet/lib-to-webos": "^0.3.16",
33
33
  "@fnet/auto-conda-env": "^0.2.1",
34
- "@fnet/config": "^0.2.28",
34
+ "@fnet/config": "^0.2.29",
35
35
  "@fnet/dir-zipper": "^0.1.8",
36
36
  "@fnet/expression": "^0.1.30",
37
37
  "@fnet/files-to-gcs": "^0.3.12",
@@ -47,7 +47,7 @@
47
47
  "@fnet/to-pyip": "^0.2.1",
48
48
  "@fnet/to-rust": "^0.1.14",
49
49
  "@fnet/up-list-files": "^0.1.14",
50
- "@fnet/yaml": "^0.1.42",
50
+ "@fnet/yaml": "^0.1.45",
51
51
  "@node-red/util": "^4.1.1",
52
52
  "ajv": "^8.17.1",
53
53
  "ajv-formats": "^3.0.1",
@@ -68,7 +68,7 @@
68
68
  "tree-kill": "^1.2.2",
69
69
  "typescript": "^5.9.3",
70
70
  "yaml": "^2.8.1",
71
- "yargs": "^17.7.2"
71
+ "yargs": "^18.0.0"
72
72
  },
73
73
  "bin": {
74
74
  "fnet": "dist/fnet/index.js",
@@ -78,7 +78,7 @@
78
78
  "fservice": "dist/fservice/index.js"
79
79
  },
80
80
  "devDependencies": {
81
- "@rollup/plugin-commonjs": "^28.0.7",
81
+ "@rollup/plugin-commonjs": "^28.0.8",
82
82
  "@rollup/plugin-json": "^6.1.0",
83
83
  "@rollup/plugin-node-resolve": "^16.0.3",
84
84
  "@rollup/plugin-replace": "^6.0.2",
@@ -72,14 +72,14 @@
72
72
  {% if atom.doc.features.cli.enabled %}
73
73
  {% if atom.doc.features.project.format ==='cjs' %}
74
74
  ,"cli": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.dir}}/index.cjs"
75
- {% if atom.doc.features.cli.mcp.enabled===true %}
75
+ {% if atom.doc.features.cli.mcp.enabled !== false %}
76
76
  ,"mcp": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.dir}}/index.cjs --cli-mode=mcp"
77
77
  ,"mcp-inspect": "bunx @modelcontextprotocol/inspector bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.dir}}/index.cjs --cli-mode=mcp"
78
78
  {% endif %}
79
79
  {% else %}
80
80
  ,"cli": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.output.file}}"
81
81
  ,"cli:dev": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.input.file}}"
82
- {% if atom.doc.features.cli.mcp.enabled===true %}
82
+ {% if atom.doc.features.cli.mcp.enabled !== false %}
83
83
  ,"cli:mcp": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.output.file}} --cli-mode=mcp"
84
84
  ,"cli:mcp:inspect": "bunx @modelcontextprotocol/inspector bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.output.file}} --cli-mode=mcp"
85
85
  ,"cli:mcp:dev": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.input.file}} --cli-mode=mcp"
@@ -257,11 +257,11 @@ run()
257
257
  {% endmacro %}
258
258
 
259
259
  {# Main template starts here #}
260
- import argv from '../default/input.args.js';
260
+ import argv,{argsParser} from '../default/input.args.js';
261
261
  import { schema as inputSchema } from '../default/validate_input.js';
262
262
  import { default as Engine } from '../default/{{atom.doc.features.cli_default_entry_file or atom.doc.features.main_default_entry_file}}';
263
263
 
264
- {% if atom.doc.features.cli.mcp.enabled===true %}
264
+ {% if atom.doc.features.cli.mcp.enabled !== false %}
265
265
  {{ importMcpDependencies() }}
266
266
  {% elif atom.doc.features.cli.http.enabled===true %}
267
267
  // Using express for HTTP mode
@@ -271,7 +271,6 @@ import express from 'express';
271
271
  {% if atom.doc.features.cli.extend===true %}
272
272
  {# TYPE 1 #}
273
273
  import { default as runExtended } from '../../../cli/index.js';
274
- import argsParser from 'yargs-parser';
275
274
 
276
275
  const run = async () => {
277
276
  const args = argsParser(process.argv.slice(2));
@@ -279,7 +278,7 @@ import express from 'express';
279
278
 
280
279
  {{ defaultModeExtended() }}
281
280
 
282
- {% if atom.doc.features.cli.mcp.enabled===true %}
281
+ {% if atom.doc.features.cli.mcp.enabled !== false %}
283
282
  {{ mcpModeCodeExtended('runExtended') }}
284
283
  {% endif %}
285
284
 
@@ -294,7 +293,7 @@ import express from 'express';
294
293
  {{ runWithThenCatch() }}
295
294
  {% else %}
296
295
  {# TYPE 2 #}
297
- import argsParser from 'yargs-parser';
296
+ import { argsParser } from '@fnet/args';
298
297
  const run = async () => {
299
298
  const args =argsParser(process.argv.slice(2));
300
299
  const cliMode = args['cli-mode'] || args.cli_mode || 'default';
@@ -302,7 +301,7 @@ import express from 'express';
302
301
 
303
302
  {{ defaultModeEngine('engine') }}
304
303
 
305
- {% if atom.doc.features.cli.mcp.enabled===true %}
304
+ {% if atom.doc.features.cli.mcp.enabled !== false %}
306
305
  {{ mcpModeCodeEngine('engine') }}
307
306
  {% endif %}
308
307
 
@@ -11,23 +11,21 @@
11
11
 
12
12
  {% if atom.doc.features.project.format==='esm' %}
13
13
  {# ESM Format #}
14
- import argv from '../default/input.args.js';
14
+ import argv,{argsParser} from '../default/input.args.js';
15
15
  import { schema as inputSchema } from '../default/validate_input.js';
16
16
  import { default as Engine } from '../default/{{atom.doc.features.cli_default_entry_file or atom.doc.features.main_default_entry_file}}';
17
17
  {% if atom.doc.features.cli.extend===true %}
18
18
  import { default as runExtended } from '../../../cli/index.js';
19
19
  {% endif %}
20
- import argsParser from 'yargs-parser';
21
20
 
22
21
  {% elif atom.doc.features.project.format==='cjs' %}
23
22
  {# CJS Format #}
24
- const argv = require('../default/input.args.js');
23
+ const { default:argv,argsParser } = require('../default/input.args.js');
25
24
  const { schema: inputSchema } = require('../default/validate_input.js');
26
25
  const { default: Engine } = require('../default/{{atom.doc.features.cli_default_entry_file or atom.doc.features.main_default_entry_file}}');
27
26
  {% if atom.doc.features.cli.extend===true %}
28
27
  const { default: runExtended } = require('../../../cli/index.js');
29
28
  {% endif %}
30
- const argsParser = require('yargs-parser');
31
29
 
32
30
  {% endif %}
33
31
 
@@ -42,7 +42,7 @@ const http = require('http');
42
42
  {% endif %}
43
43
  {% endif %}
44
44
 
45
- {% if atom.doc.features.cli.mcp.enabled===true or atom.doc.features.cli.webhook.enabled===true %}
45
+ {% if atom.doc.features.cli.mcp.enabled !== false or atom.doc.features.cli.webhook.enabled===true %}
46
46
  // Shared: crypto module (used by MCP and Webhook modes)
47
47
  {% if atom.doc.features.project.format==='esm' %}
48
48
  import crypto from 'crypto';
@@ -57,7 +57,7 @@ const crypto = require('crypto');
57
57
  Import dependencies for ALL enabled CLI modes
58
58
  Multiple modes can be enabled simultaneously
59
59
  -------------------------------------------------------------------------- #}
60
- {% if atom.doc.features.cli.mcp.enabled===true %}
60
+ {% if atom.doc.features.cli.mcp.enabled !== false %}
61
61
  {% include "./modes/mcp/imports.njk" %}
62
62
  {% endif %}
63
63
 
@@ -107,7 +107,7 @@ const run = async () => {
107
107
  --------------------------------------------------------------------------
108
108
  Model Context Protocol server with multiple transport options
109
109
  -------------------------------------------------------------------------- #}
110
- {% if atom.doc.features.cli.mcp.enabled===true %}
110
+ {% if atom.doc.features.cli.mcp.enabled !== false %}
111
111
  {% include "./modes/mcp/index.njk" %}
112
112
  {% endif %}
113
113
 
@@ -170,7 +170,7 @@ const run = async () => {
170
170
  UNKNOWN MODE HANDLER
171
171
  -------------------------------------------------------------------------- #}
172
172
  console.error(`Unknown CLI mode: ${cliMode}`);
173
- console.error(`Available modes: default{% if atom.doc.features.cli.mcp.enabled===true %}, mcp{% endif %}{% if atom.doc.features.cli.http.enabled===true %}, http{% endif %}{% if atom.doc.features.cli.pipeline.enabled===true %}, pipeline{% endif %}{% if atom.doc.features.cli.websocket.enabled===true %}, websocket{% endif %}{% if atom.doc.features.cli.webhook.enabled===true %}, webhook{% endif %}`);
173
+ console.error(`Available modes: default{% if atom.doc.features.cli.mcp.enabled !== false %}, mcp{% endif %}{% if atom.doc.features.cli.http.enabled===true %}, http{% endif %}{% if atom.doc.features.cli.pipeline.enabled===true %}, pipeline{% endif %}{% if atom.doc.features.cli.websocket.enabled===true %}, websocket{% endif %}{% if atom.doc.features.cli.webhook.enabled===true %}, webhook{% endif %}`);
174
174
  process.exit(1);
175
175
  };
176
176
 
@@ -1,9 +1,9 @@
1
1
  {% if atom.doc.features.project.format === 'esm' %}
2
- import fnetArgs from '@fnet/args';
2
+ import fnetArgs,{argsParser} from '@fnet/args';
3
3
  import validate,{schema as inputSchema} from "./validate_input.js";
4
4
 
5
5
  {% elif atom.doc.features.project.format === 'cjs' %}
6
- const fnetArgs = require('@fnet/args');
6
+ const {default:fnetArgs,argsParser} = require('@fnet/args');
7
7
  const validate,{schema as inputSchema} = require("./validate_input.js");
8
8
  {% endif %}
9
9
 
@@ -75,6 +75,7 @@
75
75
  return await fnetArgs({schema,initial,validate,packageCallback});
76
76
  };
77
77
 
78
+ export { argsParser };
78
79
  {% elif atom.doc.features.project.format === 'cjs' %}
79
80
 
80
81
  module.exports = async () => {
@@ -119,4 +120,6 @@
119
120
 
120
121
  return await fnetArgs({schema,initial,validate,packageCallback});
121
122
  };
123
+
124
+ module.exports.argsParser = argsParser;
122
125
  {% endif %}
@@ -71,14 +71,14 @@
71
71
  {% if atom.doc.features.cli.enabled %}
72
72
  {% if atom.doc.features.project.format ==='cjs' %}
73
73
  ,"cli": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.dir}}/index.cjs"
74
- {% if atom.doc.features.cli.mcp.enabled===true %}
74
+ {% if atom.doc.features.cli.mcp.enabled !== false %}
75
75
  ,"mcp": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.dir}}/index.cjs --cli-mode=mcp"
76
76
  ,"mcp-inspect": "bunx @modelcontextprotocol/inspector bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.dir}}/index.cjs --cli-mode=mcp"
77
77
  {% endif %}
78
78
  {% else %}
79
79
  ,"cli": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.output.file}}"
80
80
  ,"cli:dev": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.input.file}}"
81
- {% if atom.doc.features.cli.mcp.enabled===true %}
81
+ {% if atom.doc.features.cli.mcp.enabled !== false %}
82
82
  ,"cli:mcp": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.output.file}} --cli-mode=mcp"
83
83
  ,"cli:mcp:inspect": "bunx @modelcontextprotocol/inspector bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.output.file}} --cli-mode=mcp"
84
84
  ,"cli:mcp:dev": "bun {{atom.doc.features.cli.node_options}} {{atom.doc.features.cli.input.file}} --cli-mode=mcp"