@fnet/cli 0.116.2 → 0.117.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fnet/index.js +1 -1
- package/dist/fnode/{index.DMkgR1Dh.js → index.B1G_No8j.js} +1 -1
- package/dist/fnode/index.BqI7rTjk.js +1 -0
- package/dist/fnode/{index.D3C-8oZW.js → index.DnA30tC4.js} +1 -1
- package/dist/fnode/index.js +1 -1
- package/dist/fservice/index.js +2 -0
- package/package.json +8 -7
- package/template/fnet/bun/src/cli/index.js.njk +1 -0
- package/template/fnet/bun/src/default/input.args.js.njk +6 -4
- package/template/fnet/node/src/cli/index.js.njk +9 -22
- package/template/fnet/node/src/default/input.args.js.njk +6 -4
- package/template/fnode/bun/src/cli/index.js.njk +1 -0
- package/template/fnode/bun/src/default/input.args.js.njk +6 -4
- package/template/fnode/node/src/cli/index.js.njk +14 -15
- package/template/fnode/node/src/default/input.args.js.njk +6 -4
- package/dist/fnode/index.D4sPJLOP.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"node:fs";import t from"node:path";import a from"nunjucks";import s from"@flownet/lib-parse-imports-js";import o from"@flownet/lib-parse-node-url";import{B as i,c as r,a as n}from"./index.DIZA_GzC.js";import p from"lodash.merge";import{f as l,i as c,a as d,b as u,c as f,d as m,p as b,e as g,g as h,h as _,j as w,k as y,l as x,m as v,r as k}from"./index.D4sPJLOP.js";import j from"@fnet/npm-list-versions";import D from"@fnet/shelljs";import"node:crypto";import"yaml";import"chalk";import"@flownet/lib-atom-api-js";import"@fnet/config";import"@fnet/list-files";import"redis";import"@flownet/lib-is-redis-online";import"@fnet/yaml";import"@flownet/lib-render-templates-dir";import"@fnet/npm-pick-versions";import"object-hash";import"ajv/dist/2020.js";import"ajv/dist/standalone/index.js";import"ajv-formats";import"./index.js";import"node:url";import"yargs";import"node:util";import"tree-kill";import"node:child_process";import"node:os";import"@fnet/prompt";import"fs";import"path";import"@fnet/shell-flow";function C({dir:a,name:s="index"}){let o=t.resolve(a,`./${s}.tsx`);if(e.existsSync(o)||(o=t.resolve(a,`./${s}.ts`)),e.existsSync(o)||(o=t.resolve(a,`./${s}.jsx`)),e.existsSync(o)||(o=t.resolve(a,`./${s}.js`)),!e.existsSync(o))return{};const i=o,r=t.extname(o);return{file:i,ext:r,ts:".ts"===r||".tsx"===r,name:s}}async function S(e){const{atom:a,context:o,setProgress:i}=e;i("Initializing features..."),a.doc.features=a.doc.features||{};const r=a.doc.features;r.project=r.project||{},r.project.format=r.project.format||r.project_format||"esm",r.project_format=r.project.format,r.dts_enabled=!0===r.dts||void 0!==r.dts&&!1!==r.dts;const n=t.resolve(o.project.projectDir),b=C({dir:t.resolve(n,"./app")});if(b.file){i("Parsing app entry imports...");let e=await s({file:b.file,recursive:!0}),t=e.all.some((e=>!0===e.usesJSX&&"local"===e.type));r.app_uses_jsx=t,r.app_has_entry=!0,e=await s({file:b.file}),t=e.all.some((e=>!0===e.usesJSX&&"local"===e.type)),r.app_entry_uses_jsx=t,r.app_entry_is_ts=b.ts,r.app_entry_ext=b.ext}const g=C({dir:t.resolve(n,"./cli")});if(g.file){i("Parsing cli entry imports...");let e=await s({file:g.file,recursive:!0}),t=e.all.some((e=>!0===e.usesJSX&&"local"===e.type));r.cli_uses_jsx=t,r.cli_has_entry=!0,e=await s({file:g.file}),t=e.all.some((e=>!0===e.usesJSX&&"local"===e.type)),r.cli_entry_uses_jsx=t,r.cli_entry_is_ts=g.ts,r.cli_entry_ext=g.ext}if("workflow.lib"===a.type){const e=C({dir:t.resolve(n,"./src")});if(e.file){i("Parsing src entry imports...");let t=await s({file:e.file,recursive:!0}),a=t.all.some((e=>!0===e.usesJSX&&"local"===e.type));r.src_uses_jsx=a,r.src_has_entry=!0,t=await s({file:e.file}),a=t.all.some((e=>!0===e.usesJSX&&"local"===e.type)),r.src_entry_uses_jsx=a,r.src_entry_is_ts=e.ts,r.src_entry_ext=e.ext}}const h=Reflect.has(r,"app_entry_uses_jsx")?!0===r.app_entry_uses_jsx:!0===r.src_entry_uses_jsx,_=Reflect.has(r,"cli_entry_uses_jsx")?!0===r.cli_entry_uses_jsx:!0===r.src_entry_uses_jsx;r.form_enabled=h||_||!0===r.form||!0===r.form?.enabled,r.multiple_enabled=r.multiple_enabled||!0===r.multiple||!0===r.multiple?.enabled,!1===r.app?r.app={enabled:!1}:!0===r.app?r.app={enabled:!0,extend:!0===r.app_has_entry,export:!0,react:h}:r.app={enabled:!0,extend:!0===r.app_has_entry,export:!0,react:h,...r.app||{}},r.app.enabled=!0===r.app.enabled&&(!0===a.doc.features.form_enabled||!0===r.app.extend||!0===r.app.enabled),r.app.format=r.app.format||"esm",r.app.folder=r.app.folder||r.app.format||"default",!1===r.cli?r.cli={enabled:!1}:!0===r.cli?r.cli={enabled:!0,extend:!0===r.cli_has_entry,export:!0,react:_}:r.cli={enabled:!0,extend:!0===r.cli_has_entry,export:!0,react:_,...r.cli||{}},r.cli.enabled=!0===r.cli.enabled&&(!1===a.doc.features.form_enabled||!0===r.cli.extend||!0===r.cli.enabled),r.cli.format=r.cli.format||"esm",r.cli.folder=r.cli.folder||r.cli.folder||"esm",r.cli.node_options=r.cli.node?.options||r.cli.node_options||"",r.cli.bin=r.cli.bin||a.doc.name,r.cli.installable=!0===r.cli.installable,r.cli.enabled&&(a.doc["npm::bin"]=r.cli.bin,console.log(`Setting npm::bin to ${r.cli.bin} from features.cli.bin`)),r.json=r.cli.enabled||r.json;const w={cjs:{format:"cjs",context:r.form_enabled?"window":"global",babel:!0===r.src_uses_jsx||!1,browser:!1,replace:!0,terser:!0,enabled:!1!==r.cjs,copy:!1},esm:{format:"esm",context:r.form_enabled?"window":"global",babel:!0===r.src_uses_jsx||!1,browser:!1,replace:!0,terser:!1,enabled:!1!==r.esm,copy:!0},iife:{format:"iife",context:r.form_enabled?"window":"global",babel:!0,browser:!0,replace:!0,enabled:!0===r.iife,terser:!0,copy:!1}};!0===r.webos&&(w.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"}}}),!0===r.electron&&(w.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"}),!0===r.nextjs&&(w.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"}),!0===r.ios&&(w.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"}),!0===r.macos&&(w.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"}),!0===r.app.enabled&&(r.app.dir=`./dist/app/${r.app.folder}`,w.app={format:r.app.format,browser:!0,babel:!0,context:"window",replace:!0,input:"./src/app/index.js",output_dir:r.app.dir,terser:!0,output_exports:!1===r.app.export?"none":"auto",browsersync:!0}),!0===r.cli.enabled&&(r.cli.dir=`./dist/cli/${r.cli.folder}`,w.cli={format:r.cli.format,context:"global",babel:!0===r.src_uses_jsx||!0===r.cli_uses_jsx||!1,browser:!1,replace:!0,enabled:!0,input:"./src/cli/index.js",output_dir:r.cli.dir,banner:"#!/usr/bin/env node",terser:!0,output_exports:!1===r.cli.export?"none":"auto"});const y={server:".",startPath:`${t.normalize(r.app.dir||".")}`,files:[t.normalize("./dist/**/*")],cors:!0,open:!1};r.babel_options=p({targets:{browsers:"last 9 versions, not dead",node:"18"}},r.babel_options||r.babel?.options),r.browsersync_options=p(y,r.browsersync_options||r.browsersync?.options||{}),r.replace_options=p({},r.replace_options||r.replace?.options||{}),Reflect.has(r.browsersync_options,"proxy")&&delete r.browsersync_options.server,r.rollup=r.rollup||{},r.rollup_output=p(w,r.rollup_output||r.rollup?.output||{}),r.preact_enabled=!0===r.preact||r.preact&&!1!==r.preact?.enabled;let x=Object.keys(w);for(const e of x){const t=w[e];t&&(!1!==r.rollup[e]?(t.babel_options=t.babel_options||r.babel_options,t.browsersync_options=p(r.browsersync_options,t.browsersync_options),t.replace_options=p(r.replace_options,t.replace_options),r.preact_enabled&&(t.alias_enabled=!0,t.alias=t.alias||{},t.alias.entries=t.alias.entries||{},t.alias.entries.react="preact/compat",t.alias.entries["react-dom"]="preact/compat"),(r.form_enabled||r.babel)&&(t.babel=!0)):delete r.rollup_output[e])}x=Object.keys(r.rollup_output),r.babel_enabled=x.some((e=>!0===r.rollup_output[e].babel)),r.browser_enabled=x.some((e=>!0===r.rollup_output[e].babel)),r.browsersync_enabled=!1!==r.browsersync&&x.some((e=>!0===r.rollup_output[e].browsersync)),r.browsersync_enabled=r.browsersync_enabled&&r.app.enabled,r.dependency_auto_enabled=!1!==r.dependency_auto&&!1!==r.dependency_auto?.enabled,r.npm_install_flags=r.npm_install_flags||"",r.react_version=r.react_version||r.react?.version||18,c(e),d(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"wasm",packages:[["@rollup/plugin-wasm","^6"]]},features:s,packageDevDependencies:a})}(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"terser",packages:[["@rollup/plugin-terser","^0.4"]]},features:s,packageDevDependencies:a})}(e),u(e),f(e),m(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"analyzer",packages:[["rollup-plugin-analyzer","^3"]],options:{summaryOnly:!0,limit:12},explicit:!0},features:s,packageDevDependencies:a})}(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"visualizer",packages:[["rollup-plugin-visualizer","^5"]]},features:s,packageDevDependencies:a})}(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"polyfill",packages:[["rollup-plugin-node-polyfills","^0.2"]]},features:s,packageDevDependencies:a})}(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"nunjucks",packages:[["@fnet/rollup-plugin-nunjucks","0.1.8"]]},features:s,packageDevDependencies:a})}(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({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:s,packageDevDependencies:a})}(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"gzip",packages:[["rollup-plugin-gzip","^4"]],explicit:!0},features:s,packageDevDependencies:a})}(e)}class A extends i{async initRuntime(){await S(this.apiContext),await async function({atom:e,packageDependencies:t,packageDevDependencies:a,setProgress:s}){s("Initializing dependencies");const o=e.doc.dependencies||[];if(o.filter((e=>!e.dev)).forEach((e=>t.push(e))),o.filter((e=>e.dev)).forEach((e=>a.push(e))),"workflow"===e.type&&(t.push({package:"get-value",version:"^3"}),t.push({package:"set-value",version:"^4"})),e.doc.features.form_enabled&&e.doc.features.dependency_auto_enabled){let a="^18.2";s("Fetching React versions"),a=`^${(await j({name:"react",groupBy:{major:!0}})).find((t=>t[0]===e.doc.features.react_version.toString()))[0]}`,t.push({package:"react",version:a}),t.push({package:"react-dom",version:a}),"workflow"===e.type&&(t.push({package:"@fnet/react-app",version:"^0.1"}),t.push({package:"@fnet/react-app-state",version:"^0.1"}))}e.doc.features.preact_enabled&&t.push({package:"preact",version:"^10"}),!0===e.doc.features.cli.enabled&&(t.push({package:"@fnet/args",version:"^0.1"}),a.push({package:"ajv",version:"^8"}),e.doc.features.cli.fargs&&!1!==e.doc.features.cli.fargs?.enabled&&t.push({package:"@fnet/config",version:"0.2.21"}),e.doc.features.cli.mcp&&!0===e.doc.features.cli.mcp.enabled&&(t.push({package:"@modelcontextprotocol/sdk",version:"^1.10"}),t.push({package:"express",version:"^4.18"}))),e.doc.features.render&&!1!==e.doc.features.render.enabled&&a.push({package:"@flownet/lib-render-templates-dir",version:"0.1.19"}),a.push({package:"@babel/core",version:"^7"}),a.push({package:"@rollup/plugin-commonjs",version:"^28"}),a.push({package:"@rollup/plugin-node-resolve",version:"^16"}),a.push({package:"@rollup/plugin-replace",version:"^6"}),a.push({package:"rollup",version:"^4"}),e.doc.features.dts_enabled&&a.push({package:"rollup-plugin-dts",version:"^6"}),a.push({package:"rollup-plugin-peer-deps-external",version:"^2"}),a.push({package:"@rollup/plugin-alias",version:"^5"}),a.push({package:"fs-extra",version:"^11"}),e.doc.features.babel_enabled&&(a.push({package:"@rollup/plugin-babel",version:"^6"}),a.push({package:"@babel/preset-env",version:"^7"}),a.push({package:"@babel/preset-react",version:"^7"}),e.doc.features.babel?.options?.plugins?.forEach((e=>{switch(e[0]){case"@babel/plugin-proposal-decorators":a.push({package:"@babel/plugin-proposal-decorators",version:"^7"});break;case"@babel/plugin-proposal-class-properties":a.push({package:"@babel/plugin-proposal-class-properties",version:"^7"});break;case"@babel/plugin-proposal-private-methods":a.push({package:"@babel/plugin-proposal-private-methods",version:"^7"});break;case"@babel/plugin-proposal-private-property-in-object":a.push({package:"@babel/plugin-proposal-private-property-in-object",version:"^7"});break;case"@babel/plugin-proposal-optional-chaining":a.push({package:"@babel/plugin-proposal-optional-chaining",version:"^7"})}}))),a.push({package:"@fnet/rollup-plugin-delete",version:"0.1.10"}),e.doc.features.browsersync_enabled&&a.push({package:"@fnet/rollup-plugin-browsersync",version:"0.1.11"})}(this.apiContext),await this.initLibraryDir(),await this.initNunjucks(),await this.initLibs()}async initLibs(){this.setProgress({message:"Initializing external libs."});const e=[{name:this.atom.doc.name,type:"atom",parent_id:this.atom.parent_id}];this.libs=e,await this.initAtomLibsAndDeps({libs:e,packageDependencies:this.apiContext.packageDependencies})}async initAtomLibsAndDeps({libs:e,packageDependencies:t}){const a=e.filter((e=>"atom"===e.type));for(let e=0;e<a.length;e++){const s=a[e],o=await this.findAtomLibrary({url:s.name});s.atom=o;const i=o.doc.dependencies?.filter((e=>void 0===e.repo||"npm"===e.repo));i?.forEach((e=>{const a=t.find((t=>t.package===e.package));a?"string"==typeof e.path?(a.path||[]).some((t=>t===e.path))||(a.path=a.path||[],a.path.push(e.path)):Array.isArray(e.path)&&e.path.forEach((e=>{(a.path||[]).some((t=>t===e))||(a.path=a.path||[],a.path.push(e))})):t.push(e)}))}t.sort(((e,t)=>e.package?.localeCompare(t.package)))}async findAtomLibrary({url:e}){const a=o({url:e});if(!a)throw new Error(`Invalid package name: ${e}`);if(a.protocol||(a.protocol=this.context.protocol),"ac:"===a.protocol){const t=a.pathname.split("/");if(1===t.length)return await this.apiContext.Atom.first({where:{name:e,parent_id:this.atomConfig.env.ATOM_LIBRARIES_ID,type:"workflow.lib"}});if(2===t.length){const e=await this.apiContext.Atom.first({where:{name:t[0],parent_id:this.atomConfig.env.ATOM_LIBRARIES_ID,type:"folder"}});return await this.apiContext.Atom.first({where:{name:t[1],parent_id:e.id,type:"workflow.lib"}})}}else if("local:"===a.protocol){const e=this.atom;e.protocol="local:",e.doc.dependencies=e.doc.dependencies||[],e.name=e.doc.name;const a=t.resolve(this.context.projectSrcDir,"index.js"),o=await s({file:a,recursive:!0}),i=e.doc.dependencies,r=o.all;for await(const e of r){if("npm"!==e.type)continue;if(i.find((t=>t.package===e.package)))continue;const t=await b({name:e.package,projectDir:this.context.projectDir,setProgress:this.apiContext.setProgress});i.push({package:e.package,subpath:e.subpath,version:t.minorRange,type:"npm"})}return e}}async createAtomLibFiles({libs:a}){await this.setProgress({message:"Creating external lib files."}),this.atom.typesDir="./types";const s=a.filter((e=>"atom"===e.type));for(let a=0;a<s.length;a++){const o=s[a].atom,i=this.context.projectDir;if("local:"===o.protocol){const a=t.resolve(this.context.projectSrcDir,`${o.fileName||o.name}.js`),s=t.relative(t.join(this.context.projectDir,"src","default"),a);if(!e.existsSync(a)){e.mkdirSync(t.dirname(a),{recursive:!0});let s="export default async (args)=>{\n";s+="}",e.writeFileSync(a,s,"utf8")}o.relativePath=s.split(t.sep).join("/"),this.atom.typesDir=`./types/${t.basename(i)}/src`}else{const a=t.join(i,"src","libs",`${o.id}.js`),s=o.doc.contents?.find((e=>"esm"===e.format))||o.doc;e.writeFileSync(a,s.content,"utf8")}}}async createEngine(){await this.setProgress({message:"Creating engine file."});const s={libs:this.libs.filter((e=>"atom"===e.type)),libraryAtom:this.atom,atom:this.atom},o=this.context.templateDir,i=a.compile(e.readFileSync(t.resolve(o,t.join("src","default","engine.js.njk")),"utf8"),this.apiContext.njEnv).render(s),r=this.context.projectDir,n=t.resolve(r,t.join("src","default","index.js"));e.writeFileSync(n,i,"utf8")}async build(){try{this.fileMode&&(await this.createAtomLibFiles({libs:this.libs}),await this.createEngine(),await this.createProjectYaml(),await r(this.apiContext),await g(this.apiContext),await n(this.apiContext),await h(this.apiContext),await _(this.apiContext),await w(this.apiContext),await async function({atom:o,setProgress:i,context:r,packageDependencies:n}){await i({message:"Creating rollup file."});const p={atom:o,packageDependencies:n},l=t.resolve(r.projectDir,"src","default/index.js");if(!e.existsSync(l))throw new Error(`Entry file not found: ${l}`);const c=(await s({file:l,recursive:!0})).all.filter((e=>"node"===e.type)).map((e=>e.path)),d=o.doc.features.rollup_output,u=Object.keys(d);for(let e=0;e<u.length;e++){const t=d[u[e]];if(!0===t.browser&&c.length>0){t.globals_enabled=!0,t.globals=t.globals||[],t.globals=t.globals.concat(c.map((e=>({key:e,value:e})))),t.alias_enabled=!0,t.alias=t.alias||{},t.alias.entries=t.alias.entries||{};for(let e=0;e<c.length;e++){const a=c[e];t.alias.entries[a]=`node:${a}`,t.alias.entries[`node:${a}`]=a}t.external_enabled=!0,t.external=t.external||[],t.external=t.external.concat(c)}}const f=r.templateDir;let m=a.compile(e.readFileSync(t.resolve(f,"rollup.config.mjs.njk"),"utf8"),a.configure(f)).render(p);const b=r.projectDir;let g=t.resolve(b,"rollup.config.mjs");e.writeFileSync(g,m,"utf8")}(this.apiContext),await y(this.apiContext),await x(this.apiContext),await async function({atom:e,setProgress:t,context:a}){if(!e.doc.features.dts_enabled)return;const s=a.projectDir;if(await t({message:"Creating .d.ts"}),0!==(await D("tsc",{cwd:s})).code)throw new Error("Couldnt create .d.ts files.")}(this.apiContext),this.buildMode&&(await v(this.apiContext),await k(this.apiContext),this.deployMode&&await this.deploy())),await this._cache_set(this.buildKey,{status:"COMPLETED"})}catch(e){throw await this._cache_set(this.buildKey,{status:"FAILED",message:e.message||e}),console.log(e),e}}}export{A as default};
|
|
1
|
+
import e from"node:fs";import t from"node:path";import a from"nunjucks";import s from"@flownet/lib-parse-imports-js";import o from"@flownet/lib-parse-node-url";import{B as i,c as r,a as n}from"./index.DIZA_GzC.js";import p from"lodash.merge";import{f as l,i as c,a as d,b as u,c as f,d as m,p as b,e as g,g as h,h as _,j as w,k as y,l as x,m as v,r as k}from"./index.BqI7rTjk.js";import j from"@fnet/npm-list-versions";import D from"@fnet/shelljs";import"node:crypto";import"yaml";import"chalk";import"@flownet/lib-atom-api-js";import"@fnet/config";import"@fnet/list-files";import"redis";import"@flownet/lib-is-redis-online";import"@fnet/yaml";import"@flownet/lib-render-templates-dir";import"@fnet/npm-pick-versions";import"object-hash";import"ajv/dist/2020.js";import"ajv/dist/standalone/index.js";import"ajv-formats";import"./index.js";import"node:url";import"yargs";import"node:util";import"tree-kill";import"node:child_process";import"node:os";import"@fnet/prompt";import"fs";import"path";import"@fnet/shell-flow";function C({dir:a,name:s="index"}){let o=t.resolve(a,`./${s}.tsx`);if(e.existsSync(o)||(o=t.resolve(a,`./${s}.ts`)),e.existsSync(o)||(o=t.resolve(a,`./${s}.jsx`)),e.existsSync(o)||(o=t.resolve(a,`./${s}.js`)),!e.existsSync(o))return{};const i=o,r=t.extname(o);return{file:i,ext:r,ts:".ts"===r||".tsx"===r,name:s}}async function S(e){const{atom:a,context:o,setProgress:i}=e;i("Initializing features..."),a.doc.features=a.doc.features||{};const r=a.doc.features;r.project=r.project||{},r.project.format=r.project.format||r.project_format||"esm",r.project_format=r.project.format,r.dts_enabled=!0===r.dts||void 0!==r.dts&&!1!==r.dts;const n=t.resolve(o.project.projectDir),b=C({dir:t.resolve(n,"./app")});if(b.file){i("Parsing app entry imports...");let e=await s({file:b.file,recursive:!0}),t=e.all.some((e=>!0===e.usesJSX&&"local"===e.type));r.app_uses_jsx=t,r.app_has_entry=!0,e=await s({file:b.file}),t=e.all.some((e=>!0===e.usesJSX&&"local"===e.type)),r.app_entry_uses_jsx=t,r.app_entry_is_ts=b.ts,r.app_entry_ext=b.ext}const g=C({dir:t.resolve(n,"./cli")});if(g.file){i("Parsing cli entry imports...");let e=await s({file:g.file,recursive:!0}),t=e.all.some((e=>!0===e.usesJSX&&"local"===e.type));r.cli_uses_jsx=t,r.cli_has_entry=!0,e=await s({file:g.file}),t=e.all.some((e=>!0===e.usesJSX&&"local"===e.type)),r.cli_entry_uses_jsx=t,r.cli_entry_is_ts=g.ts,r.cli_entry_ext=g.ext}if("workflow.lib"===a.type){const e=C({dir:t.resolve(n,"./src")});if(e.file){i("Parsing src entry imports...");let t=await s({file:e.file,recursive:!0}),a=t.all.some((e=>!0===e.usesJSX&&"local"===e.type));r.src_uses_jsx=a,r.src_has_entry=!0,t=await s({file:e.file}),a=t.all.some((e=>!0===e.usesJSX&&"local"===e.type)),r.src_entry_uses_jsx=a,r.src_entry_is_ts=e.ts,r.src_entry_ext=e.ext}}const h=Reflect.has(r,"app_entry_uses_jsx")?!0===r.app_entry_uses_jsx:!0===r.src_entry_uses_jsx,_=Reflect.has(r,"cli_entry_uses_jsx")?!0===r.cli_entry_uses_jsx:!0===r.src_entry_uses_jsx;r.form_enabled=h||_||!0===r.form||!0===r.form?.enabled,r.multiple_enabled=r.multiple_enabled||!0===r.multiple||!0===r.multiple?.enabled,!1===r.app?r.app={enabled:!1}:!0===r.app?r.app={enabled:!0,extend:!0===r.app_has_entry,export:!0,react:h}:r.app={enabled:!0,extend:!0===r.app_has_entry,export:!0,react:h,...r.app||{}},r.app.enabled=!0===r.app.enabled&&(!0===a.doc.features.form_enabled||!0===r.app.extend||!0===r.app.enabled),r.app.format=r.app.format||"esm",r.app.folder=r.app.folder||r.app.format||"default",!1===r.cli?r.cli={enabled:!1}:!0===r.cli?r.cli={enabled:!0,extend:!0===r.cli_has_entry,export:!0,react:_}:r.cli={enabled:!0,extend:!0===r.cli_has_entry,export:!0,react:_,...r.cli||{}},r.cli.enabled=!0===r.cli.enabled&&(!1===a.doc.features.form_enabled||!0===r.cli.extend||!0===r.cli.enabled),r.cli.format=r.cli.format||"esm",r.cli.folder=r.cli.folder||r.cli.folder||"esm",r.cli.node_options=r.cli.node?.options||r.cli.node_options||"",r.cli.bin=r.cli.bin||a.doc.name,r.cli.installable=!0===r.cli.installable,r.cli.enabled&&(a.doc["npm::bin"]=r.cli.bin,console.log(`Setting npm::bin to ${r.cli.bin} from features.cli.bin`)),r.json=r.cli.enabled||r.json;const w={cjs:{format:"cjs",context:r.form_enabled?"window":"global",babel:!0===r.src_uses_jsx||!1,browser:!1,replace:!0,terser:!0,enabled:!1!==r.cjs,copy:!1},esm:{format:"esm",context:r.form_enabled?"window":"global",babel:!0===r.src_uses_jsx||!1,browser:!1,replace:!0,terser:!1,enabled:!1!==r.esm,copy:!0},iife:{format:"iife",context:r.form_enabled?"window":"global",babel:!0,browser:!0,replace:!0,enabled:!0===r.iife,terser:!0,copy:!1}};!0===r.webos&&(w.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"}}}),!0===r.electron&&(w.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"}),!0===r.nextjs&&(w.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"}),!0===r.ios&&(w.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"}),!0===r.macos&&(w.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"}),!0===r.app.enabled&&(r.app.dir=`./dist/app/${r.app.folder}`,w.app={format:r.app.format,browser:!0,babel:!0,context:"window",replace:!0,input:"./src/app/index.js",output_dir:r.app.dir,terser:!0,output_exports:!1===r.app.export?"none":"auto",browsersync:!0}),!0===r.cli.enabled&&(r.cli.dir=`./dist/cli/${r.cli.folder}`,w.cli={format:r.cli.format,context:"global",babel:!0===r.src_uses_jsx||!0===r.cli_uses_jsx||!1,browser:!1,replace:!0,enabled:!0,input:"./src/cli/index.js",output_dir:r.cli.dir,banner:"#!/usr/bin/env node",terser:!0,output_exports:!1===r.cli.export?"none":"auto"});const y={server:".",startPath:`${t.normalize(r.app.dir||".")}`,files:[t.normalize("./dist/**/*")],cors:!0,open:!1};r.babel_options=p({targets:{browsers:"last 9 versions, not dead",node:"18"}},r.babel_options||r.babel?.options),r.browsersync_options=p(y,r.browsersync_options||r.browsersync?.options||{}),r.replace_options=p({},r.replace_options||r.replace?.options||{}),Reflect.has(r.browsersync_options,"proxy")&&delete r.browsersync_options.server,r.rollup=r.rollup||{},r.rollup_output=p(w,r.rollup_output||r.rollup?.output||{}),r.preact_enabled=!0===r.preact||r.preact&&!1!==r.preact?.enabled;let x=Object.keys(w);for(const e of x){const t=w[e];t&&(!1!==r.rollup[e]?(t.babel_options=t.babel_options||r.babel_options,t.browsersync_options=p(r.browsersync_options,t.browsersync_options),t.replace_options=p(r.replace_options,t.replace_options),r.preact_enabled&&(t.alias_enabled=!0,t.alias=t.alias||{},t.alias.entries=t.alias.entries||{},t.alias.entries.react="preact/compat",t.alias.entries["react-dom"]="preact/compat"),(r.form_enabled||r.babel)&&(t.babel=!0)):delete r.rollup_output[e])}x=Object.keys(r.rollup_output),r.babel_enabled=x.some((e=>!0===r.rollup_output[e].babel)),r.browser_enabled=x.some((e=>!0===r.rollup_output[e].babel)),r.browsersync_enabled=!1!==r.browsersync&&x.some((e=>!0===r.rollup_output[e].browsersync)),r.browsersync_enabled=r.browsersync_enabled&&r.app.enabled,r.dependency_auto_enabled=!1!==r.dependency_auto&&!1!==r.dependency_auto?.enabled,r.npm_install_flags=r.npm_install_flags||"",r.react_version=r.react_version||r.react?.version||18,c(e),d(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"wasm",packages:[["@rollup/plugin-wasm","^6"]]},features:s,packageDevDependencies:a})}(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"terser",packages:[["@rollup/plugin-terser","^0.4"]]},features:s,packageDevDependencies:a})}(e),u(e),f(e),m(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"analyzer",packages:[["rollup-plugin-analyzer","^3"]],options:{summaryOnly:!0,limit:12},explicit:!0},features:s,packageDevDependencies:a})}(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"visualizer",packages:[["rollup-plugin-visualizer","^5"]]},features:s,packageDevDependencies:a})}(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"polyfill",packages:[["rollup-plugin-node-polyfills","^0.2"]]},features:s,packageDevDependencies:a})}(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"nunjucks",packages:[["@fnet/rollup-plugin-nunjucks","0.1.8"]]},features:s,packageDevDependencies:a})}(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({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:s,packageDevDependencies:a})}(e),function(e){const{atom:t,packageDevDependencies:a}=e,s=t.doc.features;l({feature:{name:"gzip",packages:[["rollup-plugin-gzip","^4"]],explicit:!0},features:s,packageDevDependencies:a})}(e)}class A extends i{async initRuntime(){await S(this.apiContext),await async function({atom:e,packageDependencies:t,packageDevDependencies:a,setProgress:s}){s("Initializing dependencies");const o=e.doc.dependencies||[];if(o.filter((e=>!e.dev)).forEach((e=>t.push(e))),o.filter((e=>e.dev)).forEach((e=>a.push(e))),"workflow"===e.type&&(t.push({package:"get-value",version:"^3"}),t.push({package:"set-value",version:"^4"})),e.doc.features.form_enabled&&e.doc.features.dependency_auto_enabled){let a="^18.2";s("Fetching React versions"),a=`^${(await j({name:"react",groupBy:{major:!0}})).find((t=>t[0]===e.doc.features.react_version.toString()))[0]}`,t.push({package:"react",version:a}),t.push({package:"react-dom",version:a}),"workflow"===e.type&&(t.push({package:"@fnet/react-app",version:"^0.1"}),t.push({package:"@fnet/react-app-state",version:"^0.1"}))}e.doc.features.preact_enabled&&t.push({package:"preact",version:"^10"}),!0===e.doc.features.cli.enabled&&(t.push({package:"@fnet/args",version:"^0.1"}),a.push({package:"ajv",version:"^8"}),e.doc.features.cli.fargs&&!1!==e.doc.features.cli.fargs?.enabled&&t.push({package:"@fnet/config",version:"0.2.21"}),e.doc.features.cli.mcp&&!0===e.doc.features.cli.mcp.enabled&&(t.push({package:"@modelcontextprotocol/sdk",version:"^1.10"}),t.push({package:"express",version:"^4.18"}))),e.doc.features.render&&!1!==e.doc.features.render.enabled&&a.push({package:"@flownet/lib-render-templates-dir",version:"0.1.19"}),a.push({package:"@babel/core",version:"^7"}),a.push({package:"@rollup/plugin-commonjs",version:"^28"}),a.push({package:"@rollup/plugin-node-resolve",version:"^16"}),a.push({package:"@rollup/plugin-replace",version:"^6"}),a.push({package:"rollup",version:"^4"}),e.doc.features.dts_enabled&&a.push({package:"rollup-plugin-dts",version:"^6"}),a.push({package:"rollup-plugin-peer-deps-external",version:"^2"}),a.push({package:"@rollup/plugin-alias",version:"^5"}),a.push({package:"fs-extra",version:"^11"}),e.doc.features.babel_enabled&&(a.push({package:"@rollup/plugin-babel",version:"^6"}),a.push({package:"@babel/preset-env",version:"^7"}),a.push({package:"@babel/preset-react",version:"^7"}),e.doc.features.babel?.options?.plugins?.forEach((e=>{switch(e[0]){case"@babel/plugin-proposal-decorators":a.push({package:"@babel/plugin-proposal-decorators",version:"^7"});break;case"@babel/plugin-proposal-class-properties":a.push({package:"@babel/plugin-proposal-class-properties",version:"^7"});break;case"@babel/plugin-proposal-private-methods":a.push({package:"@babel/plugin-proposal-private-methods",version:"^7"});break;case"@babel/plugin-proposal-private-property-in-object":a.push({package:"@babel/plugin-proposal-private-property-in-object",version:"^7"});break;case"@babel/plugin-proposal-optional-chaining":a.push({package:"@babel/plugin-proposal-optional-chaining",version:"^7"})}}))),a.push({package:"@fnet/rollup-plugin-delete",version:"0.1.10"}),e.doc.features.browsersync_enabled&&a.push({package:"@fnet/rollup-plugin-browsersync",version:"0.1.11"})}(this.apiContext),await this.initLibraryDir(),await this.initNunjucks(),await this.initLibs()}async initLibs(){this.setProgress({message:"Initializing external libs."});const e=[{name:this.atom.doc.name,type:"atom",parent_id:this.atom.parent_id}];this.libs=e,await this.initAtomLibsAndDeps({libs:e,packageDependencies:this.apiContext.packageDependencies})}async initAtomLibsAndDeps({libs:e,packageDependencies:t}){const a=e.filter((e=>"atom"===e.type));for(let e=0;e<a.length;e++){const s=a[e],o=await this.findAtomLibrary({url:s.name});s.atom=o;const i=o.doc.dependencies?.filter((e=>void 0===e.repo||"npm"===e.repo));i?.forEach((e=>{const a=t.find((t=>t.package===e.package));a?"string"==typeof e.path?(a.path||[]).some((t=>t===e.path))||(a.path=a.path||[],a.path.push(e.path)):Array.isArray(e.path)&&e.path.forEach((e=>{(a.path||[]).some((t=>t===e))||(a.path=a.path||[],a.path.push(e))})):t.push(e)}))}t.sort(((e,t)=>e.package?.localeCompare(t.package)))}async findAtomLibrary({url:e}){const a=o({url:e});if(!a)throw new Error(`Invalid package name: ${e}`);if(a.protocol||(a.protocol=this.context.protocol),"ac:"===a.protocol){const t=a.pathname.split("/");if(1===t.length)return await this.apiContext.Atom.first({where:{name:e,parent_id:this.atomConfig.env.ATOM_LIBRARIES_ID,type:"workflow.lib"}});if(2===t.length){const e=await this.apiContext.Atom.first({where:{name:t[0],parent_id:this.atomConfig.env.ATOM_LIBRARIES_ID,type:"folder"}});return await this.apiContext.Atom.first({where:{name:t[1],parent_id:e.id,type:"workflow.lib"}})}}else if("local:"===a.protocol){const e=this.atom;e.protocol="local:",e.doc.dependencies=e.doc.dependencies||[],e.name=e.doc.name;const a=t.resolve(this.context.projectSrcDir,"index.js"),o=await s({file:a,recursive:!0}),i=e.doc.dependencies,r=o.all;for await(const e of r){if("npm"!==e.type)continue;if(i.find((t=>t.package===e.package)))continue;const t=await b({name:e.package,projectDir:this.context.projectDir,setProgress:this.apiContext.setProgress});i.push({package:e.package,subpath:e.subpath,version:t.minorRange,type:"npm"})}return e}}async createAtomLibFiles({libs:a}){await this.setProgress({message:"Creating external lib files."}),this.atom.typesDir="./types";const s=a.filter((e=>"atom"===e.type));for(let a=0;a<s.length;a++){const o=s[a].atom,i=this.context.projectDir;if("local:"===o.protocol){const a=t.resolve(this.context.projectSrcDir,`${o.fileName||o.name}.js`),s=t.relative(t.join(this.context.projectDir,"src","default"),a);if(!e.existsSync(a)){e.mkdirSync(t.dirname(a),{recursive:!0});let s="export default async (args)=>{\n";s+="}",e.writeFileSync(a,s,"utf8")}o.relativePath=s.split(t.sep).join("/"),this.atom.typesDir=`./types/${t.basename(i)}/src`}else{const a=t.join(i,"src","libs",`${o.id}.js`),s=o.doc.contents?.find((e=>"esm"===e.format))||o.doc;e.writeFileSync(a,s.content,"utf8")}}}async createEngine(){await this.setProgress({message:"Creating engine file."});const s={libs:this.libs.filter((e=>"atom"===e.type)),libraryAtom:this.atom,atom:this.atom},o=this.context.templateDir,i=a.compile(e.readFileSync(t.resolve(o,t.join("src","default","engine.js.njk")),"utf8"),this.apiContext.njEnv).render(s),r=this.context.projectDir,n=t.resolve(r,t.join("src","default","index.js"));e.writeFileSync(n,i,"utf8")}async build(){try{this.fileMode&&(await this.createAtomLibFiles({libs:this.libs}),await this.createEngine(),await this.createProjectYaml(),await r(this.apiContext),await g(this.apiContext),await n(this.apiContext),await h(this.apiContext),await _(this.apiContext),await w(this.apiContext),await async function({atom:o,setProgress:i,context:r,packageDependencies:n}){await i({message:"Creating rollup file."});const p={atom:o,packageDependencies:n},l=t.resolve(r.projectDir,"src","default/index.js");if(!e.existsSync(l))throw new Error(`Entry file not found: ${l}`);const c=(await s({file:l,recursive:!0})).all.filter((e=>"node"===e.type)).map((e=>e.path)),d=o.doc.features.rollup_output,u=Object.keys(d);for(let e=0;e<u.length;e++){const t=d[u[e]];if(!0===t.browser&&c.length>0){t.globals_enabled=!0,t.globals=t.globals||[],t.globals=t.globals.concat(c.map((e=>({key:e,value:e})))),t.alias_enabled=!0,t.alias=t.alias||{},t.alias.entries=t.alias.entries||{};for(let e=0;e<c.length;e++){const a=c[e];t.alias.entries[a]=`node:${a}`,t.alias.entries[`node:${a}`]=a}t.external_enabled=!0,t.external=t.external||[],t.external=t.external.concat(c)}}const f=r.templateDir;let m=a.compile(e.readFileSync(t.resolve(f,"rollup.config.mjs.njk"),"utf8"),a.configure(f)).render(p);const b=r.projectDir;let g=t.resolve(b,"rollup.config.mjs");e.writeFileSync(g,m,"utf8")}(this.apiContext),await y(this.apiContext),await x(this.apiContext),await async function({atom:e,setProgress:t,context:a}){if(!e.doc.features.dts_enabled)return;const s=a.projectDir;if(await t({message:"Creating .d.ts"}),0!==(await D("tsc",{cwd:s})).code)throw new Error("Couldnt create .d.ts files.")}(this.apiContext),this.buildMode&&(await v(this.apiContext),await k(this.apiContext),this.deployMode&&await this.deploy())),await this._cache_set(this.buildKey,{status:"COMPLETED"})}catch(e){throw await this._cache_set(this.buildKey,{status:"FAILED",message:e.message||e}),console.log(e),e}}}export{A as default};
|
package/dist/fnode/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import e,{delimiter as o,join as t}from"node:path";import{fileURLToPath as n}from"node:url";import r from"yargs";import i from"chalk";import s from"@fnet/config";import a,{existsSync as c}from"node:fs";import{promisify as l}from"node:util";import d from"tree-kill";import{spawn as p}from"node:child_process";import m from"node:os";import u from"@flownet/lib-render-templates-dir";import f from"@fnet/shelljs";import y from"@fnet/yaml";import g from"yaml";import w from"@fnet/prompt";import"fs";import"path";import"@fnet/shell-flow";const h=e.dirname(n(import.meta.url));const j=l(d);let b=!1;async function x(e,o){if(b)return;if(b=!0,!e.killed&&e.pid)try{await j(e.pid,"SIGTERM").catch((()=>{})),await new Promise((e=>setTimeout(e,500))),e.killed||await j(e.pid,"SIGKILL").catch((()=>{}))}catch(e){}await new Promise((e=>setTimeout(e,100)));const t="SIGINT"===o?130:"SIGTERM"===o?143:1;process.exit(t)}function v(e){["SIGINT","SIGTERM","SIGQUIT"].forEach((o=>{process.once(o,(async()=>{await x(e,o)}))})),process.on("uncaughtException",(async o=>{await x(e)})),process.on("unhandledRejection",(async o=>{await x(e)})),e.on("close",(e=>{b||process.exit(e)}))}function $(e,{name:o,bin:t,preArgs:n=[]}){return"function"==typeof t&&(t=t()),e.command(`${o||t} [commands..]`,`${t} ${n.join(" ")}`,(e=>e.help(!1).version(!1)),(async e=>{try{const o=await P(e),{projectDir:r}=o,i=e=>e.includes(" ")?"win32"===process.platform?`"${e.replace(/(["^])/g,"^$1")}"`:`"${e.replace(/(["\\$`])/g,"\\$1")}"`:e,s=process.argv.slice(3).map(i);v(p(t,[...n,...s],{cwd:r,stdio:"inherit",shell:!0,detached:!0}))}catch(e){console.error(e.message),process.exit(1)}}))}function S(o,{name:t,bin:n,preArgs:r=[]}){return o.command(`${t||n} [commands..]`,`${n} ${r.join(" ")}`,(e=>e.help(!1).version(!1)),(async o=>{try{const i=await P(o),{projectDir:s}=i,a=e=>e.includes(" ")?"win32"===process.platform?`"${e.replace(/(["^])/g,"^$1")}"`:`"${e.replace(/(["\\$`])/g,"\\$1")}"`:e,c=process.argv.slice(3).map(a);n=e.join(s,".conda","bin",n||t);v(p(n,[...r,...c],{cwd:s,stdio:"inherit",shell:!0,detached:!0,env:{PYTHONPATH:s}}))}catch(e){console.error(e.message),process.exit(1)}}))}async function P(e){try{const o=process.argv[1].split("/").pop().split(".")[0];if("fnode"===o){const{createContext:o}=await Promise.resolve().then((function(){return F}));return o(e)}if("fnet"===o){const{createContext:o}=await import("./index.B_0ZxySP.js");return o(e)}if("frun"===o){const{createContext:o}=await import("./index.CuMyez3E.js");return o(e)}if("fbin"===o){const{createContext:o}=await import("./index.DWpw12No.js");return o(e)}}catch(e){console.warn(`Warning: Could not import context from CLI tool: ${e.message}`)}return{projectDir:process.cwd(),tags:e.ftag}}var D=e=>{const n=process.env.PATH||"",r="win32"===process.platform?(process.env.PATHEXT||".EXE;.CMD;.BAT;.COM").split(";"):[""],i=n.split(o);for(const o of i)for(const n of r){const r=t(o,"win32"===process.platform?e+n:e);if(c(r))return r}return null};const I=e.dirname(n(import.meta.url)),E=process.cwd();function C(o){const t=e.resolve(E,o);if(a.existsSync(t))return t;const n=e.resolve(I,"../..",o);if(a.existsSync(n))return n;throw new Error(`Template path not found: ${o}`)}const N={command:"create",describe:"Create a new fnode project",builder:e=>e.option("name",{type:"string",describe:"Project name",demandOption:!0}).option("vscode",{type:"boolean",default:!0,alias:"vs",describe:"Open in VS Code after creation"}).option("runtime",{type:"string",default:"node",choices:["node","python","bun"],describe:"Runtime environment"}),handler:async o=>{try{const t=process.cwd(),n=C("./template/fnode/project"),r=e.resolve(t,o.name);a.existsSync(r)||a.mkdirSync(r),await u({dir:n,outDir:r,context:{name:o.name,runtime:o.runtime,platform:m.platform()},copyUnmatchedAlso:!0});let i=await f("fnode build",{cwd:r});if(0!==i.code)throw new Error("Failed to build project.");if(D("git")&&(i=await f("git init --initial-branch=main",{cwd:r}),0!==i.code))throw new Error("Failed to initialize git.");if(D("code")&&o.vscode&&(i=await f(`cd ${r} && code .`),0!==i.code))throw new Error("Failed to open vscode.");console.log("Creating project succeeded!"),process.exit(0)}catch(e){console.error("Initialization failed!",e.message),process.exit(1)}}};async function T(o){if(o.id)return{id:o.id,buildId:o.buildId,mode:o.mode,protocol:o.protocol||"ac:",templateDir:C("./template/fnode/node"),projectDir:e.resolve(process.cwd(),`./.output/${o.id}`),tags:o.ftag,dev:o.dev};try{const t=await async function({tags:o}){let t=function(o){const t=e.resolve(o,"node.yaml"),n=e.resolve(o,"fnode.yaml");if(a.existsSync(n))return n;if(a.existsSync(t))try{const e=a.readFileSync(t,"utf8");return a.writeFileSync(n,e,"utf8"),a.unlinkSync(t),console.log(`Migrated node.yaml to fnode.yaml in ${o}`),n}catch(e){return console.error(`Error migrating node.yaml to fnode.yaml: ${e.message}`),t}return n}(process.cwd());if(!a.existsSync(t))throw new Error("fnode.yaml file not found in current directory.");const{raw:n,parsed:r}=await y({file:t,tags:o}),i=e.dirname(t);r.features=r.features||{};const s=r.features;s.runtime=s.runtime||{},s.runtime.type=s.runtime.type||"node","python"===s.runtime.type?s.runtime.template=s.runtime.template||"python":"bun"===s.runtime.type?s.runtime.template=s.runtime.template||"bun":s.runtime.template=s.runtime.template||"node";const c={libraryAtom:{doc:{...r},fileName:"index"},projectDir:i,projectFilePath:t,projectFileContent:n,projectFileParsed:r,runtime:s.runtime};let l=e.resolve(i,"fnet/targets.yaml");if(!a.existsSync(l)&&(l=e.resolve(i,"node.devops.yaml"),a.existsSync(l))){const o=e.resolve(i,"fnet");a.existsSync(o)||a.mkdirSync(o),a.copyFileSync(l,e.resolve(i,"fnet/targets.yaml")),a.unlinkSync(l)}if(a.existsSync(l)){const{raw:e,parsed:t}=await y({file:l,tags:o}),n=g.parseDocument(e);c.devops={filePath:l,fileContent:e,yamlDocument:n,doc:{...t},type:"library.deploy",save:async()=>{a.writeFileSync(c.devops.filePath,n.toString())}}}const d=e.resolve(i,"readme.md");if(a.existsSync(d)){const e=a.readFileSync(d,"utf8");c.readme={filePath:d,fileContent:e,doc:{content:e,"content-type":"markdown"},type:"wiki"}}return c}({tags:o.ftag});return{buildId:o.buildId,mode:o.mode,protocol:o.protocol||"local:",templateDir:C(`./template/fnode/${t.runtime.template}`),projectDir:e.resolve(t.projectDir,"./.workspace"),projectSrcDir:e.resolve(t.projectDir,"./src"),project:t,tags:o.ftag,dev:o.dev}}catch(e){return console.warn(`Warning: Could not load project: ${e.message}`),{projectDir:process.cwd(),tags:o.ftag}}}var F=Object.freeze({__proto__:null,createContext:T});const k={command:"project",describe:"Manage fnode project",builder:e=>e.option("update",{type:"boolean",default:!1,alias:"-u",describe:"Update project files"}),handler:async e=>{try{const o=C("./template/fnode/project"),t=process.cwd(),n=await T(e);if(e.update){if(await u({dir:o,outDir:t,context:{name:n.project.projectFileParsed.name,runtime:n.project.runtime.type,platform:m.platform()},copyUnmatchedAlso:!0}),0!==(await f("fnode build",{cwd:t})).code)throw new Error("Failed to build project.");console.log("Updating project succeeded!")}process.exit(0)}catch(e){console.error("Project failed.",e.message),process.exit(1)}}};class B{static async createBuilder(e){if(!e.project){console.warn("No project provided, defaulting to node runtime");return new(0,(await import("./index.D3C-8oZW.js")).default)(e)}const o=e.project?.runtime?.type||"node";try{return new(await this.loadBuilderClass(o))(e)}catch(t){console.warn(`Warning: Could not load builder for runtime '${o}'. Falling back to node builder.`),console.warn(`Error: ${t.message}`);return new(0,(await import("./index.D3C-8oZW.js")).default)(e)}}static async loadBuilderClass(e){switch(e.toLowerCase()){case"node":return(await import("./index.D3C-8oZW.js")).default;case"python":return(await import("./index.uPDSav7E.js")).default;case"bun":return(await import("./index.DMkgR1Dh.js")).default;default:throw new Error(`Unsupported runtime type: ${e}`)}}}const A={command:"build",describe:"Build fnode project",builder:e=>e.option("id",{type:"string",describe:"Project ID"}).option("buildId",{type:"string",alias:"bid",describe:"Build ID"}).option("mode",{type:"string",default:"build",choices:["all","file","build","deploy","bpmn"],describe:"Build mode"}).option("ftag",{type:"array",describe:"Tags for conditional configuration"}).option("dev",{type:"boolean",default:!1,describe:"Development mode"}),handler:async e=>{try{const o=await T(e),t=await B.createBuilder(o);await t.init(),await t.build(),console.log("Building library succeeded!"),process.exit(0)}catch(e){console.error("Building library failed!",e.message),process.exit(1)}}},M={command:"deploy",describe:"Build and deploy fnode project",builder:e=>e.option("id",{type:"string",describe:"Project ID"}).option("buildId",{type:"string",alias:"bid",describe:"Build ID"}).option("ftag",{type:"array",describe:"Tags for conditional configuration"}),handler:async e=>{try{const o=await T({...e,mode:"all"}),t=await B.createBuilder(o);await t.init(),await t.build(),console.log("Building library succeeded!"),process.exit(0)}catch(e){console.error("Building library failed!",e.message),process.exit(1)}}},O={command:"file",describe:"Just create files",builder:e=>e.option("id",{type:"string",describe:"Project ID"}).option("buildId",{type:"string",alias:"bid",describe:"Build ID"}).option("ftag",{type:"array",describe:"Tags for conditional configuration"}),handler:async e=>{try{const o=await T({...e,mode:"file"}),t=await B.createBuilder(o);await t.init(),await t.build(),console.log("Building library succeeded!"),process.exit(0)}catch(e){console.error("Building library failed!",e.message),process.exit(1)}}},W={command:"input [name]",describe:"Create or modify an input config file",builder:e=>e.positional("name",{type:"string",demandOption:!1,describe:"Input name"}),handler:async o=>{try{const t=await T(o),{project:n}=t,{projectDir:r,projectFileParsed:i}=n,s=i.input;if(!s)throw new Error("Config schema not found in project file.");if(!Reflect.has(o,"name")){const{inputName:e}=await w({type:"input",name:"inputName",message:"Input name:",initial:"dev"});o.name=e}const c=e.resolve(r,".fnet");a.existsSync(c)||a.mkdirSync(c);const l=e.resolve(c,`${o.name}.fnet`),d=a.existsSync(l),p=(await import("@fnet/object-from-schema")).default,m=await p({schema:s,format:"yaml",ref:d?l:void 0});a.writeFileSync(l,m)}catch(e){console.error(e.message),process.exit(1)}}},R=e.join(m.homedir(),".fnet","express");async function U(o){o.command(["$0 [project-name]","create [project-name]"],"Create a new express project",(e=>e.positional("project-name",{describe:"Name of the project",type:"string"}).option("yes",{alias:"y",describe:"Skip all prompts and use defaults",type:"boolean",default:!1}).option("runtime",{describe:"Runtime to use (node, python, bun)",type:"string",choices:["node","python","bun"],default:"node"})),(async o=>{await async function(o){try{a.existsSync(R)||a.mkdirSync(R,{recursive:!0});const t=(new Date).toISOString().slice(0,10).replace(/-/g,""),n=e.join(R,t);a.existsSync(n)||a.mkdirSync(n,{recursive:!0});let r,s=o.projectName,c=o.runtime;if(o.yes){if(!s){const e=a.readdirSync(n).filter((e=>e.startsWith("fnode-"))).map((e=>parseInt(e.replace("fnode-",""),10))).filter((e=>!isNaN(e))),o=e.length>0?Math.max(...e)+1:1;s=`fnode-${o}`}c||(c="node")}else{if(!s){const e=a.readdirSync(n).filter((e=>e.startsWith("fnode-"))).map((e=>parseInt(e.replace("fnode-",""),10))).filter((e=>!isNaN(e))),o=`fnode-${e.length>0?Math.max(...e)+1:1}`,t=await w([{type:"input",name:"projectName",message:"Enter project name:",default:o}]);s=t.projectName}const e=c||"node";c=(await w({type:"select",name:"runtime",message:"Select runtime:",choices:["node","python","bun"],initial:e})).runtime}if(r=e.join(n,s),a.existsSync(r)){let o=1;for(;a.existsSync(e.join(n,`${s}-${o}`));)o++;s=`${s}-${o}`,r=e.join(n,s)}if(!o.yes){if(!(await w([{type:"confirm",name:"proceed",message:`Create express project "${s}" in ${r}?`,default:!0}])).proceed)return void console.log(i.yellow("Project creation cancelled."))}console.log(i.blue(`Creating express project "${s}" in ${r}...`));const l=e.dirname(r),d=["create","--name",e.basename(r)];d.push("--runtime",c),o.yes&&d.push("--yes"),a.existsSync(l)||a.mkdirSync(l,{recursive:!0});const m=p("fnode",d,{stdio:"inherit",shell:!0,cwd:l});return new Promise(((e,t)=>{m.on("close",(n=>{0===n?(console.log(i.green(`\nExpress project "${s}" created successfully!`)),console.log(i.blue(`\nProject location: ${r}`)),o.yes?e():async function(e){try{(await w({type:"confirm",name:"openIDE",message:"Would you like to open the project in an IDE?",initial:!0})).openIDE&&await L(e)}catch(e){console.error(i.red(`Error opening IDE: ${e.message}`))}}(r)):(console.error(i.red(`\nFailed to create express project "${s}".`)),t(new Error(`Process exited with code ${n}`)))}))}))}catch(e){console.error(i.red(`Error creating express project: ${e.message}`)),process.exit(1)}}(o)})).command("list","List express projects",(e=>e.option("today",{describe:"Show only projects created today",type:"boolean",default:!1}).option("type",{describe:"Filter by project type (fnode or fnet)",type:"string",choices:["fnode","fnet"]}).option("name",{describe:"Filter by project name",type:"string"})),(async o=>{await async function(o){try{if(!a.existsSync(R))return void console.log(i.yellow("No express projects found."));const t=a.readdirSync(R).filter((e=>/^\d{8}$/.test(e))).sort(((e,o)=>o.localeCompare(e)));if(o.today){const e=(new Date).toISOString().slice(0,10).replace(/-/g,""),o=t.indexOf(e);if(-1===o)return void console.log(i.yellow("No express projects found for today."));t.splice(0,o),t.splice(1)}const n=[];for(const r of t){const t=e.join(R,r),i=a.readdirSync(t);for(const s of i){const i=e.join(t,s),c=a.statSync(i);let l="unknown";if(s.startsWith("fnode-")||a.existsSync(e.join(i,"fnode.yaml"))?l="fnode":(s.startsWith("fnet-")||a.existsSync(e.join(i,"fnet.yaml")))&&(l="fnet"),o.type&&l!==o.type)continue;if(o.name&&!s.includes(o.name))continue;const d=`${r.slice(0,4)}-${r.slice(4,6)}-${r.slice(6,8)}`;n.push({name:s,type:l,date:d,path:i,created:c.birthtime})}}if(n.sort(((e,o)=>o.created-e.created)),0===n.length)return void console.log(i.yellow("No express projects found matching the criteria."));console.log(i.blue("\nExpress Projects:")),console.log(i.blue("=================\n"));const r=n.map((e=>{let o=e.path;return o.startsWith(m.homedir())&&(o="~"+o.substring(m.homedir().length)),{Name:e.name,Type:e.type,Date:e.date,Path:o}}));console.table(r),console.log(i.green("Projects: ")+i.yellow(n.filter((e=>"fnode"===e.type)).length+" fnode, ")+i.cyan(n.filter((e=>"fnet"===e.type)).length+" fnet")),console.log(i.blue(`\nTotal: ${n.length} projects`))}catch(e){console.error(i.red(`Error listing express projects: ${e.message}`)),process.exit(1)}}(o)})).command("open [project-name]","Open an express project",(e=>e.positional("project-name",{describe:"Name of the project to open",type:"string"}).option("latest",{describe:"Open the most recent project",type:"boolean",default:!1})),(async o=>{await async function(o){try{if(!a.existsSync(R))return void console.log(i.yellow("No express projects found."));let t;if(o.latest){if(t=await G(),!t)return void console.log(i.yellow("No express projects found."))}else if(o.projectName){if(t=await _(o.projectName),!t)return void console.log(i.yellow(`Project "${o.projectName}" not found.`))}else{const o=await H();if(!o)return void console.log(i.yellow("No project selected."));t=e.join(R,o)}await L(t)}catch(e){console.error(i.red(`Error opening express project: ${e.message}`)),process.exit(1)}}(o)})).command("move [project-name] [destination]","Move an express project to a real project location",(e=>e.positional("project-name",{describe:"Name of the project to move",type:"string"}).positional("destination",{describe:"Destination directory",type:"string"}).option("latest",{describe:"Move the most recent project",type:"boolean",default:!1})),(async o=>{await async function(o){try{const t=process.cwd();let n;if(t.includes(R))n=t,console.log(i.blue(`Using current express project: ${e.basename(n)}`));else if(o.latest){if(n=await G(),!n)return void console.log(i.yellow("No express projects found."))}else if(o.projectName){if(n=await _(o.projectName),!n)return void console.log(i.yellow(`Project "${o.projectName}" not found.`))}else{const o=await H();if(!o)return void console.log(i.yellow("No project selected."));n=e.join(R,o)}let r=o.destination;if(!r){r=(await w({type:"input",name:"destination",message:"Enter destination directory:",initial:e.join(process.cwd(),e.basename(n))})).destination}if(r.startsWith("~")&&(r=e.join(m.homedir(),r.slice(1))),r=e.resolve(r),r.startsWith(n+e.sep)||r===n)return void console.log(i.red("Destination cannot be inside the source directory."));if(a.existsSync(r)){if(!a.statSync(r).isDirectory())return void console.log(i.red(`Destination "${r}" is not a directory.`));if(a.readdirSync(r).length>0){if(!(await w({type:"confirm",name:"overwrite",message:`Destination "${r}" is not empty. Continue anyway?`,initial:!1})).overwrite)return void console.log(i.yellow("Project move cancelled."))}}else a.mkdirSync(r,{recursive:!0});console.log(i.blue(`Moving project from ${n} to ${r}...`)),V(n,r),console.log(i.green(`\nProject moved successfully to ${r}`));(await w({type:"confirm",name:"deleteOriginal",message:"Delete the original express project?",initial:!1})).deleteOriginal&&(a.rmSync(n,{recursive:!0,force:!0}),console.log(i.green("Original project deleted."))),await L(r)}catch(e){console.error(i.red(`Error moving express project: ${e.message}`)),process.exit(1)}}(o)})).demandCommand(1,"You need to specify a command").help()}async function G(){const o=a.readdirSync(R).filter((e=>/^\d{8}$/.test(e))).sort(((e,o)=>o.localeCompare(e)));if(0===o.length)return null;const t=o[0],n=e.join(R,t),r=a.readdirSync(n);if(0===r.length)return null;let i=null,s=0;for(const o of r){const t=e.join(n,o),r=a.statSync(t);r.birthtimeMs>s&&(s=r.birthtimeMs,i=t)}return i}async function _(o){const t=a.readdirSync(R).filter((e=>/^\d{8}$/.test(e))).sort(((e,o)=>o.localeCompare(e)));for(const n of t){const t=e.join(R,n),r=a.readdirSync(t);if(r.includes(o))return e.join(t,o);const i=r.filter((e=>e.includes(o)));if(i.length>0){if(1===i.length)return e.join(t,i[0]);return(await w({type:"select",name:"selectedProject",message:`Multiple projects match "${o}". Please select one:`,choices:i.map((o=>({name:`${o} (${n})`,value:e.join(t,o)})))})).selectedProject}}return null}async function H(){const o=[],t=a.readdirSync(R).filter((e=>/^\d{8}$/.test(e))).sort(((e,o)=>o.localeCompare(e)));for(const n of t){const t=e.join(R,n),r=a.readdirSync(t);for(const i of r){const r=e.join(t,i),s=a.statSync(r),c=`${n}/${i}`;o.push({name:c,value:c,created:s.birthtime})}}if(o.sort(((e,o)=>o.created-e.created)),0===o.length)return null;return(await w({type:"select",name:"selectedProject",message:"Select a project:",choices:o})).selectedProject}async function L(e){const o=await z("code --version"),t=await z("code-insiders --version");let n=null;if(o&&t){const e=await w({type:"select",name:"ide",message:"Which IDE would you like to use?",choices:[{name:"Visual Studio Code",value:"code"},{name:"Visual Studio Code Insiders",value:"code-insiders"}]});n=e.ide}else if(o)n="code";else{if(!t)return console.log(i.yellow("No supported IDE found. Please open the project manually.")),void console.log(i.blue(`Project path: ${e}`));n="code-insiders"}console.log(i.blue(`Opening project in ${n}...`)),console.log(i.blue(`Project path: ${e}`));const r=p(n,[e],{stdio:"inherit",shell:!0});return new Promise(((e,o)=>{r.on("close",(t=>{0===t?(console.log(i.green(`Project opened in ${n}.`)),e()):(console.error(i.red(`Failed to open project in ${n}.`)),o(new Error(`Process exited with code ${t}`)))}))}))}async function z(e){return new Promise((o=>{p(e,{shell:!0,stdio:"ignore"}).on("close",(e=>{o(0===e)}))}))}function V(o,t){a.existsSync(t)||a.mkdirSync(t,{recursive:!0});const n=a.readdirSync(o,{withFileTypes:!0});for(const r of n){const n=e.join(o,r.name),i=e.join(t,r.name);if(r.isDirectory()){if(".git"===r.name||".workspace"===r.name)continue;V(n,i)}else a.copyFileSync(n,i)}}const Y=e.dirname(n(import.meta.url)),X=process.cwd();process.on("uncaughtException",(e=>{b||(b=!0,setTimeout((()=>process.exit(1)),500))})),process.on("unhandledRejection",(e=>{b||(b=!0,setTimeout((()=>process.exit(1)),500))})),function(){s({name:["redis"],dir:X,optional:!0});const o=function({baseDir:o}){let t=o=o||h;for(;t!==e.parse(t).root;){const o=e.join(t,"node_modules");if(a.existsSync(o))return o;t=e.dirname(t)}return null}({baseDir:Y}),t="win32"===process.platform?";":":";o&&(process.env.PATH=`${e.join(o,"/.bin")}${t}${process.env.PATH}`)}(),async function(){try{let o=r(process.argv.slice(2)).usage("Usage: $0 <command> [options]").command(N).command(k).command(A).command(M).command(O).command(W).command("express","Create and manage express projects",U);o=$(o,{bin:"npm"}),o=$(o,{bin:"node"}),o=$(o,{bin:"bun"}),o=$(o,{name:"serve",bin:"bun",preArgs:["run","serve","--"]}),o=$(o,{name:"watch",bin:"bun",preArgs:["run","watch","--"]}),o=$(o,{name:"app",bin:"bun",preArgs:["run","app","--"]}),o=$(o,{name:"cli",bin:"bun",preArgs:["run","cli","--"]}),o=$(o,{name:"compile",bin:"bun",preArgs:["run","compile","--"]}),o=function(o,{name:t}){return o.command(`${t} [options]`,"Install the project as a binary",(e=>e.option("name",{alias:"n",describe:"Name to use for the installed binary",type:"string"}).option("force",{alias:"f",describe:"Force overwrite if binary already exists",type:"boolean",default:!1}).option("yes",{alias:"y",describe:"Automatically answer yes to all prompts",type:"boolean",default:!1})),(async o=>{try{const t=await P(o),{projectDir:n}=t;console.log(i.blue("Compiling project..."));const r=e.join(n,".bin");a.existsSync(r)||a.mkdirSync(r,{recursive:!0});const s=e.basename(e.dirname(n)),c=t.project?.projectFileParsed?.features?.cli?.bin,l=o.name||c||s;console.log(i.blue(`Using binary name: ${l}`));const d=e.join(r,l),{spawn:p}=await import("child_process"),m=p("bun",["build","./dist/cli/esm/index.js","--compile",`--outfile=${d}`],{cwd:n,stdio:"inherit",shell:!0});await new Promise(((e,o)=>{m.on("close",(t=>{0===t?e():o(new Error(`Compilation failed with code ${t}`))})),m.on("error",(e=>{o(e)}))})),"win32"!==process.platform&&a.chmodSync(d,493),console.log(i.green(`Binary compiled successfully: ${d}`)),console.log(i.blue("Installing binary..."));const u=["install",d];o.name&&u.push("--name",o.name),o.force&&u.push("--force"),o.yes&&u.push("--yes");const f=p("fbin",u,{stdio:"inherit",shell:!0});await new Promise(((e,o)=>{f.on("close",(t=>{0===t?e():o(new Error(`Installation failed with code ${t}`))})),f.on("error",(e=>{o(e)}))}))}catch(e){console.error(i.red(`Failed to install binary: ${e.message}`)),process.exit(1)}}))}(o,{name:"install"}),o=$(o,{bin:"npx"}),o=$(o,{bin:"cdk"}),o=$(o,{bin:"aws"}),o=function(e,{name:o,preArgs:t=[]}){return e.command(`${o} <config> <command> [options..]`,"Run a command with a config context",(e=>e.positional("config",{type:"string"}).positional("command",{type:"string"}).help(!1).version(!1)),(async e=>{try{const o=await P(e),{projectDir:n}=o,r=e.config,i=await s({name:r,dir:n,transferEnv:!1,optional:!0,tags:o.tags}),c=i?.data?.env||void 0,l=e.command,d=process.argv.slice(5);v(p(l,[...t,...d],{cwd:a.existsSync(n)?n:process.cwd(),stdio:"inherit",shell:!0,detached:!0,env:{...process.env,...c}}))}catch(e){console.error(e.message),process.exit(1)}}))}(o,{name:"with"}),o=function(e,{name:o,projectType:t="auto"}){return e.command(`${o} group [options..]`,"Run a command group.",(e=>e.positional("group",{type:"string"}).option("ftag",{type:"array"}).help(!1).version(!1)),(async e=>{try{const{runCommandGroup:o}=await import("./index.DrwlOzAe.js");await o({projectType:t,group:e.group,tags:e.ftag,args:e,argv:process.argv})}catch(e){console.error(e.message),process.exit(1)}}))}(o,{name:"run",projectType:"fnode"}),o=S(o,{name:"python"}),o=S(o,{name:"python3"}),o=S(o,{name:"pip"}),o=S(o,{name:"pip3"}),o.demandCommand(1,"You need at least one command before moving on").help().version().argv}catch(e){console.error(i.red(`Fatal error: ${e.message}`)),process.exit(1)}}().catch((e=>{console.error(i.red(`Fatal error: ${e.message}`)),process.exit(1)}));export{C as r,D as w};
|
|
2
|
+
import e,{delimiter as o,join as t}from"node:path";import{fileURLToPath as n}from"node:url";import r from"yargs";import i from"chalk";import s from"@fnet/config";import a,{existsSync as c}from"node:fs";import{promisify as l}from"node:util";import d from"tree-kill";import{spawn as p}from"node:child_process";import m from"node:os";import u from"@flownet/lib-render-templates-dir";import f from"@fnet/shelljs";import y from"@fnet/yaml";import g from"yaml";import w from"@fnet/prompt";import"fs";import"path";import"@fnet/shell-flow";const h=e.dirname(n(import.meta.url));const j=l(d);let b=!1;async function x(e,o){if(b)return;if(b=!0,!e.killed&&e.pid)try{await j(e.pid,"SIGTERM").catch((()=>{})),await new Promise((e=>setTimeout(e,500))),e.killed||await j(e.pid,"SIGKILL").catch((()=>{}))}catch(e){}await new Promise((e=>setTimeout(e,100)));const t="SIGINT"===o?130:"SIGTERM"===o?143:1;process.exit(t)}function v(e){["SIGINT","SIGTERM","SIGQUIT"].forEach((o=>{process.once(o,(async()=>{await x(e,o)}))})),process.on("uncaughtException",(async o=>{await x(e)})),process.on("unhandledRejection",(async o=>{await x(e)})),e.on("close",(e=>{b||process.exit(e)}))}function $(e,{name:o,bin:t,preArgs:n=[]}){return"function"==typeof t&&(t=t()),e.command(`${o||t} [commands..]`,`${t} ${n.join(" ")}`,(e=>e.help(!1).version(!1)),(async e=>{try{const o=await P(e),{projectDir:r}=o,i=e=>e.includes(" ")?"win32"===process.platform?`"${e.replace(/(["^])/g,"^$1")}"`:`"${e.replace(/(["\\$`])/g,"\\$1")}"`:e,s=process.argv.slice(3).map(i);v(p(t,[...n,...s],{cwd:r,stdio:"inherit",shell:!0,detached:!0}))}catch(e){console.error(e.message),process.exit(1)}}))}function S(o,{name:t,bin:n,preArgs:r=[]}){return o.command(`${t||n} [commands..]`,`${n} ${r.join(" ")}`,(e=>e.help(!1).version(!1)),(async o=>{try{const i=await P(o),{projectDir:s}=i,a=e=>e.includes(" ")?"win32"===process.platform?`"${e.replace(/(["^])/g,"^$1")}"`:`"${e.replace(/(["\\$`])/g,"\\$1")}"`:e,c=process.argv.slice(3).map(a);n=e.join(s,".conda","bin",n||t);v(p(n,[...r,...c],{cwd:s,stdio:"inherit",shell:!0,detached:!0,env:{PYTHONPATH:s}}))}catch(e){console.error(e.message),process.exit(1)}}))}async function P(e){try{const o=process.argv[1].split("/").pop().split(".")[0];if("fnode"===o){const{createContext:o}=await Promise.resolve().then((function(){return F}));return o(e)}if("fnet"===o){const{createContext:o}=await import("./index.B_0ZxySP.js");return o(e)}if("frun"===o){const{createContext:o}=await import("./index.CuMyez3E.js");return o(e)}if("fbin"===o){const{createContext:o}=await import("./index.DWpw12No.js");return o(e)}}catch(e){console.warn(`Warning: Could not import context from CLI tool: ${e.message}`)}return{projectDir:process.cwd(),tags:e.ftag}}var D=e=>{const n=process.env.PATH||"",r="win32"===process.platform?(process.env.PATHEXT||".EXE;.CMD;.BAT;.COM").split(";"):[""],i=n.split(o);for(const o of i)for(const n of r){const r=t(o,"win32"===process.platform?e+n:e);if(c(r))return r}return null};const I=e.dirname(n(import.meta.url)),E=process.cwd();function C(o){const t=e.resolve(E,o);if(a.existsSync(t))return t;const n=e.resolve(I,"../..",o);if(a.existsSync(n))return n;throw new Error(`Template path not found: ${o}`)}const N={command:"create",describe:"Create a new fnode project",builder:e=>e.option("name",{type:"string",describe:"Project name",demandOption:!0}).option("vscode",{type:"boolean",default:!0,alias:"vs",describe:"Open in VS Code after creation"}).option("runtime",{type:"string",default:"node",choices:["node","python","bun"],describe:"Runtime environment"}),handler:async o=>{try{const t=process.cwd(),n=C("./template/fnode/project"),r=e.resolve(t,o.name);a.existsSync(r)||a.mkdirSync(r),await u({dir:n,outDir:r,context:{name:o.name,runtime:o.runtime,platform:m.platform()},copyUnmatchedAlso:!0});let i=await f("fnode build",{cwd:r});if(0!==i.code)throw new Error("Failed to build project.");if(D("git")&&(i=await f("git init --initial-branch=main",{cwd:r}),0!==i.code))throw new Error("Failed to initialize git.");if(D("code")&&o.vscode&&(i=await f(`cd ${r} && code .`),0!==i.code))throw new Error("Failed to open vscode.");console.log("Creating project succeeded!"),process.exit(0)}catch(e){console.error("Initialization failed!",e.message),process.exit(1)}}};async function T(o){if(o.id)return{id:o.id,buildId:o.buildId,mode:o.mode,protocol:o.protocol||"ac:",templateDir:C("./template/fnode/node"),projectDir:e.resolve(process.cwd(),`./.output/${o.id}`),tags:o.ftag,dev:o.dev};try{const t=await async function({tags:o}){let t=function(o){const t=e.resolve(o,"node.yaml"),n=e.resolve(o,"fnode.yaml");if(a.existsSync(n))return n;if(a.existsSync(t))try{const e=a.readFileSync(t,"utf8");return a.writeFileSync(n,e,"utf8"),a.unlinkSync(t),console.log(`Migrated node.yaml to fnode.yaml in ${o}`),n}catch(e){return console.error(`Error migrating node.yaml to fnode.yaml: ${e.message}`),t}return n}(process.cwd());if(!a.existsSync(t))throw new Error("fnode.yaml file not found in current directory.");const{raw:n,parsed:r}=await y({file:t,tags:o}),i=e.dirname(t);r.features=r.features||{};const s=r.features;s.runtime=s.runtime||{},s.runtime.type=s.runtime.type||"node","python"===s.runtime.type?s.runtime.template=s.runtime.template||"python":"bun"===s.runtime.type?s.runtime.template=s.runtime.template||"bun":s.runtime.template=s.runtime.template||"node";const c={libraryAtom:{doc:{...r},fileName:"index"},projectDir:i,projectFilePath:t,projectFileContent:n,projectFileParsed:r,runtime:s.runtime};let l=e.resolve(i,"fnet/targets.yaml");if(!a.existsSync(l)&&(l=e.resolve(i,"node.devops.yaml"),a.existsSync(l))){const o=e.resolve(i,"fnet");a.existsSync(o)||a.mkdirSync(o),a.copyFileSync(l,e.resolve(i,"fnet/targets.yaml")),a.unlinkSync(l)}if(a.existsSync(l)){const{raw:e,parsed:t}=await y({file:l,tags:o}),n=g.parseDocument(e);c.devops={filePath:l,fileContent:e,yamlDocument:n,doc:{...t},type:"library.deploy",save:async()=>{a.writeFileSync(c.devops.filePath,n.toString())}}}const d=e.resolve(i,"readme.md");if(a.existsSync(d)){const e=a.readFileSync(d,"utf8");c.readme={filePath:d,fileContent:e,doc:{content:e,"content-type":"markdown"},type:"wiki"}}return c}({tags:o.ftag});return{buildId:o.buildId,mode:o.mode,protocol:o.protocol||"local:",templateDir:C(`./template/fnode/${t.runtime.template}`),projectDir:e.resolve(t.projectDir,"./.workspace"),projectSrcDir:e.resolve(t.projectDir,"./src"),project:t,tags:o.ftag,dev:o.dev}}catch(e){return console.warn(`Warning: Could not load project: ${e.message}`),{projectDir:process.cwd(),tags:o.ftag}}}var F=Object.freeze({__proto__:null,createContext:T});const k={command:"project",describe:"Manage fnode project",builder:e=>e.option("update",{type:"boolean",default:!1,alias:"-u",describe:"Update project files"}),handler:async e=>{try{const o=C("./template/fnode/project"),t=process.cwd(),n=await T(e);if(e.update){if(await u({dir:o,outDir:t,context:{name:n.project.projectFileParsed.name,runtime:n.project.runtime.type,platform:m.platform()},copyUnmatchedAlso:!0}),0!==(await f("fnode build",{cwd:t})).code)throw new Error("Failed to build project.");console.log("Updating project succeeded!")}process.exit(0)}catch(e){console.error("Project failed.",e.message),process.exit(1)}}};class B{static async createBuilder(e){if(!e.project){console.warn("No project provided, defaulting to node runtime");return new(0,(await import("./index.DnA30tC4.js")).default)(e)}const o=e.project?.runtime?.type||"node";try{return new(await this.loadBuilderClass(o))(e)}catch(t){console.warn(`Warning: Could not load builder for runtime '${o}'. Falling back to node builder.`),console.warn(`Error: ${t.message}`);return new(0,(await import("./index.DnA30tC4.js")).default)(e)}}static async loadBuilderClass(e){switch(e.toLowerCase()){case"node":return(await import("./index.DnA30tC4.js")).default;case"python":return(await import("./index.uPDSav7E.js")).default;case"bun":return(await import("./index.B1G_No8j.js")).default;default:throw new Error(`Unsupported runtime type: ${e}`)}}}const A={command:"build",describe:"Build fnode project",builder:e=>e.option("id",{type:"string",describe:"Project ID"}).option("buildId",{type:"string",alias:"bid",describe:"Build ID"}).option("mode",{type:"string",default:"build",choices:["all","file","build","deploy","bpmn"],describe:"Build mode"}).option("ftag",{type:"array",describe:"Tags for conditional configuration"}).option("dev",{type:"boolean",default:!1,describe:"Development mode"}),handler:async e=>{try{const o=await T(e),t=await B.createBuilder(o);await t.init(),await t.build(),console.log("Building library succeeded!"),process.exit(0)}catch(e){console.error("Building library failed!",e.message),process.exit(1)}}},M={command:"deploy",describe:"Build and deploy fnode project",builder:e=>e.option("id",{type:"string",describe:"Project ID"}).option("buildId",{type:"string",alias:"bid",describe:"Build ID"}).option("ftag",{type:"array",describe:"Tags for conditional configuration"}),handler:async e=>{try{const o=await T({...e,mode:"all"}),t=await B.createBuilder(o);await t.init(),await t.build(),console.log("Building library succeeded!"),process.exit(0)}catch(e){console.error("Building library failed!",e.message),process.exit(1)}}},O={command:"file",describe:"Just create files",builder:e=>e.option("id",{type:"string",describe:"Project ID"}).option("buildId",{type:"string",alias:"bid",describe:"Build ID"}).option("ftag",{type:"array",describe:"Tags for conditional configuration"}),handler:async e=>{try{const o=await T({...e,mode:"file"}),t=await B.createBuilder(o);await t.init(),await t.build(),console.log("Building library succeeded!"),process.exit(0)}catch(e){console.error("Building library failed!",e.message),process.exit(1)}}},W={command:"input [name]",describe:"Create or modify an input config file",builder:e=>e.positional("name",{type:"string",demandOption:!1,describe:"Input name"}),handler:async o=>{try{const t=await T(o),{project:n}=t,{projectDir:r,projectFileParsed:i}=n,s=i.input;if(!s)throw new Error("Config schema not found in project file.");if(!Reflect.has(o,"name")){const{inputName:e}=await w({type:"input",name:"inputName",message:"Input name:",initial:"dev"});o.name=e}const c=e.resolve(r,".fnet");a.existsSync(c)||a.mkdirSync(c);const l=e.resolve(c,`${o.name}.fnet`),d=a.existsSync(l),p=(await import("@fnet/object-from-schema")).default,m=await p({schema:s,format:"yaml",ref:d?l:void 0});a.writeFileSync(l,m)}catch(e){console.error(e.message),process.exit(1)}}},R=e.join(m.homedir(),".fnet","express");async function U(o){o.command(["$0 [project-name]","create [project-name]"],"Create a new express project",(e=>e.positional("project-name",{describe:"Name of the project",type:"string"}).option("yes",{alias:"y",describe:"Skip all prompts and use defaults",type:"boolean",default:!1}).option("runtime",{describe:"Runtime to use (node, python, bun)",type:"string",choices:["node","python","bun"],default:"node"})),(async o=>{await async function(o){try{a.existsSync(R)||a.mkdirSync(R,{recursive:!0});const t=(new Date).toISOString().slice(0,10).replace(/-/g,""),n=e.join(R,t);a.existsSync(n)||a.mkdirSync(n,{recursive:!0});let r,s=o.projectName,c=o.runtime;if(o.yes){if(!s){const e=a.readdirSync(n).filter((e=>e.startsWith("fnode-"))).map((e=>parseInt(e.replace("fnode-",""),10))).filter((e=>!isNaN(e))),o=e.length>0?Math.max(...e)+1:1;s=`fnode-${o}`}c||(c="node")}else{if(!s){const e=a.readdirSync(n).filter((e=>e.startsWith("fnode-"))).map((e=>parseInt(e.replace("fnode-",""),10))).filter((e=>!isNaN(e))),o=`fnode-${e.length>0?Math.max(...e)+1:1}`,t=await w([{type:"input",name:"projectName",message:"Enter project name:",default:o}]);s=t.projectName}const e=c||"node";c=(await w({type:"select",name:"runtime",message:"Select runtime:",choices:["node","python","bun"],initial:e})).runtime}if(r=e.join(n,s),a.existsSync(r)){let o=1;for(;a.existsSync(e.join(n,`${s}-${o}`));)o++;s=`${s}-${o}`,r=e.join(n,s)}if(!o.yes){if(!(await w([{type:"confirm",name:"proceed",message:`Create express project "${s}" in ${r}?`,default:!0}])).proceed)return void console.log(i.yellow("Project creation cancelled."))}console.log(i.blue(`Creating express project "${s}" in ${r}...`));const l=e.dirname(r),d=["create","--name",e.basename(r)];d.push("--runtime",c),o.yes&&d.push("--yes"),a.existsSync(l)||a.mkdirSync(l,{recursive:!0});const m=p("fnode",d,{stdio:"inherit",shell:!0,cwd:l});return new Promise(((e,t)=>{m.on("close",(n=>{0===n?(console.log(i.green(`\nExpress project "${s}" created successfully!`)),console.log(i.blue(`\nProject location: ${r}`)),o.yes?e():async function(e){try{(await w({type:"confirm",name:"openIDE",message:"Would you like to open the project in an IDE?",initial:!0})).openIDE&&await L(e)}catch(e){console.error(i.red(`Error opening IDE: ${e.message}`))}}(r)):(console.error(i.red(`\nFailed to create express project "${s}".`)),t(new Error(`Process exited with code ${n}`)))}))}))}catch(e){console.error(i.red(`Error creating express project: ${e.message}`)),process.exit(1)}}(o)})).command("list","List express projects",(e=>e.option("today",{describe:"Show only projects created today",type:"boolean",default:!1}).option("type",{describe:"Filter by project type (fnode or fnet)",type:"string",choices:["fnode","fnet"]}).option("name",{describe:"Filter by project name",type:"string"})),(async o=>{await async function(o){try{if(!a.existsSync(R))return void console.log(i.yellow("No express projects found."));const t=a.readdirSync(R).filter((e=>/^\d{8}$/.test(e))).sort(((e,o)=>o.localeCompare(e)));if(o.today){const e=(new Date).toISOString().slice(0,10).replace(/-/g,""),o=t.indexOf(e);if(-1===o)return void console.log(i.yellow("No express projects found for today."));t.splice(0,o),t.splice(1)}const n=[];for(const r of t){const t=e.join(R,r),i=a.readdirSync(t);for(const s of i){const i=e.join(t,s),c=a.statSync(i);let l="unknown";if(s.startsWith("fnode-")||a.existsSync(e.join(i,"fnode.yaml"))?l="fnode":(s.startsWith("fnet-")||a.existsSync(e.join(i,"fnet.yaml")))&&(l="fnet"),o.type&&l!==o.type)continue;if(o.name&&!s.includes(o.name))continue;const d=`${r.slice(0,4)}-${r.slice(4,6)}-${r.slice(6,8)}`;n.push({name:s,type:l,date:d,path:i,created:c.birthtime})}}if(n.sort(((e,o)=>o.created-e.created)),0===n.length)return void console.log(i.yellow("No express projects found matching the criteria."));console.log(i.blue("\nExpress Projects:")),console.log(i.blue("=================\n"));const r=n.map((e=>{let o=e.path;return o.startsWith(m.homedir())&&(o="~"+o.substring(m.homedir().length)),{Name:e.name,Type:e.type,Date:e.date,Path:o}}));console.table(r),console.log(i.green("Projects: ")+i.yellow(n.filter((e=>"fnode"===e.type)).length+" fnode, ")+i.cyan(n.filter((e=>"fnet"===e.type)).length+" fnet")),console.log(i.blue(`\nTotal: ${n.length} projects`))}catch(e){console.error(i.red(`Error listing express projects: ${e.message}`)),process.exit(1)}}(o)})).command("open [project-name]","Open an express project",(e=>e.positional("project-name",{describe:"Name of the project to open",type:"string"}).option("latest",{describe:"Open the most recent project",type:"boolean",default:!1})),(async o=>{await async function(o){try{if(!a.existsSync(R))return void console.log(i.yellow("No express projects found."));let t;if(o.latest){if(t=await G(),!t)return void console.log(i.yellow("No express projects found."))}else if(o.projectName){if(t=await _(o.projectName),!t)return void console.log(i.yellow(`Project "${o.projectName}" not found.`))}else{const o=await H();if(!o)return void console.log(i.yellow("No project selected."));t=e.join(R,o)}await L(t)}catch(e){console.error(i.red(`Error opening express project: ${e.message}`)),process.exit(1)}}(o)})).command("move [project-name] [destination]","Move an express project to a real project location",(e=>e.positional("project-name",{describe:"Name of the project to move",type:"string"}).positional("destination",{describe:"Destination directory",type:"string"}).option("latest",{describe:"Move the most recent project",type:"boolean",default:!1})),(async o=>{await async function(o){try{const t=process.cwd();let n;if(t.includes(R))n=t,console.log(i.blue(`Using current express project: ${e.basename(n)}`));else if(o.latest){if(n=await G(),!n)return void console.log(i.yellow("No express projects found."))}else if(o.projectName){if(n=await _(o.projectName),!n)return void console.log(i.yellow(`Project "${o.projectName}" not found.`))}else{const o=await H();if(!o)return void console.log(i.yellow("No project selected."));n=e.join(R,o)}let r=o.destination;if(!r){r=(await w({type:"input",name:"destination",message:"Enter destination directory:",initial:e.join(process.cwd(),e.basename(n))})).destination}if(r.startsWith("~")&&(r=e.join(m.homedir(),r.slice(1))),r=e.resolve(r),r.startsWith(n+e.sep)||r===n)return void console.log(i.red("Destination cannot be inside the source directory."));if(a.existsSync(r)){if(!a.statSync(r).isDirectory())return void console.log(i.red(`Destination "${r}" is not a directory.`));if(a.readdirSync(r).length>0){if(!(await w({type:"confirm",name:"overwrite",message:`Destination "${r}" is not empty. Continue anyway?`,initial:!1})).overwrite)return void console.log(i.yellow("Project move cancelled."))}}else a.mkdirSync(r,{recursive:!0});console.log(i.blue(`Moving project from ${n} to ${r}...`)),V(n,r),console.log(i.green(`\nProject moved successfully to ${r}`));(await w({type:"confirm",name:"deleteOriginal",message:"Delete the original express project?",initial:!1})).deleteOriginal&&(a.rmSync(n,{recursive:!0,force:!0}),console.log(i.green("Original project deleted."))),await L(r)}catch(e){console.error(i.red(`Error moving express project: ${e.message}`)),process.exit(1)}}(o)})).demandCommand(1,"You need to specify a command").help()}async function G(){const o=a.readdirSync(R).filter((e=>/^\d{8}$/.test(e))).sort(((e,o)=>o.localeCompare(e)));if(0===o.length)return null;const t=o[0],n=e.join(R,t),r=a.readdirSync(n);if(0===r.length)return null;let i=null,s=0;for(const o of r){const t=e.join(n,o),r=a.statSync(t);r.birthtimeMs>s&&(s=r.birthtimeMs,i=t)}return i}async function _(o){const t=a.readdirSync(R).filter((e=>/^\d{8}$/.test(e))).sort(((e,o)=>o.localeCompare(e)));for(const n of t){const t=e.join(R,n),r=a.readdirSync(t);if(r.includes(o))return e.join(t,o);const i=r.filter((e=>e.includes(o)));if(i.length>0){if(1===i.length)return e.join(t,i[0]);return(await w({type:"select",name:"selectedProject",message:`Multiple projects match "${o}". Please select one:`,choices:i.map((o=>({name:`${o} (${n})`,value:e.join(t,o)})))})).selectedProject}}return null}async function H(){const o=[],t=a.readdirSync(R).filter((e=>/^\d{8}$/.test(e))).sort(((e,o)=>o.localeCompare(e)));for(const n of t){const t=e.join(R,n),r=a.readdirSync(t);for(const i of r){const r=e.join(t,i),s=a.statSync(r),c=`${n}/${i}`;o.push({name:c,value:c,created:s.birthtime})}}if(o.sort(((e,o)=>o.created-e.created)),0===o.length)return null;return(await w({type:"select",name:"selectedProject",message:"Select a project:",choices:o})).selectedProject}async function L(e){const o=await z("code --version"),t=await z("code-insiders --version");let n=null;if(o&&t){const e=await w({type:"select",name:"ide",message:"Which IDE would you like to use?",choices:[{name:"Visual Studio Code",value:"code"},{name:"Visual Studio Code Insiders",value:"code-insiders"}]});n=e.ide}else if(o)n="code";else{if(!t)return console.log(i.yellow("No supported IDE found. Please open the project manually.")),void console.log(i.blue(`Project path: ${e}`));n="code-insiders"}console.log(i.blue(`Opening project in ${n}...`)),console.log(i.blue(`Project path: ${e}`));const r=p(n,[e],{stdio:"inherit",shell:!0});return new Promise(((e,o)=>{r.on("close",(t=>{0===t?(console.log(i.green(`Project opened in ${n}.`)),e()):(console.error(i.red(`Failed to open project in ${n}.`)),o(new Error(`Process exited with code ${t}`)))}))}))}async function z(e){return new Promise((o=>{p(e,{shell:!0,stdio:"ignore"}).on("close",(e=>{o(0===e)}))}))}function V(o,t){a.existsSync(t)||a.mkdirSync(t,{recursive:!0});const n=a.readdirSync(o,{withFileTypes:!0});for(const r of n){const n=e.join(o,r.name),i=e.join(t,r.name);if(r.isDirectory()){if(".git"===r.name||".workspace"===r.name)continue;V(n,i)}else a.copyFileSync(n,i)}}const Y=e.dirname(n(import.meta.url)),X=process.cwd();process.on("uncaughtException",(e=>{b||(b=!0,setTimeout((()=>process.exit(1)),500))})),process.on("unhandledRejection",(e=>{b||(b=!0,setTimeout((()=>process.exit(1)),500))})),function(){s({name:["redis"],dir:X,optional:!0});const o=function({baseDir:o}){let t=o=o||h;for(;t!==e.parse(t).root;){const o=e.join(t,"node_modules");if(a.existsSync(o))return o;t=e.dirname(t)}return null}({baseDir:Y}),t="win32"===process.platform?";":":";o&&(process.env.PATH=`${e.join(o,"/.bin")}${t}${process.env.PATH}`)}(),async function(){try{let o=r(process.argv.slice(2)).usage("Usage: $0 <command> [options]").command(N).command(k).command(A).command(M).command(O).command(W).command("express","Create and manage express projects",U);o=$(o,{bin:"npm"}),o=$(o,{bin:"node"}),o=$(o,{bin:"bun"}),o=$(o,{name:"serve",bin:"bun",preArgs:["run","serve","--"]}),o=$(o,{name:"watch",bin:"bun",preArgs:["run","watch","--"]}),o=$(o,{name:"app",bin:"bun",preArgs:["run","app","--"]}),o=$(o,{name:"cli",bin:"bun",preArgs:["run","cli","--"]}),o=$(o,{name:"compile",bin:"bun",preArgs:["run","compile","--"]}),o=function(o,{name:t}){return o.command(`${t} [options]`,"Install the project as a binary",(e=>e.option("name",{alias:"n",describe:"Name to use for the installed binary",type:"string"}).option("force",{alias:"f",describe:"Force overwrite if binary already exists",type:"boolean",default:!1}).option("yes",{alias:"y",describe:"Automatically answer yes to all prompts",type:"boolean",default:!1})),(async o=>{try{const t=await P(o),{projectDir:n}=t;console.log(i.blue("Compiling project..."));const r=e.join(n,".bin");a.existsSync(r)||a.mkdirSync(r,{recursive:!0});const s=e.basename(e.dirname(n)),c=t.project?.projectFileParsed?.features?.cli?.bin,l=o.name||c||s;console.log(i.blue(`Using binary name: ${l}`));const d=e.join(r,l),{spawn:p}=await import("child_process"),m=p("bun",["build","./dist/cli/esm/index.js","--compile",`--outfile=${d}`],{cwd:n,stdio:"inherit",shell:!0});await new Promise(((e,o)=>{m.on("close",(t=>{0===t?e():o(new Error(`Compilation failed with code ${t}`))})),m.on("error",(e=>{o(e)}))})),"win32"!==process.platform&&a.chmodSync(d,493),console.log(i.green(`Binary compiled successfully: ${d}`)),console.log(i.blue("Installing binary..."));const u=["install",d];o.name&&u.push("--name",o.name),o.force&&u.push("--force"),o.yes&&u.push("--yes");const f=p("fbin",u,{stdio:"inherit",shell:!0});await new Promise(((e,o)=>{f.on("close",(t=>{0===t?e():o(new Error(`Installation failed with code ${t}`))})),f.on("error",(e=>{o(e)}))}))}catch(e){console.error(i.red(`Failed to install binary: ${e.message}`)),process.exit(1)}}))}(o,{name:"install"}),o=$(o,{bin:"npx"}),o=$(o,{bin:"cdk"}),o=$(o,{bin:"aws"}),o=function(e,{name:o,preArgs:t=[]}){return e.command(`${o} <config> <command> [options..]`,"Run a command with a config context",(e=>e.positional("config",{type:"string"}).positional("command",{type:"string"}).help(!1).version(!1)),(async e=>{try{const o=await P(e),{projectDir:n}=o,r=e.config,i=await s({name:r,dir:n,transferEnv:!1,optional:!0,tags:o.tags}),c=i?.data?.env||void 0,l=e.command,d=process.argv.slice(5);v(p(l,[...t,...d],{cwd:a.existsSync(n)?n:process.cwd(),stdio:"inherit",shell:!0,detached:!0,env:{...process.env,...c}}))}catch(e){console.error(e.message),process.exit(1)}}))}(o,{name:"with"}),o=function(e,{name:o,projectType:t="auto"}){return e.command(`${o} group [options..]`,"Run a command group.",(e=>e.positional("group",{type:"string"}).option("ftag",{type:"array"}).help(!1).version(!1)),(async e=>{try{const{runCommandGroup:o}=await import("./index.DrwlOzAe.js");await o({projectType:t,group:e.group,tags:e.ftag,args:e,argv:process.argv})}catch(e){console.error(e.message),process.exit(1)}}))}(o,{name:"run",projectType:"fnode"}),o=S(o,{name:"python"}),o=S(o,{name:"python3"}),o=S(o,{name:"pip"}),o=S(o,{name:"pip3"}),o.demandCommand(1,"You need at least one command before moving on").help().version().argv}catch(e){console.error(i.red(`Fatal error: ${e.message}`)),process.exit(1)}}().catch((e=>{console.error(i.red(`Fatal error: ${e.message}`)),process.exit(1)}));export{C as r,D as w};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import e from"yargs";import{hideBin as n}from"yargs/helpers";import i from"chalk";import t from"node:fs";import r from"node:path";import o from"@fnet/object-from-schema";import s from"@fnet/prompt";import a from"node:os";import c from"yaml";import l from"@fnet/service";import{createRequire as d}from"module";function m(){return r.join(a.homedir(),".fnet","bin")}function f(){return r.join(a.homedir(),".fnet","metadata")}function p(){return r.join(f(),"binaries.json")}function u(){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":t.existsSync(r.join(a.homedir(),".bashrc"))?"bash":t.existsSync(r.join(a.homedir(),".zshrc"))?"zsh":t.existsSync(r.join(a.homedir(),".config","fish","config.fish"))?"fish":"unknown"}catch(e){return"unknown"}}function g(e){const n=a.homedir(),i=[];switch(e){case"bash":i.push({name:".bashrc",path:r.join(n,".bashrc")}),i.push({name:".bash_profile",path:r.join(n,".bash_profile")}),i.push({name:".profile",path:r.join(n,".profile")});break;case"zsh":i.push({name:".zshrc",path:r.join(n,".zshrc")}),i.push({name:".zprofile",path:r.join(n,".zprofile")});break;case"fish":i.push({name:"config.fish",path:r.join(n,".config","fish","config.fish")});break;case"ksh":i.push({name:".kshrc",path:r.join(n,".kshrc")}),i.push({name:".profile",path:r.join(n,".profile")});break;case"csh":i.push({name:".cshrc",path:r.join(n,".cshrc")}),i.push({name:".tcshrc",path:r.join(n,".tcshrc")});break;case"powershell":i.push({name:"Microsoft.PowerShell_profile.ps1",path:r.join(n,"Documents","WindowsPowerShell","Microsoft.PowerShell_profile.ps1")}),i.push({name:"profile.ps1",path:r.join(n,"Documents","WindowsPowerShell","profile.ps1")});break;case"powershell-core":i.push({name:"Microsoft.PowerShell_profile.ps1",path:r.join(n,"Documents","PowerShell","Microsoft.PowerShell_profile.ps1")}),i.push({name:"profile.ps1",path:r.join(n,"Documents","PowerShell","profile.ps1")});break;case"cmd":i.push({name:"fnet-path.bat",path:r.join(n,"fnet-path.bat")})}return i}function y(e,n){switch(e){case"bash":case"zsh":case"ksh":default:return`export PATH="${n}:$PATH"`;case"fish":return`set -gx PATH ${n} $PATH`;case"csh":return`setenv PATH ${n}:$PATH`;case"powershell":case"powershell-core":return`$env:PATH = "${n};" + $env:PATH`;case"cmd":return`@echo off\nSETX PATH "%PATH%;${n}"\necho Path updated successfully`}}var v={getBinDirectory:m,getMetadataDirectory:f,getMetadataFilePath:p,checkIfInPath:function(e){return(process.env.PATH||"").split(r.delimiter).includes(e)},detectUserShell:u,getShellConfigPath:function(){const e=g(u());for(const n of e)if(t.existsSync(n.path))return n.path;return e.length>0?e[0].path:null},getAllShellConfigPaths:g,createBinDirectoryStructure:async function(){const e=m(),n=f(),i=p();t.existsSync(e)||t.mkdirSync(e,{recursive:!0}),t.existsSync(n)||t.mkdirSync(n,{recursive:!0}),t.existsSync(i)||t.writeFileSync(i,JSON.stringify({binaries:{},lastUpdated:(new Date).toISOString()},null,2))},getExportPathCommand:y,addBinToPath:async function(e,n,o){try{const s=y(e,o);if("cmd"===e)return t.writeFileSync(n,s),console.log(i.yellow(`Created batch file at ${n}`)),console.log(i.yellow("Run this file to add the bin directory to your PATH")),!0;if("powershell"!==e&&"powershell-core"!==e||t.existsSync(r.dirname(n))||t.mkdirSync(r.dirname(n),{recursive:!0}),!t.existsSync(n)){const r="fish"===e?"# Fish shell configuration\n\n":"powershell"===e||"powershell-core"===e?"# PowerShell profile\n\n":"# Shell configuration\n\n";t.writeFileSync(n,r),console.log(i.green(`Created config file at ${n}`))}const a=t.readFileSync(n,"utf8");if(a.includes(o))return!0;const c=`${a.trim()}\n\n# Added by @fnet/cli\n${s}\n`;return t.writeFileSync(n,c),"powershell"!==e&&"powershell-core"!==e||(console.log(i.yellow("You may need to set the PowerShell execution policy to run scripts:")),console.log(i.green("Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned"))),!0}catch(e){return console.error(i.red(`Failed to add bin directory to PATH: ${e.message}`)),!1}}};function h(){return r.join(a.homedir(),".fnet","services")}function S(){return r.join(a.homedir(),".fnet","metadata")}function b(){return r.join(S(),"services.json")}function w(){const e=b();if(!t.existsSync(e))return{services:{},lastUpdated:(new Date).toISOString()};try{return JSON.parse(t.readFileSync(e,"utf8"))}catch(e){return console.warn(i.yellow(`Failed to parse service metadata file: ${e.message}`)),{services:{},lastUpdated:(new Date).toISOString()}}}function $(e){const n=b();e.lastUpdated=(new Date).toISOString(),t.writeFileSync(n,JSON.stringify(e,null,2))}function x(e){return r.join(h(),`${e}.yaml`)}function D(e){const n=x(e);if(!t.existsSync(n))return null;try{const e=t.readFileSync(n,"utf8");return c.parse(e)}catch(e){return console.warn(i.yellow(`Failed to parse service definition file: ${e.message}`)),null}}function E(e){const n=[];if(e.name||n.push("Service name is required"),e.binary||n.push("Binary name is required"),e.binary){const i=v.getBinDirectory(),o=r.join(i,e.binary);t.existsSync(o)||n.push(`Binary '${e.binary}' not found in bin directory`)}return{valid:0===n.length,errors:n}}var j={getServicesDirectory:h,getServiceMetadataDirectory:S,getServiceMetadataFilePath:b,createServiceDirectoryStructure:async function(){const e=h(),n=S(),i=b();t.existsSync(e)||t.mkdirSync(e,{recursive:!0}),t.existsSync(n)||t.mkdirSync(n,{recursive:!0}),t.existsSync(i)||t.writeFileSync(i,JSON.stringify({services:{},lastUpdated:(new Date).toISOString()},null,2))},loadServiceMetadata:w,saveServiceMetadata:$,getServiceDefinitionPath:x,serviceDefinitionExists:function(e){const n=x(e);return t.existsSync(n)},loadServiceDefinition:D,saveServiceDefinition:function(e,n){const r=x(e);try{const e=c.stringify(n);return t.writeFileSync(r,e),!0}catch(e){return console.error(i.red(`Failed to save service definition: ${e.message}`)),!1}},deleteServiceDefinition:function(e){const n=x(e);if(!t.existsSync(n))return!1;try{return t.unlinkSync(n),!0}catch(e){return console.error(i.red(`Failed to delete service definition: ${e.message}`)),!1}},listServiceDefinitions:function(){const e=h();if(!t.existsSync(e))return[];try{return t.readdirSync(e).filter((e=>e.endsWith(".yaml"))).map((e=>e.replace(".yaml","")))}catch(e){return console.error(i.red(`Failed to list service definitions: ${e.message}`)),[]}},validateServiceDefinition:E,registerService:async function(e,n={}){const i=D(e);if(!i)throw new Error(`Service definition '${e}' not found`);const t=E(i);if(!t.valid)throw new Error(`Invalid service definition: ${t.errors.join(", ")}`);const o=v.getBinDirectory(),s=r.join(o,i.binary);try{await l({action:"register",name:i.name,description:i.description||`Service for ${i.binary}`,command:[s,...i.args||[]],env:i.env||{},wdir:i.workingDir,system:!1!==i.system,autoStart:!0===i.autoStart,restartOnFailure:!1!==i.restartOnFailure,user:i.user});const n=w();return n.services[i.name]={definition:e,binary:i.binary,registered:(new Date).toISOString(),status:"registered"},$(n),{success:!0,name:i.name,definition:e}}catch(e){throw new Error(`Failed to register service: ${e.message}`)}}};async function F(e){await j.createServiceDirectoryStructure();return{servicesDir:j.getServicesDirectory(),metadataDir:j.getServiceMetadataDirectory(),metadata:j.loadServiceMetadata(),args:e}}var P={getServiceDefinitionSchema:function(e=!0){let n=[];if(e)try{const e=v.getBinDirectory(),i=v.getMetadataFilePath();if(t.existsSync(i)){const e=JSON.parse(t.readFileSync(i,"utf8"));n=Object.keys(e.binaries).map((n=>({name:n,message:`${n} (${e.binaries[n].version||"unknown"})`})))}else t.existsSync(e)&&(n=t.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:n}},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,n)=>{const[i,...t]=n.split("=");return e[i.trim()]=t.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"}}}}};const O={command:"definition <subcommand>",describe:"Manage service definitions",builder:e=>e.command({command:"create",describe:"Create a new service definition",builder:e=>e.option("name",{describe:"Service definition name",type:"string"}).option("output",{describe:"Output file path",type:"string",alias:"o"}),handler:k}).command({command:"list",describe:"List service definitions",builder:e=>e.option("format",{describe:"Output format",type:"string",choices:["json","text","table"],default:"table"}),handler:M}).command({command:"show <name>",describe:"Show service definition details",builder:e=>e.positional("name",{describe:"Service definition name",type:"string"}).option("format",{describe:"Output format",type:"string",choices:["json","yaml"],default:"yaml"}),handler:A}).command({command:"edit <name>",describe:"Edit a service definition",builder:e=>e.positional("name",{describe:"Service definition name",type:"string"}),handler:N}).command({command:"delete <name>",describe:"Delete a service definition",builder:e=>e.positional("name",{describe:"Service definition name",type:"string"}).option("force",{describe:"Force deletion without confirmation",type:"boolean",default:!1,alias:"f"}),handler:T}).command({command:"validate <name>",describe:"Validate a service definition",builder:e=>e.positional("name",{describe:"Service definition name",type:"string"}),handler:I}).demandCommand(1,"You need to specify a subcommand"),handler:()=>{}};async function k(e){try{await F(e);const n=P.getServiceDefinitionSchema(),t=await o({schema:n,format:"yaml"});let r;if(console.log("Result from fnetObjectFromSchema:",t),"string"==typeof t)try{r=(await import("yaml")).default.parse(t)}catch(e){console.warn(i.yellow(`Failed to parse YAML: ${e.message}`)),r={name:"service-"+Date.now()}}else r=t&&"object"==typeof t?t.data||t:{name:"service-"+Date.now()};console.log("Generated definition:",r);const a=e.name||(r&&r.name?r.name:"service-"+Date.now());if(j.serviceDefinitionExists(a)&&!e.force){const{confirmOverwrite:e}=await s({type:"confirm",name:"confirmOverwrite",message:`Service definition '${a}' already exists. Overwrite?`,initial:!1});if(!e)return void console.log(i.yellow("Operation cancelled."))}j.saveServiceDefinition(a,r)?(console.log(i.green(`Service definition '${a}' created successfully.`)),console.log(i.blue(`Location: ${j.getServiceDefinitionPath(a)}`))):console.error(i.red(`Failed to create service definition '${a}'.`))}catch(e){console.error(i.red(`Error: ${e.message}`)),process.exit(1)}}async function M(e){try{await F(e);const n=j.listServiceDefinitions();if(0===n.length)return void console.log(i.yellow("No service definitions found."));if("json"===e.format)console.log(JSON.stringify(n,null,2));else if("text"===e.format)n.forEach((e=>console.log(e)));else{console.log(i.bold("\nService Definitions:")),console.log(i.bold("─".repeat(50)));for(const e of n){const n=j.loadServiceDefinition(e);n&&(console.log(i.green(`${e}`)),console.log(` Binary: ${n.binary}`),n.description&&console.log(` Description: ${n.description}`),console.log(i.bold("─".repeat(50))))}}}catch(e){console.error(i.red(`Error: ${e.message}`)),process.exit(1)}}async function A(e){try{await F(e);const n=j.loadServiceDefinition(e.name);if(n||(console.error(i.red(`Service definition '${e.name}' not found.`)),process.exit(1)),"json"===e.format)console.log(JSON.stringify(n,null,2));else{const e=(await import("yaml")).default;console.log(e.stringify(n))}}catch(e){console.error(i.red(`Error: ${e.message}`)),process.exit(1)}}async function N(e){try{await F(e);const n=j.loadServiceDefinition(e.name);n||(console.error(i.red(`Service definition '${e.name}' not found.`)),process.exit(1));const t=P.getServiceDefinitionSchema(),r=(await o({schema:t,ref:n,format:"yaml"})).data;j.saveServiceDefinition(e.name,r)?console.log(i.green(`Service definition '${e.name}' updated successfully.`)):console.error(i.red(`Failed to update service definition '${e.name}'.`))}catch(e){console.error(i.red(`Error: ${e.message}`)),process.exit(1)}}async function T(e){try{await F(e);if(j.serviceDefinitionExists(e.name)||(console.error(i.red(`Service definition '${e.name}' not found.`)),process.exit(1)),!e.force){const{confirmDelete:n}=await s({type:"confirm",name:"confirmDelete",message:`Are you sure you want to delete service definition '${e.name}'?`,initial:!1});if(!n)return void console.log(i.yellow("Operation cancelled."))}j.deleteServiceDefinition(e.name)?console.log(i.green(`Service definition '${e.name}' deleted successfully.`)):console.error(i.red(`Failed to delete service definition '${e.name}'.`))}catch(e){console.error(i.red(`Error: ${e.message}`)),process.exit(1)}}async function I(e){try{await F(e);const n=j.loadServiceDefinition(e.name);n||(console.error(i.red(`Service definition '${e.name}' not found.`)),process.exit(1));const t=j.validateServiceDefinition(n);t.valid?console.log(i.green(`Service definition '${e.name}' is valid.`)):(console.error(i.red(`Service definition '${e.name}' is invalid:`)),t.errors.forEach((e=>{console.error(i.red(`- ${e}`))})),process.exit(1))}catch(e){console.error(i.red(`Error: ${e.message}`)),process.exit(1)}}const U={command:"register",describe:"Register a service definition as a system service",builder:e=>e.option("definition",{describe:"Service definition name",type:"string",demandOption:!0,alias:"d"}).option("start",{describe:"Start the service after registration",type:"boolean",default:!1}),handler:async e=>{try{await F(e);j.serviceDefinitionExists(e.definition)||(console.error(i.red(`Service definition '${e.definition}' not found.`)),process.exit(1)),console.log(i.blue(`Registering service from definition '${e.definition}'...`));const n=await j.registerService(e.definition);if(console.log(i.green(`Service '${n.name}' registered successfully.`)),e.start){console.log(i.blue(`Starting service '${n.name}'...`));const e=(await import("@fnet/service")).default;try{await e({action:"start",name:n.name}),console.log(i.green(`Service '${n.name}' started successfully.`));const t=j.loadServiceMetadata();t.services[n.name]&&(t.services[n.name].status="running",t.services[n.name].lastStarted=(new Date).toISOString(),j.saveServiceMetadata(t))}catch(e){console.error(i.red(`Failed to start service: ${e.message}`))}}}catch(e){console.error(i.red(`Error: ${e.message}`)),process.exit(1)}}},C={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-definition",{describe:"Keep the service definition",type:"boolean",default:!0}).option("force",{describe:"Force unregistration without confirmation",type:"boolean",default:!1,alias:"f"}),handler:async e=>{try{await F(e);const n=j.loadServiceMetadata();if(n.services[e.name]||(console.error(i.red(`Service '${e.name}' not found in metadata.`)),process.exit(1)),!e.force){const{confirmUnregister:n}=await s({type:"confirm",name:"confirmUnregister",message:`Are you sure you want to unregister service '${e.name}'?`,initial:!1});if(!n)return void console.log(i.yellow("Operation cancelled."))}console.log(i.blue(`Unregistering service '${e.name}'...`));const t=(await import("@fnet/service")).default;try{const r=n.services[e.name].definition,o=j.loadServiceDefinition(r);if(!o)throw new Error(`Service definition '${r}' not found`);const s=!1!==o.system;try{await t({action:"stop",name:e.name,system:s}),console.log(i.blue(`Service '${e.name}' stopped.`))}catch(e){console.warn(i.yellow(`Warning: Failed to stop service: ${e.message}`))}if(await t({action:"unregister",name:e.name,system:s}),console.log(i.green(`Service '${e.name}' unregistered successfully.`)),delete n.services[e.name],j.saveServiceMetadata(n),!e.keepDefinition&&r&&j.serviceDefinitionExists(r)){j.deleteServiceDefinition(r)?console.log(i.green(`Service definition '${r}' deleted.`)):console.warn(i.yellow(`Warning: Failed to delete service definition '${r}'.`))}}catch(e){console.error(i.red(`Failed to unregister service: ${e.message}`)),process.exit(1)}}catch(e){console.error(i.red(`Error: ${e.message}`)),process.exit(1)}}},H={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 F(e);const n=j.loadServiceMetadata();n.services[e.name]||(console.error(i.red(`Service '${e.name}' not found in metadata.`)),process.exit(1)),console.log(i.blue(`Starting service '${e.name}'...`));const t=(await import("@fnet/service")).default;try{const r=n.services[e.name].definition,o=j.loadServiceDefinition(r);if(!o)throw new Error(`Service definition '${r}' not found`);await t({action:"start",name:e.name,system:!1!==o.system}),console.log(i.green(`Service '${e.name}' started successfully.`)),n.services[e.name].status="running",n.services[e.name].lastStarted=(new Date).toISOString(),j.saveServiceMetadata(n)}catch(e){console.error(i.red(`Failed to start service: ${e.message}`)),process.exit(1)}}catch(e){console.error(i.red(`Error: ${e.message}`)),process.exit(1)}}},B={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 F(e);const n=j.loadServiceMetadata();n.services[e.name]||(console.error(i.red(`Service '${e.name}' not found in metadata.`)),process.exit(1)),console.log(i.blue(`Stopping service '${e.name}'...`));const t=(await import("@fnet/service")).default;try{const r=n.services[e.name].definition,o=j.loadServiceDefinition(r);if(!o)throw new Error(`Service definition '${r}' not found`);await t({action:"stop",name:e.name,system:!1!==o.system}),console.log(i.green(`Service '${e.name}' stopped successfully.`)),n.services[e.name].status="stopped",n.services[e.name].lastStopped=(new Date).toISOString(),j.saveServiceMetadata(n)}catch(e){console.error(i.red(`Failed to stop service: ${e.message}`)),process.exit(1)}}catch(e){console.error(i.red(`Error: ${e.message}`)),process.exit(1)}}},R={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 F(e);const n=j.loadServiceMetadata();n.services[e.name]||(console.error(i.red(`Service '${e.name}' not found in metadata.`)),process.exit(1)),console.log(i.blue(`Restarting service '${e.name}'...`));const t=(await import("@fnet/service")).default;try{await t({action:"stop",name:e.name}),console.log(i.blue(`Service '${e.name}' stopped.`)),await t({action:"start",name:e.name}),console.log(i.green(`Service '${e.name}' restarted successfully.`)),n.services[e.name].status="running",n.services[e.name].lastRestarted=(new Date).toISOString(),j.saveServiceMetadata(n)}catch(e){console.error(i.red(`Failed to restart service: ${e.message}`)),process.exit(1)}}catch(e){console.error(i.red(`Error: ${e.message}`)),process.exit(1)}}},z={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 F(e);const n=j.loadServiceMetadata();n.services[e.name]||(console.error(i.red(`Service '${e.name}' not found in metadata.`)),process.exit(1)),console.log(i.blue(`Checking status of service '${e.name}'...`));const t=(await import("@fnet/service")).default;try{const r=n.services[e.name].definition,o=j.loadServiceDefinition(r);if(!o)throw new Error(`Service definition '${r}' not found`);const s=await t({action:"status",name:e.name,system:!1!==o.system});console.log(i.green(`Service '${e.name}' status: ${s}`)),n.services[e.name].status=s||"unknown",n.services[e.name].lastChecked=(new Date).toISOString(),j.saveServiceMetadata(n),"json"===e.format?console.log(JSON.stringify({name:e.name,status:s||"unknown",definition:n.services[e.name].definition,binary:n.services[e.name].binary},null,2)):"text"===e.format?(console.log(`Name: ${e.name}`),console.log(`Status: ${s||"unknown"}`),console.log(`Definition: ${n.services[e.name].definition}`),console.log(`Binary: ${n.services[e.name].binary}`)):(console.log(i.bold("\nService Status:")),console.log(i.bold("─".repeat(50))),console.log(`${i.bold("Name:")} ${e.name}`),console.log(`${i.bold("Status:")} ${function(e){switch(e){case"running":return i.green;case"stopped":return i.yellow;case"failed":return i.red;default:return i.gray}}(s)(s||"unknown")}`),console.log(`${i.bold("Definition:")} ${n.services[e.name].definition}`),console.log(`${i.bold("Binary:")} ${n.services[e.name].binary}`),console.log(i.bold("─".repeat(50))))}catch(e){console.error(i.red(`Failed to check service status: ${e.message}`)),process.exit(1)}}catch(e){console.error(i.red(`Error: ${e.message}`)),process.exit(1)}}};const J={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 F(e);const n=j.loadServiceMetadata();let t=Object.entries(n.services).map((([e,n])=>({name:e,...n})));if(e.binary&&(t=t.filter((n=>n.binary===e.binary))),e.status&&(t=t.filter((n=>n.status===e.status))),0===t.length)return void console.log(i.yellow("No services found."));"json"===e.format?console.log(JSON.stringify(t,null,2)):"text"===e.format?t.forEach((e=>{console.log(`${e.name} (${e.status||"unknown"})`)})):(console.log(i.bold("\nRegistered Services:")),console.log(i.bold("─".repeat(80))),console.log(i.bold("NAME").padEnd(20)+i.bold("STATUS").padEnd(15)+i.bold("BINARY").padEnd(20)+i.bold("DEFINITION")),console.log(i.bold("─".repeat(80))),t.forEach((e=>{const n=function(e){switch(e){case"running":return i.green;case"stopped":return i.yellow;case"failed":return i.red;default:return i.gray}}(e.status);console.log(e.name.padEnd(20)+n(e.status||"unknown").padEnd(15)+e.binary.padEnd(20)+e.definition)})),console.log(i.bold("─".repeat(80))),console.log(`Total: ${t.length} service(s)`))}catch(e){console.error(i.red(`Error: ${e.message}`)),process.exit(1)}}};const L=d(import.meta.url),{version:W}=L("../../package.json");e(n(process.argv)).scriptName("fservice").usage("Usage: $0 <command> [options]").version(W).command(O).command(U).command(C).command(H).command(B).command(R).command(z).command(J).demandCommand(1,"You need to specify a command").strict().help().alias("h","help").alias("v","version").epilogue("For more information, visit https://flownet.com").fail(((e,n,t)=>{n?(console.error(i.red(`Error: ${n.message}`)),console.error(n)):console.error(i.red(`Error: ${e}`)),console.error(i.yellow("\nUsage:"),t.help()),process.exit(1)})).parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fnet/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.117.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist",
|
|
6
6
|
"template"
|
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
"build": "rollup --config",
|
|
12
12
|
"build:dev": "rollup --config --sourcemap --environment DEVELOPMENT",
|
|
13
13
|
"deploy": "bun publish --access public",
|
|
14
|
-
"watch": "rollup --config --watch --sourcemap --environment DEVELOPMENT"
|
|
15
|
-
"postbuild": "chmod +x dist/fnode/index.js dist/fnet/index.js dist/frun/index.js dist/fbin/index.js"
|
|
14
|
+
"watch": "rollup --config --watch --sourcemap --environment DEVELOPMENT"
|
|
16
15
|
},
|
|
17
16
|
"repository": {
|
|
18
17
|
"type": "git",
|
|
@@ -42,11 +41,12 @@
|
|
|
42
41
|
"@fnet/object-from-schema": "^0.1.25",
|
|
43
42
|
"@fnet/prompt": "^0.2.16",
|
|
44
43
|
"@fnet/rollup-plugin-delete": "^0.1.10",
|
|
45
|
-
"@fnet/
|
|
44
|
+
"@fnet/service": "^0.1.7",
|
|
45
|
+
"@fnet/shell-flow": "^0.1.50",
|
|
46
46
|
"@fnet/shelljs": "^0.2.4",
|
|
47
47
|
"@fnet/to-pyip": "^0.1.7",
|
|
48
48
|
"@fnet/to-rust": "^0.1.14",
|
|
49
|
-
"@fnet/up-list-files": "^0.1.
|
|
49
|
+
"@fnet/up-list-files": "^0.1.14",
|
|
50
50
|
"@fnet/yaml": "^0.1.40",
|
|
51
51
|
"@node-red/util": "^4.0.9",
|
|
52
52
|
"ajv": "^8.17.1",
|
|
@@ -76,7 +76,8 @@
|
|
|
76
76
|
"fnet": "dist/fnet/index.js",
|
|
77
77
|
"fnode": "dist/fnode/index.js",
|
|
78
78
|
"frun": "dist/frun/index.js",
|
|
79
|
-
"fbin": "dist/fbin/index.js"
|
|
79
|
+
"fbin": "dist/fbin/index.js",
|
|
80
|
+
"fservice": "dist/fservice/index.js"
|
|
80
81
|
},
|
|
81
82
|
"devDependencies": {
|
|
82
83
|
"@rollup/plugin-commonjs": "^28.0.3",
|
|
@@ -84,6 +85,6 @@
|
|
|
84
85
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
85
86
|
"@rollup/plugin-replace": "^6.0.2",
|
|
86
87
|
"@rollup/plugin-terser": "^0.4.4",
|
|
87
|
-
"rollup": "^4.40.
|
|
88
|
+
"rollup": "^4.40.2"
|
|
88
89
|
}
|
|
89
90
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{% if atom.doc.features.cli.enabled===true %}
|
|
2
2
|
import argv from '../default/input.args.js';
|
|
3
|
+
import { schema as inputSchema } from '../default/validate_input.js';
|
|
3
4
|
import { default as Engine } from '../default/{{atom.doc.features.cli_default_entry_file or atom.doc.features.main_default_entry_file}}';
|
|
4
5
|
|
|
5
6
|
{% if atom.doc.features.cli.extend===true %}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{% if atom.doc.features.project.format === 'esm' %}
|
|
2
2
|
import fnetArgs from '@fnet/args';
|
|
3
|
-
import validate from "./validate_input";
|
|
3
|
+
import validate,{schema as inputSchema} from "./validate_input";
|
|
4
|
+
|
|
4
5
|
{% elif atom.doc.features.project.format === 'cjs' %}
|
|
5
6
|
const fnetArgs = require('@fnet/args');
|
|
6
|
-
const validate = require("./validate_input");
|
|
7
|
+
const validate,{schema as inputSchema} = require("./validate_input");
|
|
7
8
|
{% endif %}
|
|
8
9
|
|
|
9
10
|
{% if atom.doc.features.cli.fargs and atom.doc.features.cli.fargs?.enabled !== false %}
|
|
@@ -38,7 +39,7 @@
|
|
|
38
39
|
|
|
39
40
|
export default async () => {
|
|
40
41
|
|
|
41
|
-
let schema =
|
|
42
|
+
let schema = inputSchema;
|
|
42
43
|
let initial;
|
|
43
44
|
|
|
44
45
|
{% if atom.doc.features.cli.fargs and atom.doc.features.cli.fargs?.enabled !== false %}
|
|
@@ -77,7 +78,8 @@
|
|
|
77
78
|
{% elif atom.doc.features.project.format === 'cjs' %}
|
|
78
79
|
|
|
79
80
|
module.exports = async () => {
|
|
80
|
-
|
|
81
|
+
|
|
82
|
+
let schema = inputSchema;
|
|
81
83
|
let initial;
|
|
82
84
|
|
|
83
85
|
{% if atom.doc.features.cli.fargs and atom.doc.features.cli.fargs?.enabled !== false %}
|
|
@@ -27,15 +27,7 @@ import express from "express";
|
|
|
27
27
|
tools: [{
|
|
28
28
|
name: "{{atom.doc.features.cli.mcp.tool.name or atom.doc.name}}",
|
|
29
29
|
description: "{{atom.doc.features.cli.mcp.tool.description or atom.doc.description}}",
|
|
30
|
-
|
|
31
|
-
inputSchema: {{atom.doc.input | dump | safe}}
|
|
32
|
-
{% else %}
|
|
33
|
-
inputSchema: {
|
|
34
|
-
type: "object",
|
|
35
|
-
properties: {},
|
|
36
|
-
additionalProperties: true
|
|
37
|
-
}
|
|
38
|
-
{% endif %}
|
|
30
|
+
inputSchema: inputSchema,
|
|
39
31
|
}]
|
|
40
32
|
};
|
|
41
33
|
});
|
|
@@ -125,15 +117,7 @@ import express from "express";
|
|
|
125
117
|
tools: [{
|
|
126
118
|
name: "{{atom.doc.features.cli.mcp.tool.name or atom.doc.name}}",
|
|
127
119
|
description: "{{atom.doc.features.cli.mcp.tool.description or atom.doc.description}}",
|
|
128
|
-
|
|
129
|
-
inputSchema: {{atom.doc.input | dump | safe}}
|
|
130
|
-
{% else %}
|
|
131
|
-
inputSchema: {
|
|
132
|
-
type: "object",
|
|
133
|
-
properties: {},
|
|
134
|
-
additionalProperties: true
|
|
135
|
-
}
|
|
136
|
-
{% endif %}
|
|
120
|
+
inputSchema: inputSchema,
|
|
137
121
|
}]
|
|
138
122
|
};
|
|
139
123
|
});
|
|
@@ -234,14 +218,14 @@ import express from "express";
|
|
|
234
218
|
{% macro defaultModeExtended() %}
|
|
235
219
|
if (cliMode === 'default') {
|
|
236
220
|
// Default mode code
|
|
237
|
-
return await runExtended(
|
|
221
|
+
return await runExtended(await argv(), { Engine });
|
|
238
222
|
}
|
|
239
223
|
{% endmacro %}
|
|
240
224
|
|
|
241
225
|
{% macro defaultModeEngine(engineVar) %}
|
|
242
226
|
if (cliMode === 'default') {
|
|
243
227
|
// Default mode code
|
|
244
|
-
const result = await {{ engineVar }}.run(
|
|
228
|
+
const result = await {{ engineVar }}.run(await argv());
|
|
245
229
|
|
|
246
230
|
if (typeof result !== 'undefined') {
|
|
247
231
|
const stdout_format = args['stdout-format'] || args.stdout_format || null;
|
|
@@ -274,6 +258,7 @@ run()
|
|
|
274
258
|
|
|
275
259
|
{# Main template starts here #}
|
|
276
260
|
import argv from '../default/input.args.js';
|
|
261
|
+
import { schema as inputSchema } from '../default/validate_input.js';
|
|
277
262
|
import { default as Engine } from '../default/{{atom.doc.features.cli_default_entry_file or atom.doc.features.main_default_entry_file}}';
|
|
278
263
|
|
|
279
264
|
{% if atom.doc.features.cli.mcp.enabled===true %}
|
|
@@ -286,9 +271,10 @@ import express from 'express';
|
|
|
286
271
|
{% if atom.doc.features.cli.extend===true %}
|
|
287
272
|
{# TYPE 1 #}
|
|
288
273
|
import { default as runExtended } from '../../../cli';
|
|
274
|
+
import minimist from 'minimist';
|
|
289
275
|
|
|
290
276
|
const run = async () => {
|
|
291
|
-
const args =
|
|
277
|
+
const args = minimist(process.argv.slice(2));
|
|
292
278
|
const cliMode = args['cli-mode'] || args.cli_mode || 'default';
|
|
293
279
|
|
|
294
280
|
{{ defaultModeExtended() }}
|
|
@@ -308,8 +294,9 @@ import express from 'express';
|
|
|
308
294
|
{{ runWithThenCatch() }}
|
|
309
295
|
{% else %}
|
|
310
296
|
{# TYPE 2 #}
|
|
297
|
+
import minimist from 'minimist';
|
|
311
298
|
const run = async () => {
|
|
312
|
-
const args =
|
|
299
|
+
const args =minimist(process.argv.slice(2));
|
|
313
300
|
const cliMode = args['cli-mode'] || args.cli_mode || 'default';
|
|
314
301
|
const engine = new Engine();
|
|
315
302
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{% if atom.doc.features.project.format === 'esm' %}
|
|
2
2
|
import fnetArgs from '@fnet/args';
|
|
3
|
-
import validate from "./validate_input";
|
|
3
|
+
import validate,{schema as inputSchema} from "./validate_input";
|
|
4
|
+
|
|
4
5
|
{% elif atom.doc.features.project.format === 'cjs' %}
|
|
5
6
|
const fnetArgs = require('@fnet/args');
|
|
6
|
-
const validate = require("./validate_input");
|
|
7
|
+
const validate,{schema as inputSchema} = require("./validate_input");
|
|
7
8
|
{% endif %}
|
|
8
9
|
|
|
9
10
|
{% if atom.doc.features.cli.fargs and atom.doc.features.cli.fargs?.enabled !== false %}
|
|
@@ -38,7 +39,7 @@
|
|
|
38
39
|
|
|
39
40
|
export default async () => {
|
|
40
41
|
|
|
41
|
-
let schema =
|
|
42
|
+
let schema = inputSchema;
|
|
42
43
|
let initial;
|
|
43
44
|
|
|
44
45
|
{% if atom.doc.features.cli.fargs and atom.doc.features.cli.fargs?.enabled !== false %}
|
|
@@ -77,7 +78,8 @@
|
|
|
77
78
|
{% elif atom.doc.features.project.format === 'cjs' %}
|
|
78
79
|
|
|
79
80
|
module.exports = async () => {
|
|
80
|
-
|
|
81
|
+
|
|
82
|
+
let schema = inputSchema;
|
|
81
83
|
let initial;
|
|
82
84
|
|
|
83
85
|
{% if atom.doc.features.cli.fargs and atom.doc.features.cli.fargs?.enabled !== false %}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{% if atom.doc.features.project.format === 'esm' %}
|
|
2
2
|
import fnetArgs from '@fnet/args';
|
|
3
|
-
import validate from "./validate_input";
|
|
3
|
+
import validate,{schema as inputSchema} from "./validate_input";
|
|
4
|
+
|
|
4
5
|
{% elif atom.doc.features.project.format === 'cjs' %}
|
|
5
6
|
const fnetArgs = require('@fnet/args');
|
|
6
|
-
const validate = require("./validate_input");
|
|
7
|
+
const validate,{schema as inputSchema} = require("./validate_input");
|
|
7
8
|
{% endif %}
|
|
8
9
|
|
|
9
10
|
{% if atom.doc.features.cli.fargs and atom.doc.features.cli.fargs?.enabled !== false %}
|
|
@@ -38,7 +39,7 @@
|
|
|
38
39
|
|
|
39
40
|
export default async () => {
|
|
40
41
|
|
|
41
|
-
let schema =
|
|
42
|
+
let schema = inputSchema;
|
|
42
43
|
let initial;
|
|
43
44
|
|
|
44
45
|
{% if atom.doc.features.cli.fargs and atom.doc.features.cli.fargs?.enabled !== false %}
|
|
@@ -77,7 +78,8 @@
|
|
|
77
78
|
{% elif atom.doc.features.project.format === 'cjs' %}
|
|
78
79
|
|
|
79
80
|
module.exports = async () => {
|
|
80
|
-
|
|
81
|
+
|
|
82
|
+
let schema = inputSchema;
|
|
81
83
|
let initial;
|
|
82
84
|
|
|
83
85
|
{% if atom.doc.features.cli.fargs and atom.doc.features.cli.fargs?.enabled !== false %}
|