@crossdelta/platform-sdk 0.18.3 → 0.18.4
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/CHANGELOG.md +40 -0
- package/bin/cli.js +158 -149
- package/bin/docs/generators/service.md +9 -0
- package/bin/templates/workspace/infra/package.json.hbs +1 -1
- package/bin/templates/workspace/packages/contracts/README.md.hbs +2 -2
- package/bin/templates/workspace/packages/contracts/package.json.hbs +1 -1
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";var
|
|
3
|
-
`)}function
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
"use strict";var kc=Object.create;var Nn=Object.defineProperty;var vc=Object.getOwnPropertyDescriptor;var Cc=Object.getOwnPropertyNames;var xc=Object.getPrototypeOf,wc=Object.prototype.hasOwnProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var bc=(e,t)=>{for(var n in t)Nn(e,n,{get:t[n],enumerable:!0})},Sc=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Cc(t))!wc.call(e,o)&&o!==n&&Nn(e,o,{get:()=>t[o],enumerable:!(r=vc(t,o))||r.enumerable});return e};var u=(e,t,n)=>(n=e!=null?kc(xc(e)):{},Sc(t||!e||!e.__esModule?Nn(n,"default",{value:e,enumerable:!0}):n,e));var Dd,po,Rn,Rt=N(()=>{"use strict";Dd=process.env.npm_package_version||"0.0.0",po=["bun.lock","bun.lockb","package-lock.json","yarn.lock","pnpm-lock.yaml"],Rn="start:dev"});function Mn(e,t){if(e.length===0)return"No entries to display.";let n=t?.title||"Benchmark Results",r=t?.footer||"",o=t?.maxBarWidth||50,s=t?.unit||"",a=Math.max(...e.map(c=>c.value)),i=[];i.push(""),i.push(n),i.push("");for(let c of e){let l=Pc(c.barColor??t?.barColor),p=Tc(c,a,o,l,s,t?.labelColor);i.push(p)}return r&&(i.push(""),i.push(r)),i.join(`
|
|
3
|
+
`)}function Pc(e){return e?nt.default[e]("\u2587"):"\u2587"}function Tc(e,t,n,r,o,s){let a=Math.round(e.value/t*n),i=e.barColor?nt.default[e.barColor](r.repeat(a)):r.repeat(a),c=e.color??s;return`${nt.default.bold(c?nt.default[c](e.label.padEnd(12)):e.label.padEnd(12))} ${i} ${e.value.toLocaleString()}${o?` ${o}`:""}`}var nt,mo=N(()=>{"use strict";nt=u(require("chalk"))});var me,jt,Mt,jn,Ft,Ec,uo,Fn,$c,go,On=N(()=>{"use strict";me=require("node:fs"),jt=require("node:path"),Mt=u(require("chokidar"));g();v();jn=".pf-generating",Ft=e=>(0,jt.join)(e,jn),Ec=e=>(0,me.existsSync)(Ft(e)),uo=e=>{(0,me.writeFileSync)(Ft(e),"","utf-8")},Fn=e=>{let t=Ft(e);(0,me.existsSync)(t)&&(0,me.unlinkSync)(t)},$c=e=>{let n=G(e)?.pf?.paths;return n?Object.values(n).filter(r=>typeof r=="object"&&r!==null&&r.watch===!0&&typeof r.path=="string"):[{path:"services"},{path:"apps"}]},go=(e,t)=>{Fn(e);let n=$c(e),r=Ft(e),s=Ot(async()=>{Ec(e)||await t()},300),a=[];a.push(Mt.default.watch(r,{ignoreInitial:!0}).on("unlink",()=>t()));for(let i of n){let c=(0,jt.join)(e,i.path);if(!(0,me.existsSync)(c))continue;let l=i.ignorePatterns?.map(p=>(0,jt.join)(c,p));a.push(Mt.default.watch(c,{ignoreInitial:!0,depth:0,ignored:l,usePolling:!0,interval:1e3}).on("addDir",p=>p!==c&&s()).on("unlinkDir",p=>p!==c&&s())),a.push(Mt.default.watch(`${c}/*/package.json`,{ignoreInitial:!0,ignored:l}).on("add",s).on("change",s))}return console.log("\u{1F440} Watching for changes..."),console.log(" Press Ctrl+C twice to exit (first stops Turbo, second triggers cleanup)"),async()=>{await Promise.all(a.map(i=>i.close()))}}});var rt,m,_n=N(()=>{"use strict";rt=u(require("chalk")),m={logs:[],breakLine:()=>(console.log(),m),success:(e,...t)=>(console.log(rt.default.green(`\u2714 ${e}`),...t),m),info:(e,...t)=>(console.log(rt.default.cyan(`\u{1F6C8} ${e}`),...t),m),warn:(e,...t)=>(console.warn(rt.default.yellow(`\u26A0\uFE0E ${e}`),...t),m),error:(e,...t)=>(console.error(rt.default.red(`\u2716 ${e}`),...t),m),log:(e,...t)=>(console.log(e,...t),m.logs.push({message:e,context:t.join()}),m),getStoredLogs:e=>e?m.logs.filter(t=>t.context?.includes(e)):m.logs,storeLog:(e,t)=>m.logs.push({message:e,context:t})}});var Dn,ho,Ln,q,Ac,fo,yo=N(()=>{"use strict";Dn=u(require("chalk")),ho=require("commander"),Ln=require("listr2");On();v();_n();q=e=>{let t=new ho.Command(e.name).description(e.description).showHelpAfterError();e.arguments?.forEach(([s,a])=>{t.argument(s,a)}),e.options?.forEach(([s,a])=>{t.option(s,a)}),e.exampleUsage&&t.addHelpText("after",()=>`${Dn.default.cyan.bold(`
|
|
4
|
+
Example:`)}
|
|
5
|
+
${Dn.default.bold(e.exampleUsage)}
|
|
6
|
+
`),e.additionalInfo&&t.addHelpText("after",()=>(typeof e.additionalInfo=="function"?e.additionalInfo():e.additionalInfo)??"");let n=async s=>{e.prompts?.length&&await new Ln.Listr(fo(e.prompts,s),{rendererOptions:{lazy:!0,showErrorMessage:!1}}).run(s),await new Ln.Listr(fo(e.actions,s),{rendererOptions:{lazy:!1,showErrorMessage:!1}}).run(s),await e.onComplete?.(s)},r=()=>{try{let s=y();return uo(s),s}catch{return null}},o=s=>{m.error(s.message)};return t.action(async(...s)=>{let a=null;try{let i=s.at(-1),c=i.args,l=i.opts(),p=Ac(e.arguments??[],c);if(e.shouldSkipWorkflow?.(p,l)){await e.onSkipWorkflow?.(p,l);return}let d=await e.buildContext(p,l);a=r(),await n(d)}catch(i){o(i)}finally{a&&Fn(a)}}),t},Ac=(e,t)=>{let n=e.map(([r],o)=>[r.replace(/[<>[\]]/g,""),t[o]]);return Object.fromEntries(n)},fo=(e,t)=>e.map(n=>typeof n=="function"?n(t):n)});var Ot,ko=N(()=>{"use strict";Ot=(e,t)=>{let n=null;return(...r)=>(n&&clearTimeout(n),new Promise(o=>{n=setTimeout(async()=>{n=null,await e(...r),o()},t)}))}});function _t(e,t,n){let r=t.split("."),o=e;for(;r.length>1;){let s=r.shift();s in o||(o[s]={}),o=o[s]}o[r[0]]=n}var vo=N(()=>{"use strict"});function ot(e){try{return(0,Co.execaSync)(e,["--version"]),!0}catch{return!1}}var Co,Hn=N(()=>{"use strict";Co=require("execa")});var xo=N(()=>{"use strict";Hn()});function Po(){let e=(0,bo.packageUpSync)({cwd:(0,$e.dirname)(__filename)});if(!e)throw new Error("Could not find package.json");return(0,$e.dirname)(e)}var $e,wo,bo,So,f,Dt,To,Eo=N(()=>{"use strict";$e=require("node:path"),wo=require("fs-extra"),bo=require("package-up"),So=require("rimraf"),f=e=>(0,$e.join)(process.cwd(),e),Dt=e=>{try{return(0,wo.readdirSync)(e).length===0}catch{return!0}};To=e=>(0,So.rimraf)(e)});var $o=N(()=>{"use strict"});async function T(e,t){let n=Date.now(),r=e.title,o=()=>Math.floor((Date.now()-n)/1e3),s=setInterval(()=>{o()>1&&(e.title=`${r} (${o()}s)`)},1e3);try{return await t(o)}finally{clearInterval(s)}}async function Lt(e,t,n){for(let r=0;r<t.length;r++){let o=t[r];e.output=Ao.default.dim(`[${r+1}/${t.length}] ${o.title}`),await o.fn(n??{},e)}}var Ao,Io=N(()=>{"use strict";Ao=u(require("chalk"))});var g=N(()=>{"use strict";mo();yo();ko();vo();xo();Eo();_n();$o();Hn();Io()});var Mo={};bc(Mo,{findWorkspaceRoot:()=>y,getContractsConfig:()=>x,getGeneratorConfig:()=>Ae,getPackageJsonField:()=>Un,getPkgJson:()=>Jn,getRootPackageScope:()=>xe,getWorkspacePackageJson:()=>G,getWorkspacePathsConfig:()=>E,isInWorkspace:()=>Gn,pkgJson:()=>O,readPackageConfig:()=>at,updatePackageJsonField:()=>V});var ve,R,Ce,st,Ic,Wn,Ht,Nc,Rc,No,Mc,jc,Ro,Gn,y,G,E,x,xe,Fc,Oc,Un,V,at,Bn,Jn,O,Ae,v=N(()=>{"use strict";ve=require("node:fs"),R=require("node:path"),Ce=require("fs-extra");Rt();g();st={services:"services",apps:"apps",packages:"packages",contracts:"packages/contracts"},Ic={docs:{base:["service.md"],frameworks:{}},serviceTypes:{hono:{commandType:"hono-micro",entryPoint:"src/index.ts",skipFiles:[]},nest:{commandType:"nest-micro",entryPoint:"src/main.ts",skipFiles:[]}}},Wn=e=>{if(!(0,ve.existsSync)(e))return null;try{return JSON.parse((0,ve.readFileSync)(e,"utf-8"))}catch{return null}},Ht=(e,t)=>typeof e=="string"?e:typeof e=="object"&&e!==null&&"path"in e?e.path:t,Nc=e=>e.split("/").pop()||"workspace",Rc=e=>{let t=e.slice(0,e.lastIndexOf("/"));return t===e?null:t},No=e=>e.split("."),Mc=(e,t)=>{if(!e.workspaces)return!1;if(e.pf||(0,ve.existsSync)((0,R.join)(t,"turbo.json")))return!0;let n=po.some(o=>(0,ve.existsSync)((0,R.join)(t,o))),r=(0,ve.existsSync)((0,R.join)(t,"infra"));return n&&r},jc=e=>{let t=Wn((0,R.join)(e,"package.json"));return t?Mc(t,e):!1},Ro=e=>{let t=e;for(;t;){if(jc(t))return t;t=Rc(t)}return null},Gn=()=>Ro(process.cwd())!==null,y=()=>{let e=Ro(process.cwd());if(!e)throw new Error(`
|
|
7
|
+
\x1B[31m\u2716\x1B[0m Not in a workspace directory
|
|
8
|
+
|
|
9
|
+
Current directory: ${process.cwd()}
|
|
10
|
+
|
|
11
|
+
This command must be run from within a workspace created with \x1B[36mpf new workspace\x1B[0m
|
|
12
|
+
|
|
13
|
+
To create a new workspace, run:
|
|
14
|
+
|
|
15
|
+
\x1B[36mpf new workspace my-platform\x1B[0m
|
|
16
|
+
`);return e},G=e=>{let t=e??y();return Wn((0,R.join)(t,"package.json"))},E=e=>{let t=G(e);if(!t?.pf?.paths)return st;let{paths:n}=t.pf;return{services:Ht(n.services,st.services),apps:Ht(n.apps,st.apps),packages:Ht(n.packages,st.packages),contracts:Ht(n.contracts,st.contracts)}},x=e=>{let t=e??y(),n=E(t),r=(0,R.join)(t,n.contracts);return{packagePath:r,eventsPath:(0,R.join)(r,"src","events"),indexPath:(0,R.join)(r,"src","index.ts"),relativePath:n.contracts}},xe=()=>{let e=y(),t=Wn((0,R.join)(e,"package.json")),n=`@${Nc(e)}`;return t?.name?t.name.startsWith("@")?t.name.split("/")[0]:`@${t.name}`:n},Fc=(e,t)=>{let n=No(t),r=e;for(let o of n){if(r===null||typeof r!="object"||!(o in r))return;r=r[o]}return r},Oc=(e,t,n)=>{let r=No(t),o=r[r.length-1],s=e;for(let a of r.slice(0,-1))(!(a in s)||typeof s[a]!="object"||s[a]===null)&&(s[a]={}),s=s[a];s[o]=n},Un=(e,t=process.cwd())=>{let n=(0,Ce.readJsonSync)((0,R.join)(t,"package.json"));return Fc(n,e)},V=(e,t,n=process.cwd())=>{let r=(0,R.join)(n,"package.json"),o=(0,Ce.readJsonSync)(r);Oc(o,e,t),(0,Ce.writeJsonSync)(r,o,{spaces:2,EOL:`
|
|
17
|
+
`,encoding:"utf-8"})},at=e=>{let t=Po();return(0,Ce.readJSONSync)((0,R.resolve)(t,e),{encoding:"utf-8"})},Bn=null,Jn=()=>(Bn||(Bn=at("package.json")),Bn),O=new Proxy({},{get:(e,t)=>Jn()[t]}),Ae=()=>Jn().generatorConfig??Ic});var pc=require("node:process"),Ee=u(require("chalk")),mc=require("commander"),dc=u(require("terminal-link"));var Zo=u(require("chalk")),Yo=require("commander");v();var Wo=require("node:fs"),Go=require("node:path"),Vn=require("node:process"),Uo=require("execa");g();var qn=require("node:child_process"),Do=require("node:path"),Lo=require("execa");g();var jo=require("node:fs"),Fo=require("node:path"),Oo=require("dotenv"),zn=(e,t)=>{let n=(0,Fo.resolve)(t,e);return(0,jo.existsSync)(n)?(0,Oo.config)({path:n,processEnv:{}}).parsed||{}:{}},_o=(e,t)=>{let n=zn(e,t),r=[];for(let[o,s]of Object.entries(n))if(o.endsWith("_PORT")&&s){let a=Number.parseInt(s,10);!Number.isNaN(a)&&a>0&&r.push(a)}return r};var Kn={...process.env,NODE_NO_WARNINGS:"1"},_c=(e,t,n)=>e?"pipe":t||n?["ignore","pipe","pipe"]:"inherit",Dc=(e,t,n)=>e?{...Kn,...e}:t||n?{...Kn,CI:"true"}:{...Kn},Lc=e=>e.includes("EEXIST")||e.includes("failed to link package");async function de(e,t,{cwd:n=process.cwd(),task:r,shell:o,context:s=e,quiet:a=!1,nonInteractive:i=!1,env:c}={}){try{t.length===0&&(t=e.split(" ").slice(1));let l=(0,Lo.execa)(e,t,{cwd:n,stdio:_c(a,r,i),all:r||i?!0:void 0,shell:o??!0,env:Dc(c,r,i)});l.all&&l.all.on("data",p=>{let d=p.toString().trim();r?(r.output=d,d.length&&m.storeLog(d,s)):i&&d.length&&console.log(d)}),await l}catch(l){let p=l instanceof Error?l.message:String(l);if(Lc(p))return;throw new Error(Hc(p))}}var Hc=e=>{let t=e.match(/error: (.+)/);return t?t[1].trim():e};function Ho(e,t,n={}){let{cwd:r=process.cwd(),envFile:o,detached:s=!0,pipeStdout:a=!1,onStdout:i,onStderr:c,onExit:l}=n,p=o?zn(o,r):{},d=(0,Do.resolve)(r,"node_modules",".bin"),C=process.env.PATH||"",L=`${d}:${C}`,tt={...process.env,...p,PATH:L,FORCE_COLOR:"1"},H=(0,qn.spawn)(e,t,{cwd:r,env:tt,stdio:["inherit",a?"pipe":"inherit","pipe"],detached:s});return i&&a&&H.stdout?.on("data",i),c&&H.stderr?.on("data",c),l&&H.on("exit",l),H}function Bt(e,t,n={}){let{cwd:r=process.cwd()}=n;(0,qn.spawn)(e,t,{cwd:r,stdio:"inherit",shell:!0}).on("exit",s=>process.exit(s||0))}async function Bo(e){let{execSync:t}=await import("node:child_process");for(let n of e)try{let o=t(`lsof -ti:${n}`,{encoding:"utf8",stdio:"pipe"}).trim().split(`
|
|
18
|
+
`).filter(Boolean);for(let s of o)try{process.kill(Number.parseInt(s,10),"SIGKILL")}catch{}}catch{}}v();var Wt=e=>ot(e);function Zn(e=process.cwd()){let t=n=>(0,Wo.existsSync)((0,Go.join)(e,n));if(t("bun.lock")||t("bun.lockb"))return"bun";if(t("pnpm-lock.yaml"))return"pnpm";if(t("yarn.lock"))return"yarn";if(t("package-lock.json"))return"npm"}function S(e){return Zn(e)??Yn()}function Yn(){return Wt("bun")?"bun":Wt("pnpm")?"pnpm":Wt("yarn")?"yarn":"npm"}function Jo(){return["bun","pnpm","yarn","npm"].filter(Wt)}async function Z(e,t){let n=Wc(e,t),{mergedOptions:r,packages:o}=n,{cwd:s=process.cwd(),flags:a=[],task:i,quiet:c}=r,l=r.packageManager??S(),p=[],d=Array.isArray(o)?o:[o];l==="bun"&&(d=d.map(L=>L.replace("git+ssh://",""))),l==="pnpm"&&(p.push("--config.engine-strict=false"),p.push("--no-frozen-lockfile")),["yarn","npm"].includes(l)&&p.push("--ignore-engines");let C=d.length?l==="npm"?["install",...a,...p,...d]:["add",...a,...p,...d]:["install",...a,...p];await de(l,C,{cwd:s,task:i,quiet:c})}async function zo(e){let t=["-g"],n=[...e.flags??[],...t];await Z({...e,flags:n,packageManager:e.packageManager??S()})}function Ko(e,t,n){let{args:r,mergedOptions:o}=Vo(t??[],n),s=o.manager??S(),{command:a,args:i}=qo(s);console.log(`
|
|
19
|
+
Running command: ${a} ${[...i,e,...r].join(" ")}
|
|
20
|
+
`),(0,Uo.execaSync)(a,[...i,e,...r],{cwd:o.cwd??(0,Vn.cwd)(),stdio:"inherit",preferLocal:!0})}async function se(e,t,n){let{args:r,mergedOptions:o}=Vo(t??[],n),s=o.manager??S(),{command:a,args:i}=qo(s);await de(a,[...i,e,...r],o)}async function it(e,t){let{script:n,mergedOptions:r}=Gc(e,t),o=r.packageManager??S();await de(o,["run",n,...r.args??[]],{cwd:r.cwd??(0,Vn.cwd)(),task:r.task})}function qo(e){let n={bun:"bunx",pnpm:"npx",yarn:"npx",npm:"npx"}[e];if(!n)throw new Error(`No executor found for the detected package manager: ${e}`);let[r,...o]=n.split(" ");return{command:r,args:o}}function Wc(e,t){return Array.isArray(e)?{packages:e,mergedOptions:{...t,packages:e}}:{packages:e.packages??[],mergedOptions:e}}function Vo(e,t){return Array.isArray(e)?{args:e,mergedOptions:t??{}}:{args:[],mergedOptions:e}}function Gc(e,t){return typeof e=="string"?{script:e,mergedOptions:t??{}}:{script:e.script,mergedOptions:e}}var Uc=e=>e==="yarn"?["npm","audit"]:["audit"],Xo=new Yo.Command("audit").description("Run security audit on dependencies").allowUnknownOption(!0).action((e,t)=>{let n=y(),r=S(),o=Uc(r),s=t.args||[];console.log(Zo.default.dim(`Running ${r} ${[...o,...s].join(" ")}`)),Bt(r,[...o,...s],{cwd:n})});var he=require("@listr2/prompt-adapter-enquirer"),le=u(require("chalk"));var Ne=require("node:fs"),ss=require("node:os"),as=require("node:path");var ue=require("node:crypto"),Ie=require("node:fs"),we=require("node:os"),Qo=require("node:path"),Xn=(0,Qo.join)((0,we.homedir)(),".platform-sdk-keys"),es="aes-256-gcm",ts=()=>{let e=`${(0,we.hostname)()}:${(0,we.userInfo)().username}:${(0,we.homedir)()}`;return(0,ue.createHash)("sha256").update(e).digest()},ns=()=>{if(!(0,Ie.existsSync)(Xn))return{};try{return JSON.parse((0,Ie.readFileSync)(Xn,"utf-8"))}catch{return{}}},Jc=e=>{(0,Ie.writeFileSync)(Xn,JSON.stringify(e,null,2),{mode:384})},zc=e=>{let t=ts(),n=(0,ue.randomBytes)(16),r=(0,ue.createCipheriv)(es,t,n),o=r.update(e,"utf8","hex");return o+=r.final("hex"),{iv:n.toString("hex"),tag:r.getAuthTag().toString("hex"),data:o}},Kc=e=>{let t=ts(),n=Buffer.from(e.iv,"hex"),r=Buffer.from(e.tag,"hex"),o=(0,ue.createDecipheriv)(es,t,n);o.setAuthTag(r);let s=o.update(e.data,"hex","utf8");return s+=o.final("utf8"),s};async function rs(e,t){let n=ns();n[e]=zc(t),Jc(n)}async function Gt(e){let n=ns()[e];if(!n)return null;try{return Kc(n)}catch{return null}}var ct={openai:{id:"openai",name:"OpenAI",defaultApiKeyEnvVar:"OPENAI_API_KEY",defaultModel:"gpt-4o-mini",modelsApiUrl:"https://api.openai.com/v1/models",apiKeyUrl:"https://platform.openai.com/api-keys",buildHeaders:e=>({Authorization:`Bearer ${e}`}),parseModelsResponse:e=>e.data??[],modelFilters:[/^gpt-4/,/^gpt-3\.5/,/^o1/,/^o3/]},anthropic:{id:"anthropic",name:"Anthropic (Claude)",defaultApiKeyEnvVar:"ANTHROPIC_API_KEY",defaultModel:"claude-sonnet-4-20250514",modelsApiUrl:"https://api.anthropic.com/v1/models",apiKeyUrl:"https://console.anthropic.com/settings/keys",buildHeaders:e=>({"x-api-key":e,"anthropic-version":"2023-06-01"}),parseModelsResponse:e=>(e.data??[]).map(n=>({id:n.id,created:new Date(n.created_at).getTime()})),modelFilters:[/^claude-/]}};function os(){return Object.entries(ct).map(([e,t])=>({name:t.name,value:e}))}function lt(e){let t=ct[e];if(!t)throw new Error(`Unknown AI provider: ${e}`);return t}var be=(0,as.join)((0,ss.homedir)(),".platform-sdk-ai.json"),qc=()=>{let e="anthropic",t=ct[e];return{provider:e,model:t.defaultModel}},Qn=qc();function pt(){return(0,Ne.existsSync)(be)}function Ut(){if(!pt())throw new Error("AI configuration not found. Please run 'pf ai:setup' to configure your AI provider.");try{let e=(0,Ne.readFileSync)(be,"utf-8"),t=JSON.parse(e);return{...Qn,...t}}catch{throw new Error(`Failed to load AI configuration from ${be}. Please run 'pf setup --ai' again.`)}}function is(e){let t=JSON.stringify(e,null,2);(0,Ne.writeFileSync)(be,t,"utf-8")}async function cs(e,t){await rs(e,t)}async function ls(e){let t=await Gt(e.provider);if(t)return t;let n=ct[e.provider],r=process.env[n.defaultApiKeyEnvVar];if(r)return r;throw new Error("API key not found. Please run 'pf setup --ai' to configure your API key.")}var Vc=async(e,t,n,r)=>{let{createOpenAI:o}=await import("@ai-sdk/openai"),s=o({apiKey:n});if(r.onToken){let{streamText:c}=await import("ai"),l=c({model:s(t),prompt:e,system:r.system,maxOutputTokens:r.maxTokens,temperature:r.temperature}),p="";for await(let d of(await l).textStream)p+=d,r.onToken(d);return p}let{generateText:a}=await import("ai"),{text:i}=await a({model:s(t),prompt:e,system:r.system,maxOutputTokens:r.maxTokens,temperature:r.temperature});return i},Zc=async(e,t,n,r)=>{let{createAnthropic:o}=await import("@ai-sdk/anthropic"),s=o({apiKey:n});if(r.onToken){let{streamText:c}=await import("ai"),l=c({model:s(t),prompt:e,system:r.system,maxOutputTokens:r.maxTokens,temperature:r.temperature}),p="";for await(let d of(await l).textStream)p+=d,r.onToken(d);return p}let{generateText:a}=await import("ai"),{text:i}=await a({model:s(t),prompt:e,system:r.system,maxOutputTokens:r.maxTokens,temperature:r.temperature});return i};async function ps(e,t,n={}){let{system:r,maxTokens:o=4096,temperature:s=.7,onToken:a}=n,i=await ls(e);switch(e.provider){case"openai":return Vc(t,e.model,i,{system:r,maxTokens:o,temperature:s,onToken:a});case"anthropic":return Zc(t,e.model,i,{system:r,maxTokens:o,temperature:s,onToken:a});default:throw new Error(`Unsupported AI provider: ${e.provider}`)}}var ae=require("node:fs"),_e=require("node:path"),qs=require("@inquirer/prompts"),k=u(require("chalk")),Vs=u(require("ora"));var Re=require("node:fs"),mt=require("node:path");On();var dt=(e=__dirname)=>{let t=r=>(0,Re.existsSync)((0,mt.join)(r,"package.json")),n=(0,mt.dirname)(e);if(t(e))return e;if(e==="/")throw new Error("Could not find package.json (package root)");return dt(n)},ms=(e,t)=>{let n=e.find(Re.existsSync);if(!n)throw new Error(t??`Directory not found. Searched in: ${e.join(", ")}`);return n},ds=async e=>{let{getWorkspacePathsConfig:t}=await Promise.resolve().then(()=>(v(),Mo)),n=t(e);return[n.services,n.apps].flatMap(o=>{let s=(0,mt.join)(e,o);if(!(0,Re.existsSync)(s))return[];try{return(0,Re.readdirSync)(s,{withFileTypes:!0}).filter(a=>a.isDirectory()&&a.name!==".gitkeep").map(a=>`${o}/${a.name}`)}catch{return[]}})};var Zt=require("node:fs"),bs=require("node:path"),Ss=require("ts-morph");var M=require("node:fs"),Se=require("node:path"),Jt=require("@crossdelta/cloudevents");v();var gs=e=>e.replace(/\./g,"-").toLowerCase(),us=e=>e.split(/[-.]/).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(""),Yc=e=>{let n={string:"z.string()",number:"z.number()",boolean:"z.boolean()",date:"z.string().datetime()",datetime:"z.string().datetime()",array:"z.array(z.unknown())",object:"z.record(z.unknown())","string?":"z.string().optional()","number?":"z.number().optional()","boolean?":"z.boolean().optional()","date?":"z.string().datetime().optional()","datetime?":"z.string().datetime().optional()"}[e.toLowerCase()];return n||(console.warn(`Unknown field type "${e}", using z.string()`),"z.string()")},Xc=e=>!e||Object.keys(e).length===0?` id: z.string(),
|
|
21
|
+
createdAt: z.string(),`:Object.entries(e).map(([t,n])=>` ${t}: ${Yc(n)},`).join(`
|
|
22
|
+
`),U=e=>{let t=gs(e),n=us(e),r=e.split(".")[0],o=e.split(".").slice(1).join("-"),s=(0,Jt.pluralize)(r).toUpperCase(),a=(0,Jt.pluralize)(r).toLowerCase(),i=us(`${(0,Jt.pluralize)(r)}.${o}`);return{eventName:t,contractName:`${i}Contract`,schemaName:`${n}Schema`,typeName:`${n}Data`,streamName:s,domain:a,event:o}},zt=e=>{let t=ut(e);if((0,M.existsSync)(t))return!0;let{eventsPath:n}=x(),r=gs(e),o=(0,Se.join)(n,`${r}.ts`);if((0,M.existsSync)(o))return!0;let s=e.split(".")[0],a=e.split(".").slice(1).join("-"),i=(0,Se.join)(n,s,`${a}.ts`);return(0,M.existsSync)(i)},er=(e,t)=>{let{eventsPath:n}=x(),{contractName:r,schemaName:o,typeName:s,streamName:a,domain:i,event:c}=U(e),l=`import { createContract } from '@crossdelta/cloudevents'
|
|
6
23
|
import { z } from 'zod'
|
|
7
24
|
|
|
8
25
|
export const ${o} = z.object({
|
|
9
|
-
${
|
|
26
|
+
${Xc(t)}
|
|
10
27
|
})
|
|
11
28
|
|
|
12
29
|
export const ${r} = createContract({
|
|
@@ -16,24 +33,24 @@ export const ${r} = createContract({
|
|
|
16
33
|
})
|
|
17
34
|
|
|
18
35
|
export type ${s} = z.infer<typeof ${r}.schema>
|
|
19
|
-
`,p=(0,Se.join)(n,i),d=(0,Se.join)(p,`${c}.ts`);return(0,
|
|
36
|
+
`,p=(0,Se.join)(n,i),d=(0,Se.join)(p,`${c}.ts`);return(0,M.existsSync)(p)||(0,M.mkdirSync)(p,{recursive:!0}),(0,M.writeFileSync)(d,l,"utf-8"),d},ut=e=>{let{eventsPath:t}=x(),{domain:n,event:r}=U(e);return(0,Se.join)(t,n,`${r}.ts`)},tr=e=>{let t=ut(e);if(!(0,M.existsSync)(t))return null;let n=(0,M.readFileSync)(t,"utf-8"),r=n.match(/export const \w+Schema\s*=\s*z\.object\(\s*\{([\s\S]*?)\}\s*\)/m);if(r)return r[1];let o=n.match(/schema:\s*z\.object\(\s*\{([\s\S]*?)\}\s*\)/m);return o?o[1]:null},nr=()=>{let{packagePath:e}=x(),t=(0,Se.join)(e,"package.json");if(!(0,M.existsSync)(t))return"@my-platform";try{return JSON.parse((0,M.readFileSync)(t,"utf-8")).name?.split("/")[0]??"@my-platform"}catch{return"@my-platform"}};var qt=require("node:fs"),sr=require("node:path"),hs=require("@crossdelta/cloudevents");var A=require("node:fs"),Me=require("node:path");var Kt=e=>{let{streamName:t}=U(e);return t},fs=(e,t)=>{let n=(0,Me.join)(e,"src","index.ts");if(!(0,A.existsSync)(n))return!1;let r=(0,A.readFileSync)(n,"utf-8"),o=t.toLowerCase();return new RegExp(`streams:\\s*\\[[^\\]]*['"]${t}['"]`).test(r)||r.includes(`stream: '${t}'`)?!0:new RegExp(`subjects:\\s*\\[.*['"]${o}\\.[*>]`).test(r)},Qc=e=>{if(e.includes("@crossdelta/cloudevents"))return e;let t=`import { consumeJetStreams } from '@crossdelta/cloudevents'
|
|
20
37
|
`,n=e.match(/import\s+['"]@crossdelta\/telemetry['"]\s*\n/);if(n){let o=(n.index??0)+n[0].length;return`${e.slice(0,o)}
|
|
21
|
-
${t}${e.slice(o)}`}let r=e.match(/import\s+.*\n/);if(r){let o=(r.index??0)+r[0].length;return e.slice(0,o)+t+e.slice(o)}return e},
|
|
38
|
+
${t}${e.slice(o)}`}let r=e.match(/import\s+.*\n/);if(r){let o=(r.index??0)+r[0].length;return e.slice(0,o)+t+e.slice(o)}return e},el=(e,t,n)=>`
|
|
22
39
|
|
|
23
40
|
// Consume from ${e} stream
|
|
24
41
|
consumeJetStreams({
|
|
25
42
|
streams: ['${e}'],
|
|
26
43
|
consumer: '${n}-service',
|
|
27
44
|
discover: './src/events/**/*.handler.ts',
|
|
28
|
-
})`,
|
|
29
|
-
`;return(0,
|
|
45
|
+
})`,rr=(e,t)=>{let n=Kt(t),r=t.split(".")[0],o=(0,Me.join)(e,"src","index.ts"),s=(0,Me.join)(e,"src","main.ts");if(!(0,A.existsSync)(o)&&(0,A.existsSync)(s))return{added:!1,streamName:n};if(!(0,A.existsSync)(o))return{added:!1,streamName:n,warning:"Entry point not found (index.ts or main.ts)"};if(fs(e,n))return{added:!1,streamName:n};let a=(0,A.readFileSync)(o,"utf-8"),i=e.split("/").pop()||"unknown";a.includes("consumeJetStreams")||(a=Qc(a));let c=el(n,r,i),l=`${a.trimEnd()+c}
|
|
46
|
+
`;return(0,A.writeFileSync)(o,l,"utf-8"),{added:!0,streamName:n}},or=(e,t)=>{let{eventName:n,contractName:r,typeName:o}=U(e),s=nr(),a=(0,Me.join)(t,"src","events"),i=(0,Me.join)(a,`${n}.handler.ts`);if((0,A.existsSync)(i))return null;let c=`import { handleEvent } from '@crossdelta/cloudevents'
|
|
30
47
|
import { ${r}, type ${o} } from '${s}/contracts'
|
|
31
48
|
|
|
32
49
|
export default handleEvent(${r}, async (data: ${o}) => {
|
|
33
50
|
// TODO: Implement event handling logic
|
|
34
51
|
console.log('Received ${e}:', data)
|
|
35
52
|
})
|
|
36
|
-
`;return(0,
|
|
53
|
+
`;return(0,A.existsSync)(a)||(0,A.mkdirSync)(a,{recursive:!0}),(0,A.writeFileSync)(i,c,"utf-8"),i};var ys=e=>{try{return(0,qt.readdirSync)(e,{withFileTypes:!0}).flatMap(n=>{let r=(0,sr.join)(e,n.name);return n.isDirectory()?ys(r):n.name.endsWith(".handler.ts")?[r]:[]})}catch{return[]}},ar=e=>{let t=(0,sr.join)(e,"src","events");return ys(t).flatMap(r=>{let o=(0,qt.readFileSync)(r,"utf-8");return tl(r,o)})},tl=(e,t)=>{let n=nl(t);if(!n)return[];let s=(n.replace(/Contract$/,"").match(/[A-Z][a-z]*/g)??[]).map(a=>a.toLowerCase()).join(".");return[{filePath:e,eventType:s,contractName:n}]},nl=e=>{let n=/import\s+{([^}]+)}\s+from\s+['"]@[\w-]+\/contracts['"]/.exec(e);return n?n[1].split(",").map(s=>s.trim()).filter(s=>s.endsWith("Contract")).map(s=>s.replace(/\s+as\s+.+$/,"").trim()).at(0)??null:null},ir=e=>{let t=e.reduce((n,r)=>{let o=r.eventType.split(".")[0],s=n.get(o)??[];return n.set(o,[...s,r]),n},new Map);return Array.from(t.entries()).map(([n,r])=>rl(n,r)).sort((n,r)=>n.stream.localeCompare(r.stream))},rl=(e,t)=>{let n=Kt(t[0]?.eventType??`${e}.event`),o=`${(0,hs.pluralize)(e)}.>`;return{stream:n,subjects:[o],handlers:t}},cr=(e,t)=>e.length===0?"":` // Services NEVER create streams!
|
|
37
54
|
// - Development: pf dev auto-creates ephemeral streams from contracts
|
|
38
55
|
// - Production: Pulumi materializes persistent streams
|
|
39
56
|
|
|
@@ -41,33 +58,32 @@ export default handleEvent(${r}, async (data: ${o}) => {
|
|
|
41
58
|
streams: [${e.map(n=>`'${n.stream}'`).join(", ")}],
|
|
42
59
|
consumer: '${t}',
|
|
43
60
|
discover: './src/events/**/*.handler.ts',
|
|
44
|
-
})`;var
|
|
45
|
-
* ${(0,
|
|
61
|
+
})`;var w=require("node:fs"),Y=require("node:path");v();var ol=(e,t)=>{let n=`export * from './${t}'`;if(!(0,w.existsSync)(e)){let s=(0,Y.dirname)(e);(0,w.existsSync)(s)||(0,w.mkdirSync)(s,{recursive:!0});let a=`/**
|
|
62
|
+
* ${(0,Y.dirname)(e).split("/").pop()} Domain Events
|
|
46
63
|
*/
|
|
47
64
|
|
|
48
|
-
`;return(0,
|
|
49
|
-
`,"utf-8"),!0}let r=(0,
|
|
65
|
+
`;return(0,w.writeFileSync)(e,a+n+`
|
|
66
|
+
`,"utf-8"),!0}let r=(0,w.readFileSync)(e,"utf-8");if(r.includes(`'./${t}'`))return!1;let o=r.trimEnd()+`
|
|
50
67
|
`+n+`
|
|
51
|
-
`;return(0,
|
|
68
|
+
`;return(0,w.writeFileSync)(e,o,"utf-8"),!0},sl=(e,t)=>{let n=`export * from './${t}'`;if(!(0,w.existsSync)(e))return(0,w.writeFileSync)(e,`/**
|
|
52
69
|
* Event Contracts Index
|
|
53
70
|
*
|
|
54
71
|
* Re-exports all event contracts for convenient importing.
|
|
55
72
|
*/
|
|
56
73
|
|
|
57
74
|
`+n+`
|
|
58
|
-
`,"utf-8"),!0;let o=(0,
|
|
59
|
-
`);if(o.some(a=>a.trim()===n))return!1;let s=o.findLastIndex(a=>a.startsWith("export"));return s>=0?o.splice(s+1,0,n):o.push(n),(0,
|
|
60
|
-
`),"utf-8"),!0},
|
|
61
|
-
|
|
62
|
-
`),
|
|
75
|
+
`,"utf-8"),!0;let o=(0,w.readFileSync)(e,"utf-8").split(`
|
|
76
|
+
`);if(o.some(a=>a.trim()===n))return!1;let s=o.findLastIndex(a=>a.startsWith("export"));return s>=0?o.splice(s+1,0,n):o.push(n),(0,w.writeFileSync)(e,o.join(`
|
|
77
|
+
`),"utf-8"),!0},al=e=>{if(!(0,w.existsSync)(e))return!1;let t=(0,w.readFileSync)(e,"utf-8"),n="export * from './events'";if(t.includes(n))return!1;let r=t;return r=r.replace(/\/\/\s*export \* from '\.\/events'/,n),r=r.replace(/\/\/\s*export \* from '\.\/stream-policies'/,"export * from './stream-policies'"),/export \* from '\.\/events\/\w+\/\w+'/.test(r)&&(r=r.replace(/export \* from '\.\/events\/\w+\/\w+'\n?/g,"")),r.includes(n)||(r=r.trimEnd()+`
|
|
78
|
+
${n}
|
|
79
|
+
`),r!==t?((0,w.writeFileSync)(e,r,"utf-8"),!0):!1},lr=e=>{let{packagePath:t}=x(),{domain:n,event:r}=U(e),o=(0,Y.join)(t,"src","events"),s=(0,Y.join)(o,n),a=(0,Y.join)(s,"index.ts"),i=(0,Y.join)(o,"index.ts"),c=(0,Y.join)(t,"src","index.ts"),l=e.split(".")[0],p=(0,Y.join)(o,l);l!==n&&(0,w.existsSync)(p)&&(console.warn(`\u26A0\uFE0F Warning: Legacy folder '${l}/' found. Please migrate to '${n}/' to avoid conflicts.`),console.warn(` Run: mv ${p} ${s}`));let d=!1;return ol(a,r)&&(d=!0),sl(i,n)&&(d=!0),al(c)&&(d=!0),d},pr=(e,t)=>{if(!(0,w.existsSync)(e))return!1;let n=`export * from './events/${t}'`,r=(0,w.readFileSync)(e,"utf-8");if(r.includes(`'./events/${t}'`))return!1;let o=r.split(`
|
|
80
|
+
`),s=o.findLastIndex(a=>a.startsWith("export"));return s>=0?o.splice(s+1,0,n):o.push("",n),(0,w.writeFileSync)(e,o.join(`
|
|
81
|
+
`),"utf-8"),!0};var P=require("node:fs"),X=require("node:path"),h=require("@faker-js/faker");v();var ks=[{pattern:"email",generate:()=>h.faker.internet.email(),hint:"email"},{pattern:"id",generate:()=>h.faker.string.uuid(),hint:"uuid"},{pattern:"firstname",generate:()=>h.faker.person.firstName(),hint:"firstName"},{pattern:"lastname",generate:()=>h.faker.person.lastName(),hint:"lastName"},{pattern:"name",generate:()=>h.faker.person.fullName(),hint:"fullName"},{pattern:"phone",generate:()=>h.faker.phone.number(),hint:"phoneNumber"},{pattern:"address",generate:()=>h.faker.location.streetAddress(),hint:"streetAddress"},{pattern:"street",generate:()=>h.faker.location.streetAddress(),hint:"streetAddress"},{pattern:"city",generate:()=>h.faker.location.city(),hint:"city"},{pattern:"country",generate:()=>h.faker.location.country(),hint:"country"},{pattern:"price",generate:()=>h.faker.number.float({min:10,max:1e3,fractionDigits:2}),hint:"price"},{pattern:"amount",generate:()=>h.faker.number.float({min:10,max:1e3,fractionDigits:2}),hint:"price"},{pattern:"total",generate:()=>h.faker.number.float({min:10,max:1e3,fractionDigits:2}),hint:"price"},{pattern:"quantity",generate:()=>h.faker.number.int({min:1,max:10}),hint:"quantity"},{pattern:"date",generate:()=>h.faker.date.recent().toISOString(),hint:"date"},{pattern:"createdat",generate:()=>h.faker.date.recent().toISOString(),hint:"date"},{pattern:"updatedat",generate:()=>h.faker.date.recent().toISOString(),hint:"date"}],vs=e=>({email:()=>h.faker.internet.email(),datetime:()=>h.faker.date.recent().toISOString(),url:()=>h.faker.internet.url(),uuid:()=>h.faker.string.uuid(),date:()=>h.faker.date.recent().toISOString().split("T")[0],time:()=>h.faker.date.recent().toISOString().split("T")[1]?.split(".")[0]})[e]?.()??h.faker.lorem.word(),Cs=e=>{let t=e.toLowerCase(),n=ks.find(r=>t.includes(r.pattern));return n?{value:n.generate(),hint:n.hint}:null},il=(e,t)=>{if(e.format)return vs(e.format);let n=Cs(t);if(n)return n.value;switch(e.type){case"string":return h.faker.lorem.word();case"number":return h.faker.number.int({min:1,max:100});case"boolean":return h.faker.datatype.boolean();case"array":return e.element?[mr(e.element)]:[];case"object":return mr(e);default:return null}},mr=e=>{let t={},n=e.shape??(typeof e.def?.shape=="function"?e.def.shape():void 0);if(!n)return t;for(let[r,o]of Object.entries(n))t[r]=il(o,r);return t},cl=async e=>{try{let{createJiti:t}=await import("jiti"),r=t(process.cwd(),{interopDefault:!0})(e),o=Object.entries(r).find(([s])=>s.endsWith("Schema")||s==="schema");if(o?.[1]){let s=o[1],a=mr(s);if(a&&typeof a=="object"&&Object.keys(a).length>0){let i={};return dr(a,i,""),{data:a,faker:i}}}}catch{}return null},dr=(e,t,n)=>{if(!(!e||typeof e!="object"))for(let[r,o]of Object.entries(e)){let s=n?`${n}.${r}`:r,a=r.toLowerCase(),i=ks.find(c=>a.includes(c.pattern));i&&(i.hint!=="uuid"||typeof o=="string")&&(t[s]=i.hint),typeof o=="object"&&o!==null&&!Array.isArray(o)?dr(o,t,s):Array.isArray(o)&&o.length>0&&typeof o[0]=="object"&&dr(o[0],t,`${s}[0]`)}},ll=e=>({string:()=>h.faker.lorem.word(),number:()=>h.faker.number.int({min:1,max:100}),boolean:()=>h.faker.datatype.boolean()})[e]?.(),pl=(e,t,n)=>{let r=/(\w+):\s*z\.(\w+)\(/g,o=Array.from(e.matchAll(r));for(let[,s,a]of o){if(a==="array"||a==="object")continue;let i=Cs(s);if(i)t[s]=i.value,i.hint&&(n[s]=i.hint);else{let c=ll(a);c!==void 0&&(t[s]=c)}}},ml=(e,t,n)=>{let r=/(\w+):\s*z\.string\(\)\.(datetime|email|url|uuid)\(\)/g,o=Array.from(e.matchAll(r));for(let[,s,a]of o)t[s]=vs(a),n[s]=a==="datetime"?"date":a},xs=e=>{let t={},n={};return pl(e,t,n),ml(e,t,n),{data:t,faker:n}},Vt=async e=>{let{eventsPath:t}=x(),n=ut(e);if(!(0,P.existsSync)(n))return null;let o=(0,P.readFileSync)(n,"utf-8").match(/type:\s*['"]([^'"]+)['"]/),s=o?o[1]:e,a=await cl(n);if(!a){let C=tr(e);C&&(a=xs(C))}if(!a)return null;let i={eventName:s,description:`Mock data for ${s} event`,data:a.data};Object.keys(a.faker).length>0&&(i.faker=a.faker);let{domain:c,event:l}=U(e),p=(0,X.join)(t,c,`${l}.mock.json`),d=(0,X.join)(t,c);return(0,P.existsSync)(d)||(0,P.mkdirSync)(d,{recursive:!0}),(0,P.writeFileSync)(p,JSON.stringify(i,null,2),"utf-8"),p};var ws=e=>{let t=e.match(/import\s+\{[^}]*?(\w+Contract)[^}]*?\}\s+from\s+['"][^'"]+\/contracts['"]/);return t?t[1].replace("Contract","").replace(/([A-Z])/g,(r,o,s)=>(s>0?".":"")+o.toLowerCase()):null},dl=(e,t,n)=>{if(!(0,P.existsSync)(e))return!1;let r=(0,P.readFileSync)(e,"utf-8"),o=r.match(/export const \w+(?:Schema|Data)\s*=\s*z\.object\(\s*\{([\s\S]*?)\}\s*\)/m)??r.match(/schema:\s*z\.object\(\s*\{([\s\S]*?)\}\s*\)/m);if(!o)return!1;let s=xs(o[1]),a={eventName:n,description:`Mock data for ${n} event`,data:s.data};return Object.keys(s.faker).length>0&&(a.faker=s.faker),(0,P.writeFileSync)(t,JSON.stringify(a,null,2)),!0},ur=async(e,t={})=>{let n=(0,X.join)(e,"src","events");if(!(0,P.existsSync)(n))return{mockPaths:[],skippedHandlers:[]};let r=(0,P.readdirSync)(n).filter(a=>a.endsWith(".event.ts")).map(a=>(0,X.join)(n,a)),o=[],s=[];for(let a of r){let i=(0,P.readFileSync)(a,"utf-8"),c=ws(i);if(!c){s.push(`${(0,X.basename)(a)} (Handler does not use contracts)`);continue}let{eventName:l}=U(c),p=t.outputDir??x().eventsPath,d=(0,X.join)(p,`${l}.mock.json`);if((0,P.existsSync)(d)&&!t.overwrite){s.push(`${(0,X.basename)(a)} (Mock already exists)`);continue}if(t.outputDir){let L=(0,X.join)(t.outputDir,`${l}.ts`);dl(L,d,c)&&o.push(d);continue}let C=await Vt(c);C&&o.push(C)}return{mockPaths:o,skippedHandlers:s}};var Ps=e=>{let t=e.split("/").pop()||"service",n=(0,bs.join)(e,"src","events","events.service.ts");if(!(0,Zt.existsSync)(n))return!1;let r=ar(e);if(r.length===0||(0,Zt.readFileSync)(n,"utf-8").replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"").includes("consumeJetStreams"))return!1;let i=ir(r),c=cr(i,t);if(!c)return!1;let l=new Ss.Project({skipAddingFilesFromTsConfig:!0,skipFileDependencyResolution:!0}),p=l.addSourceFileAtPath(n),d=!1;for(let C of p.getClasses()){let L=C.getMethod("startConsumers");if(!L)continue;let H=[...c.split(`
|
|
63
82
|
`),""," this.logger.log('Event consumers started successfully')"].join(`
|
|
64
|
-
`);
|
|
65
|
-
`)
|
|
66
|
-
|
|
67
|
-
`)
|
|
68
|
-
`));for(let n of e)console.log(q.default.dim(` ${t}/contracts \u2192 ${n}`));console.log()}},_c=(e,t)=>{let n=/^packages\/contracts\/src\/events\/([^/]+)\.ts$/,r=(0,_t.join)(t,"packages/contracts/src/index.ts");for(let o of e){let s=o.match(n);s&&s[1]!=="index"&&Ln(r,s[1])}},Oo=async(e,t)=>{t.start("Applying code formatting...");try{await te("biome",["check","--fix","--unsafe","."],{cwd:e,quiet:!0}),t.succeed("Code formatted!")}catch{t.warn("Code formatting completed with warnings")}},Dc=async(e,t)=>{t.start("Scanning for event handlers...");let{mockPaths:n,skippedHandlers:r}=await Wn(e);if(n.length+r.length===0){t.info("No event handlers found");return}if(n.length>0){t.succeed(`Generated ${n.length} event ${n.length===1?"mock":"mocks"}`),console.log();for(let s of n){let a=s.replace(`${e}/`,"");console.log(q.default.dim(` ${a}`))}console.log()}else t.succeed("Event handlers found");if(r.length>0){for(let s of r)console.log(q.default.dim(` \u2139 Skipped: ${s}`));console.log()}},_o=async(e,t,n,r)=>{r.start("Writing generated files...");let o=Fo(e,{baseDir:t,workspaceRoot:n.workspaceRoot,overwrite:!0});if(o.written.length>0){r.succeed(`Created ${o.written.length} files`),console.log();for(let l of o.written)console.log(q.default.dim(` ${l}`));console.log()}else r.succeed("No files to write");let s=Rc(e,n),{existing:a,missing:i,suggestedCommands:c}=Fc(s,n.workspaceRoot,t);if(a.length>0&&Oc(a,n.scope),i.length>0){console.log(q.default.yellow(`\u26A0\uFE0F Missing contracts (not exported from @${n.scope}/contracts):
|
|
69
|
-
`));for(let l of i)console.log(q.default.yellow(` ${l}`));console.log(),console.log(q.default.cyan(`\u{1F4A1} Run these commands to create the missing contracts:
|
|
70
|
-
`));for(let l of c)console.log(q.default.dim(` ${l}`));console.log()}return _c(o.written,n.workspaceRoot),o.written.length>0&&await Dc(t,r),{missingContractCommands:c}};var Dt=require("node:fs"),$e=require("node:path");var Te=require("node:fs"),Do=require("node:path");var Lo=e=>{let{eventsPath:t}=C(e);if(!(0,Te.existsSync)(t))return[];let n=[];try{let r=(0,Te.readdirSync)(t).filter(o=>o.endsWith(".ts")&&!o.endsWith(".mock.json")&&o!=="index.ts");for(let o of r){let s=(0,Do.join)(t,o),a=(0,Te.readFileSync)(s,"utf-8"),i=Lc(a,s);i&&n.push(i)}}catch(r){return console.warn("Warning: Could not scan contracts package:",r),[]}return n},Lc=(e,t)=>{try{let n=e.match(/export const (\w+Contract) = createContract/);if(!n)return null;let r=n[1],o=e.match(/export type (\w+(?:Data|Event)) = z\.infer/);if(!o)return null;let s=o[1],a=e.match(/type:\s*['"]([^'"]+)['"]/);if(!a)return null;let i=a[1],c=Bc(e);return{name:r,typeName:s,eventType:i,fields:c,filePath:t}}catch{return null}},Hc={string:"string",number:"number",boolean:"boolean",array:"array",object:"object",date:"date"},Bc=e=>{let t=e.match(/z\.object\({([^}]+)\}/);if(!t)return[];let n=t[1],r=/(\w+):\s*z\.(\w+)\([^)]*\)/g,o=[...n.matchAll(r)].map(([,i,c])=>{let l=Hc[c]||c;return`${i}: ${l}`});if(!e.includes("z.array("))return o;let s=/(\w+):\s*z\.array\(/g,a=[...e.matchAll(s)].map(([,i])=>i).filter(i=>!o.some(c=>c.startsWith(i))).map(i=>`${i}: array`);return[...o,...a]},Ho=(e,t)=>{if(e.length===0)return`
|
|
83
|
+
`);L.setBodyText(H),d=!0;break}return d&&l.saveSync(),d};v();var ul=e=>{let t=e.split(/\s+/),n=t[0],r=t.slice(1);return n==="pf"&&(n=process.argv[1]),{executable:n,args:r}},gl=async(e,t)=>{try{let{executable:n,args:r}=ul(e.command);return await de(n,r,{cwd:t,shell:!1}),{command:e.command,success:!0}}catch(n){return{command:e.command,success:!1,error:n instanceof Error?n.message:String(n)}}},gr=async(e,t)=>{let n=[];for(let r of e){let o=await gl(r,t);if(n.push(o),!o.success)break}return n},fr=e=>{let t=[/^pf\s+/,/^bun\s+pf\s+/,/^npx\s+pf\s+/,/^bunx\s+pf\s+/];return e.filter(n=>t.some(r=>r.test(n.command)))},Ts=e=>{for(let t of e){let n=t.command.match(/(?:bun\s+)?pf\s+new\s+\S+\s+(\S+)/);if(n)return n[1]}return null};var gt=require("node:fs"),Xt=require("node:path"),Q=u(require("chalk"));v();var Pe=require("node:fs"),Yt=require("node:path"),fl=(e,t)=>{let r=e.path.startsWith("packages/")&&t.workspaceRoot?t.workspaceRoot:t.baseDir,o=(0,Yt.join)(r,e.path);try{if((0,Pe.existsSync)(o)&&!t.overwrite)return{status:"skipped",path:e.path};if(t.dryRun)return{status:"written",path:e.path};let s=(0,Yt.dirname)(o);return(0,Pe.existsSync)(s)||(0,Pe.mkdirSync)(s,{recursive:!0}),(0,Pe.writeFileSync)(o,e.content,"utf-8"),{status:"written",path:e.path}}catch(s){return{status:"failed",path:e.path,error:s.message}}},Es=(e,t)=>{let n=e.map(r=>fl(r,t));return{written:n.filter(r=>r.status==="written").map(r=>r.path),skipped:n.filter(r=>r.status==="skipped").map(r=>r.path),failed:n.filter(r=>r.status==="failed").map(r=>({path:r.path,error:r.error}))}};var hl=(e,t)=>{let n=E(t.workspaceRoot),r=(0,Xt.join)(t.workspaceRoot,n.contracts);if(!(0,gt.existsSync)(r))return[];let o=/import\s+(?:type\s+)?{([^}]+)}\s+from\s+['"]@\w+\/contracts['"]/g,s=new Set;for(let a of e){let i=a.content.matchAll(o);for(let c of i){let p=c[1].split(",").map(d=>d.trim()).map(d=>d.replace(/^type\s+/,"").replace(/\s+as\s+.+$/,"").trim()).filter(d=>d.endsWith("Contract"));for(let d of p)s.add(d)}}return Array.from(s).sort()},yl=e=>{let t=(0,Xt.join)(e,"packages/contracts/src/index.ts");if(!(0,gt.existsSync)(t))return new Set;try{let n=(0,gt.readFileSync)(t,"utf-8"),r=new Set,o=/export\s+(?:\*|{[^}]*Contract[^}]*})\s+from\s+['"]\.\/events\/([^'"]+)['"]/g,s=n.matchAll(o);for(let a of s){let i=a[0],c=/(\w+Contract)/g,l=i.matchAll(c);for(let p of l)r.add(p[1])}return r}catch{return new Set}},kl=e=>{let t=e.replace(/Contract$/,""),n=t.split(/(?=[A-Z])/).filter(Boolean);if(n.length<2)return t.toLowerCase();let r=n[0].toLowerCase(),o=n.slice(1).join("").toLowerCase();return`${r}.${o}`},vl=(e,t,n)=>{let r=yl(t),o=[],s=[],a=[];for(let i of e)if(r.has(i))o.push(i);else{s.push(i);let c=kl(i),l=n.replace(`${t}/`,"");a.push(`pf event add ${c} --service ${l}`)}return{existing:o,missing:s,suggestedCommands:a}},Cl=(e,t)=>{if(e.length!==0){console.log(Q.default.cyan(`\u{1F4E6} Using existing contracts:
|
|
84
|
+
`));for(let n of e)console.log(Q.default.dim(` ${t}/contracts \u2192 ${n}`));console.log()}},xl=(e,t)=>{let n=/^packages\/contracts\/src\/events\/([^/]+)\.ts$/,r=(0,Xt.join)(t,"packages/contracts/src/index.ts");for(let o of e){let s=o.match(n);s&&s[1]!=="index"&&pr(r,s[1])}},$s=async(e,t)=>{t.start("Applying code formatting...");try{await se("biome",["check","--fix","--unsafe","."],{cwd:e,quiet:!0}),t.succeed("Code formatted!")}catch{t.warn("Code formatting completed with warnings")}},wl=async(e,t)=>{t.start("Scanning for event handlers...");let{mockPaths:n,skippedHandlers:r}=await ur(e);if(n.length+r.length===0){t.info("No event handlers found");return}if(n.length>0){t.succeed(`Generated ${n.length} event ${n.length===1?"mock":"mocks"}`),console.log();for(let s of n){let a=s.replace(`${e}/`,"");console.log(Q.default.dim(` ${a}`))}console.log()}else t.succeed("Event handlers found");if(r.length>0){for(let s of r)console.log(Q.default.dim(` \u2139 Skipped: ${s}`));console.log()}},As=async(e,t,n,r)=>{r.start("Writing generated files...");let o=Es(e,{baseDir:t,workspaceRoot:n.workspaceRoot,overwrite:!0});if(o.written.length>0){r.succeed(`Created ${o.written.length} files`),console.log();for(let l of o.written)console.log(Q.default.dim(` ${l}`));console.log()}else r.succeed("No files to write");let s=hl(e,n),{existing:a,missing:i,suggestedCommands:c}=vl(s,n.workspaceRoot,t);if(a.length>0&&Cl(a,n.scope),i.length>0){console.log(Q.default.yellow(`\u26A0\uFE0F Missing contracts (not exported from @${n.scope}/contracts):
|
|
85
|
+
`));for(let l of i)console.log(Q.default.yellow(` ${l}`));console.log(),console.log(Q.default.cyan(`\u{1F4A1} Run these commands to create the missing contracts:
|
|
86
|
+
`));for(let l of c)console.log(Q.default.dim(` ${l}`));console.log()}return xl(o.written,n.workspaceRoot),o.written.length>0&&await wl(t,r),{missingContractCommands:c}};v();var Qt=require("node:fs"),Fe=require("node:path");v();var je=require("node:fs"),Is=require("node:path");v();var Ns=e=>{let{eventsPath:t}=x(e);if(!(0,je.existsSync)(t))return[];let n=[];try{let r=(0,je.readdirSync)(t).filter(o=>o.endsWith(".ts")&&!o.endsWith(".mock.json")&&o!=="index.ts");for(let o of r){let s=(0,Is.join)(t,o),a=(0,je.readFileSync)(s,"utf-8"),i=bl(a,s);i&&n.push(i)}}catch(r){return console.warn("Warning: Could not scan contracts package:",r),[]}return n},bl=(e,t)=>{try{let n=e.match(/export const (\w+Contract) = createContract/);if(!n)return null;let r=n[1],o=e.match(/export type (\w+(?:Data|Event)) = z\.infer/);if(!o)return null;let s=o[1],a=e.match(/type:\s*['"]([^'"]+)['"]/);if(!a)return null;let i=a[1],c=Pl(e);return{name:r,typeName:s,eventType:i,fields:c,filePath:t}}catch{return null}},Sl={string:"string",number:"number",boolean:"boolean",array:"array",object:"object",date:"date"},Pl=e=>{let t=e.match(/z\.object\({([^}]+)\}/);if(!t)return[];let n=t[1],r=/(\w+):\s*z\.(\w+)\([^)]*\)/g,o=[...n.matchAll(r)].map(([,i,c])=>{let l=Sl[c]||c;return`${i}: ${l}`});if(!e.includes("z.array("))return o;let s=/(\w+):\s*z\.array\(/g,a=[...e.matchAll(s)].map(([,i])=>i).filter(i=>!o.some(c=>c.startsWith(i))).map(i=>`${i}: array`);return[...o,...a]},Rs=(e,t)=>{if(e.length===0)return`
|
|
71
87
|
**Available Contracts:**
|
|
72
88
|
|
|
73
89
|
No contracts are currently defined. Use Basic Mode with inline schemas for all events.
|
|
@@ -88,15 +104,15 @@ The following event contracts are available in \`${t}/contracts\`:
|
|
|
88
104
|
${n}
|
|
89
105
|
|
|
90
106
|
If the event type your service consumes matches one of these, **you MUST use Advanced Mode**.
|
|
91
|
-
`.trim()};var
|
|
107
|
+
`.trim()};var Tl=(e,t)=>{let n=(0,Fe.join)(__dirname,"docs","generators"),r=Ae(),o=[];for(let s of r.docs.base)o.push((0,Fe.join)(n,s));if(e&&r.docs.frameworks[e]){let s=r.docs.frameworks[e];if(typeof s=="string")o.push((0,Fe.join)(n,s));else{let a=t==="bun"?"bun":"node";s[a]&&o.push((0,Fe.join)(n,s[a]))}}return o},Ms={copilot:".github/copilot-instructions.md",projectGuidelines:"docs/ai-guidelines.md"},El=1500,js=e=>{try{return(0,Qt.existsSync)(e)?(0,Qt.readFileSync)(e,"utf-8"):null}catch{return null}},$l=e=>e.replace(/<!--[\s\S]*?-->/g,"").replace(/^\[.+\]:\s*.+$/gm,"").replace(/\n{3,}/g,`
|
|
92
108
|
|
|
93
|
-
`).replace(/[ \t]+$/gm,"").trim(),
|
|
109
|
+
`).replace(/[ \t]+$/gm,"").trim(),Al=e=>e.replace(/<!--[\s\S]*?-->/g,"").replace(/^\[.+\]:\s*.+$/gm,"").replace(/```[\s\S]*?```/g,"").replace(/`[^`]{50,}`/g,"`...`").replace(/\n{3,}/g,`
|
|
94
110
|
|
|
95
|
-
`).replace(/[ \t]+$/gm,"").trim(),
|
|
111
|
+
`).replace(/[ \t]+$/gm,"").trim(),Il=e=>Math.ceil(e.length/4),Nl=(e,t)=>{let n=e.split(/(?=^## )/m),r="",o=0;for(let s of n){let a=Il(s);if(o+a<=t)r+=s,o+=a;else if(o===0){r=s.slice(0,t*4);break}else break}return r.trim()},Rl=(e,t)=>{let{workspaceRoot:n,scope:r}=t,o=Ns(n),s=Rs(o,r);return e.replace(/\{\{scope\}\}/g,r).replace(/\{\{AVAILABLE_CONTRACTS\}\}/g,s)},Fs=e=>{let{workspaceRoot:t,scope:n}=e,r=[],o=Tl(e.serviceType,e.packageManager);for(let i of o){let c=js(i);if(c){let l=Rl(c,e),p=$l(l);r.push(p)}}let s=[Ms.copilot,Ms.projectGuidelines],a=Math.floor(El/s.length);for(let i of s){let c=js((0,Fe.join)(t,i));if(c){let l=Al(c),p=Nl(l,a);p.length>50&&r.push(p)}}return r.length===0?(console.warn("\u26A0\uFE0F No instruction files found."),`Use ${n}/contracts for shared types.`):r.join(`
|
|
96
112
|
|
|
97
113
|
---
|
|
98
114
|
|
|
99
|
-
`)};var
|
|
115
|
+
`)};var Ml=`You are an expert code generator. Generate clean, production-ready code.
|
|
100
116
|
|
|
101
117
|
## Output Format
|
|
102
118
|
|
|
@@ -110,13 +126,13 @@ Format your code blocks with the file path on the line before the code block:
|
|
|
110
126
|
**IMPORTANT:** Always generate:
|
|
111
127
|
- Source code files (src/**)
|
|
112
128
|
- Test files (src/**/*.test.ts) for all business logic
|
|
113
|
-
- README.md with service documentation`,
|
|
129
|
+
- README.md with service documentation`,jl=e=>e.replace(/-/g,"_").toUpperCase(),Fl=e=>e.split("/").pop()||"my-service",Os=(e,t,n)=>{let r=Fs({...e,serviceType:t,packageManager:n});return`${Ml}
|
|
114
130
|
|
|
115
131
|
## Project Guidelines & Patterns
|
|
116
132
|
|
|
117
133
|
Follow these project-specific conventions and patterns when generating code:
|
|
118
134
|
|
|
119
|
-
${r}`},
|
|
135
|
+
${r}`},_s=(e,t,n,r)=>{let o=Fl(e),s=`${jl(o)}_PORT`,a=xe();return`Generate source code for a microservice at path "${e}".
|
|
120
136
|
|
|
121
137
|
Use the patterns and conventions from the Project Guidelines above.
|
|
122
138
|
|
|
@@ -131,60 +147,60 @@ Service purpose: ${t}
|
|
|
131
147
|
- BUT you MUST keep the existing port configuration line unchanged!
|
|
132
148
|
|
|
133
149
|
Do NOT include the service path in file headers (use \`src/...\`, NOT \`${e}/src/...\`).
|
|
134
|
-
`};var
|
|
135
|
-
`).map(o=>o.trim()).filter(o=>o.length>0&&!o.startsWith("#"))),
|
|
136
|
-
`),n=[],r=0;for(let o of t){let s=
|
|
137
|
-
`));return}let o=(await
|
|
138
|
-
\u2717 Scaffolding failed: ${o.command}`)),o.error&&console.log(
|
|
150
|
+
`};var Ol=()=>!1,Ds=(e,t)=>{Ol()&&console.log(`[AI Parser] ${e}`,t??"")},en={commandsBlock:/```commands\n([\s\S]*?)```/gi,postCommandsBlock:/```post-commands\n([\s\S]*?)```/gi,dependenciesBlock:/```dependencies\n([\s\S]*?)```/gi,fileHeader:/^#{1,4}\s+`([^`]+)`\s*$/},yr=(e,t)=>[...e.matchAll(t)].flatMap(r=>r[1].split(`
|
|
151
|
+
`).map(o=>o.trim()).filter(o=>o.length>0&&!o.startsWith("#"))),Ls=e=>({command:e,isPfCommand:e.startsWith("pf ")||e.includes(" pf ")}),_l=e=>yr(e,en.commandsBlock).map(Ls),Dl=e=>yr(e,en.postCommandsBlock).map(Ls),Ll=e=>yr(e,en.dependenciesBlock).filter(t=>!t.startsWith("@crossdelta/")&&t!=="zod"),Hl=e=>{let t={ts:"typescript",js:"javascript",md:"markdown",yml:"yaml"},n=(e||"typescript").toLowerCase();return t[n]||n},Bl=e=>{let t=e.split(".").pop()?.toLowerCase();return{ts:"typescript",tsx:"typescript",js:"javascript",jsx:"javascript",json:"json",yaml:"yaml",yml:"yaml",md:"markdown"}[t||""]||"plaintext"},Wl=e=>e.replace(/^\s*\/\/ \.{3,}.*$/gm,"").replace(/^\s*\/\/ Lines? \d+.*omitted.*$/gim,"").replace(/^\s*\/\* Lines? \d+.*omitted.*\*\/$/gim,"").trim(),Gl=e=>{let t=e.split(`
|
|
152
|
+
`),n=[],r=0;for(let o of t){let s=en.fileHeader.exec(o);s&&n.push({path:s[1],index:r}),r+=o.length+1}return n},Ul=(e,t)=>{let r=e.slice(t).match(/```(\w+)?\n([\s\S]*?)```/);return r?{language:r[1]?Hl(r[1]):void 0,content:Wl(r[2])}:null},Jl=e=>Gl(e).map(n=>{let r=Ul(e,n.index);return!r||r.content.length===0?null:{path:n.path,language:r.language||Bl(n.path),content:r.content,startIndex:n.index}}).filter(n=>n!==null),hr=e=>e.includes("packages/contracts")||e.includes("contracts/src"),zl=e=>{let t=e.filter(r=>hr(r.path)),n=e.filter(r=>!hr(r.path));return[...t,...n]},Kl=e=>{let t=e.replace(/^\/+/,"").replace(/\/{2,}/g,"/");if(hr(t))return t;let n=t.match(/^services\/[^/]+\/(.+)$/);return n?n[1]:t},Hs=(e,t)=>{Ds("Parsing AI response",{length:e.length});let n=_l(e),r=Dl(e),o=Ll(e),s=Jl(e),a=zl(s.map(i=>({path:Kl(i.path),content:i.content,language:i.language})));return Ds("Parsed response",{commands:n.length,postCommands:r.length,dependencies:o.length,files:a.length}),{commands:n,files:a,dependencies:o,postCommands:r}},Bs=e=>{let t=e.filter(s=>!s.content||s.content.trim().length===0),n=e.length===0?["No files could be extracted from the AI response"]:t.map(s=>`File ${s.path} is empty`),r=e.some(s=>["src/index.ts","src/main.ts","index.ts"].includes(s.path)),o=e.length>0&&!r?["No entry point file (src/index.ts or src/main.ts) found - assuming it exists from scaffolding"]:[];return{valid:n.length===0,errors:n,warnings:o}};var Ws=require("node:fs"),J=u(require("chalk"));var Gs=async(e,t,n)=>{if(e.length===0){(0,Ws.mkdirSync)(t,{recursive:!0}),console.log(J.default.yellow(`\u26A0 No scaffolding command found - creating empty directory
|
|
153
|
+
`));return}let o=(await gr(e,n)).find(s=>!s.success);if(o)throw console.log(J.default.red(`
|
|
154
|
+
\u2717 Scaffolding failed: ${o.command}`)),o.error&&console.log(J.default.red(` Error: ${o.error}`)),new Error(`Command failed: ${o.command}${o.error?` - ${o.error}`:""}`)},Us=async(e,t,n)=>{if(e.length===0)return;n.stop();let r=e.length===1?"package":"packages";console.log(J.default.cyan(`
|
|
139
155
|
\u25B6 Installing ${e.length} additional ${r}...
|
|
140
|
-
`));try{await
|
|
141
|
-
`))}catch(o){throw console.log(
|
|
142
|
-
`)),o}},
|
|
156
|
+
`));try{await Z({packages:e,cwd:t,flags:["--silent"]}),console.log(J.default.green(`\u2713 Installed ${e.length} ${r}
|
|
157
|
+
`))}catch(o){throw console.log(J.default.red(`\u2717 Package installation failed
|
|
158
|
+
`)),o}},kr=async(e,t)=>{if(e.length===0)return;console.log(J.default.cyan(`
|
|
143
159
|
\u25B6 Running post-generation commands...
|
|
144
|
-
`));let r=(await
|
|
145
|
-
\u26A0 Post-command failed: ${r.command}`)),r.error&&console.log(
|
|
146
|
-
`))};var
|
|
147
|
-
`,
|
|
148
|
-
`),
|
|
149
|
-
\u{1F4C1} Files to create:`),...e.map(t=>` ${
|
|
160
|
+
`));let r=(await gr(e,t)).find(o=>!o.success);if(r){console.log(J.default.yellow(`
|
|
161
|
+
\u26A0 Post-command failed: ${r.command}`)),r.error&&console.log(J.default.yellow(` Error: ${r.error}`));return}console.log(J.default.green(`\u2713 Post-generation commands complete
|
|
162
|
+
`))};var ft=u(require("chalk")),ql=e=>`${ft.default.dim(" \u2022 ")+ft.default.cyan(e)}
|
|
163
|
+
`,Js=e=>ft.default.dim(` \u2728 Generated ${ft.default.white.bold(e)} tokens
|
|
164
|
+
`),zs=()=>{let e="",t=0,n=Date.now(),r=[],o=()=>{let a=e.match(/####\s+`([^`]+)`/);if(!a)return!1;r.push(a[1]),process.stdout.write(ql(a[1]));let i=e.indexOf(a[0])+a[0].length;return e=e.slice(i),!0},s=a=>{e+=a,t++,o(),e.length>500&&(e=e.slice(-200))};return s.getStats=()=>{let a=((Date.now()-n)/1e3).toFixed(2),i=(t/Number.parseFloat(a)).toFixed(0);return{tokenCount:t,duration:a,tokensPerSec:i}},s.getFiles=()=>r,s};var Vl=()=>{let e=y(),t=(0,_e.join)(e,"package.json"),n=(()=>{if(!(0,ae.existsSync)(t))throw new Error("No package.json found in workspace root. Run from a valid workspace.");try{let o=JSON.parse((0,ae.readFileSync)(t,"utf-8")).name;if(!o)throw new Error('package.json has no "name" field. Please add a name to your root package.json.');return o.startsWith("@")?o:`@${o}`}catch(r){throw r instanceof SyntaxError?new Error("Invalid JSON in package.json"):r}})();return{workspaceRoot:e,scope:n,cwd:process.cwd()}},Zl=async(e,t,n,r,o,s)=>{let a=_s(n,r,o,t.workspaceRoot),i=Os(t,o,s),c=zs(),l=await ps(e,a,{system:i,maxTokens:16384,temperature:.7,onToken:c}),p=c.getStats();return console.log(Js(p.tokenCount)),console.log(),l},Yl=(e,t)=>{let{serviceTypes:n}=Ae(),r=n[t]?.commandType;if(!r)return e;let o=Object.values(n).map(s=>s.commandType);return e.map(s=>{for(let a of o)if(a!==r&&s.command.includes(`pf new ${a}`))return{...s,command:s.command.replace(`pf new ${a}`,`pf new ${r}`)};return s})},Xl=e=>e.length===0?"":`${[k.default.cyan(`
|
|
165
|
+
\u{1F4C1} Files to create:`),...e.map(t=>` ${k.default.green("\u2022")} ${k.default.white(t.path)} ${k.default.dim(`(${t.language})`)}`)].join(`
|
|
150
166
|
`)}
|
|
151
|
-
`,
|
|
152
|
-
${n} ${t}:`),...e.map(r=>` ${
|
|
167
|
+
`,Ks=(e,t,n)=>e.length===0?"":`${[k.default.cyan(`
|
|
168
|
+
${n} ${t}:`),...e.map(r=>` ${k.default.yellow("$")} ${k.default.white(r.command)}`)].join(`
|
|
153
169
|
`)}
|
|
154
|
-
`,
|
|
155
|
-
\u{1F4E6} Dependencies to install:`),...e.map(t=>` ${
|
|
170
|
+
`,Ql=e=>e.length===0?"":`${[k.default.cyan(`
|
|
171
|
+
\u{1F4E6} Dependencies to install:`),...e.map(t=>` ${k.default.magenta("+")} ${k.default.white(t)}`)].join(`
|
|
156
172
|
`)}
|
|
157
|
-
`,
|
|
158
|
-
Validation errors:`),...e.map(n=>
|
|
159
|
-
Response preview:`),
|
|
173
|
+
`,ep=(e,t)=>`${[k.default.yellow(`
|
|
174
|
+
Validation errors:`),...e.map(n=>k.default.yellow(` \u26A0 ${n}`)),k.default.dim(`
|
|
175
|
+
Response preview:`),k.default.dim(t)].join(`
|
|
160
176
|
`)}
|
|
161
|
-
`,
|
|
162
|
-
`)},
|
|
163
|
-
`)+
|
|
164
|
-
`)};try{return{valid:!0,config:
|
|
165
|
-
`)}}},
|
|
177
|
+
`,Oe=e=>{e&&process.stdout.write(e)},tp=(e,t)=>{let n=Hs(e,t),r=fr(n.commands),o=fr(n.postCommands),s=Bs(n.files);return s.valid?{files:n.files,commands:r,dependencies:n.dependencies,postCommands:o}:(console.log(`${k.default.yellow("\u26A0")} Could not extract structured files from AI response`),Oe(ep(s.errors,e.slice(0,500))),null)},np=e=>{console.log(`${k.default.green("\u2714")} Extracted ${e.files.length} files`),Oe(Xl(e.files)),Oe(Ks(e.commands,"Commands to run","\u{1F527}")),Oe(Ks(e.postCommands,"Post-generation commands","\u{1F4DD}")),Oe(Ql(e.dependencies)),Oe(`
|
|
178
|
+
`)},rp=(e,t,n)=>{let r=Ts(e);return r&&!r.includes("/")&&!r.startsWith(".")&&(r=`${E().services}/${r}`),r?(0,_e.resolve)(n,r):(0,_e.resolve)(n,t)},op=(e,t)=>{let{serviceTypes:n}=Ae(),r=n[t]?.skipFiles||["package.json","tsconfig.json","Dockerfile"];return e.filter(o=>!r.includes(o.path))},De=()=>{if(!pt())return{valid:!1,error:k.default.red.bold(`\u274C AI configuration not found.
|
|
179
|
+
`)+k.default.yellow("Please run ")+k.default.cyan.bold("pf setup --ai")+k.default.yellow(` first to configure your AI provider.
|
|
180
|
+
`)};try{return{valid:!0,config:Ut()}}catch(e){return{valid:!1,error:k.default.red.bold(`\u274C ${e.message}
|
|
181
|
+
`)}}},tn=async e=>e||(0,qs.input)({message:"\u{1F4DD} Describe what this service should do:",validate:t=>t.trim().length>0||"Please provide a description for the AI to generate code"}),nn=(e,t,n)=>{console.log(k.default.cyan.bold(`
|
|
166
182
|
\u{1F916} AI-Powered Generation
|
|
167
|
-
`)),console.log(
|
|
168
|
-
`))},
|
|
183
|
+
`)),console.log(k.default.dim(`Service: ${e.split("/").pop()}`)),console.log(k.default.dim(`Path: ${e}`)),console.log(k.default.dim(`Model: ${t.model}`)),console.log(k.default.dim(`Description: ${n}
|
|
184
|
+
`))},rn=async(e,t)=>{let{servicePath:n,description:r="",serviceType:o,packageManager:s}=e,a=n.split("/").pop()||n,i=Vl(),c=(0,_e.join)(i.workspaceRoot,jn);(0,ae.writeFileSync)(c,`generating:${n}`);let l=()=>{(0,ae.existsSync)(c)&&(0,ae.unlinkSync)(c)},p=()=>{l(),process.exit(130)};process.on("SIGINT",p),process.on("SIGTERM",p);try{console.log(k.default.cyan.bold(`
|
|
169
185
|
\u{1F916} AI Generation
|
|
170
|
-
`));let d=await
|
|
171
|
-
`));let
|
|
186
|
+
`));let d=await Zl(t,i,n,r,o,s),C=tp(d,a);if(!C)return!1;np(C);let L=(0,Vs.default)({text:"Processing files...",color:"cyan"}).start(),tt=Yl(C.commands,o),H=rp(tt,n,i.cwd),fc=op(C.files,o);await Gs(tt,H,i.workspaceRoot);let{missingContractCommands:lo}=await As(fc,H,i,L);if(C.postCommands.length>0)await kr(C.postCommands,i.workspaceRoot);else if(lo.length>0){console.log(k.default.cyan(`\u{1F527} Auto-creating missing contracts...
|
|
187
|
+
`));let hc=lo.map(yc=>({command:yc,isPfCommand:!0}));await kr(hc,i.workspaceRoot)}return Ps(H),await Us(C.dependencies,H,L),await $s(H,L),!0}finally{process.off("SIGINT",p),process.off("SIGTERM",p),l()}};var Ys=require("node:fs"),ht=require("ts-morph"),Zs=new ht.Project({skipAddingFilesFromTsConfig:!0,skipFileDependencyResolution:!0}),vr=e=>{if(!(0,Ys.existsSync)(e))return null;let t=Zs.getSourceFile(e);return t||Zs.addSourceFileAtPath(e)},Cr=e=>{e.saveSync()},xr=(e,t,n)=>{let r=e.getImportDeclaration(t);if(r){let o=r.getNamedImports().map(a=>a.getName()),s=n.filter(a=>!o.includes(a));for(let a of s)r.addNamedImport(a);return}e.addImportDeclaration({moduleSpecifier:t,namedImports:n})},sp=e=>{for(let t of e.getClasses()){let n=t.getDecorator("Module");if(!n)continue;let r=n.getArguments();if(r.length===0)continue;let o=r[0];if(o.getKind()===ht.SyntaxKind.ObjectLiteralExpression)return o}return null},wr=(e,t)=>{let n=sp(e);if(!n)return!1;let r=n.getProperty("imports");if(r){let o=r.getFirstChildByKind(ht.SyntaxKind.ArrayLiteralExpression);return o?(o.getElements().map(a=>a.getText()).includes(t)||o.addElement(t),!0):!1}return n.addPropertyAssignment({name:"imports",initializer:`[${t}]`}),!0};var on=require("node:fs"),yt=u(require("node:path")),br=u(require("chalk"));g();var Xs=async e=>{await de("bash",["-c",`
|
|
172
188
|
curl -fsSL https://bun.sh/install | bash && if [ -f "$HOME/.bun/bin/bun" ]; then export PATH="$HOME/.bun/bin:$PATH"; fi
|
|
173
|
-
`],{task:e,shell:!0}),await
|
|
189
|
+
`],{task:e,shell:!0}),await ap()},Sr=()=>ot("bun"),Qs=()=>Mn([{label:"Bun",value:59026,color:"magenta",barColor:"magenta"},{label:"Deno",value:25335},{label:"Node.js",value:19039}],{title:'Express.js "hello world" HTTP requests per second (Linux x64)',barColor:"blackBright"}),ea=()=>Mn([{label:"Bun",value:.36,color:"magenta",barColor:"magenta"},{label:"pnpm",value:6.44},{label:"npm",value:10.58},{label:"yarn",value:12.08}],{title:"Bun is an npm-compatible package manager.",unit:"s",footer:br.default.blackBright("* Installing dependencies from cache for a Remix app."),barColor:"blackBright"}),ap=async()=>{let e='export PATH="$HOME/.bun/bin:$PATH"',t=process.env.HOME;if(!t){m.error("Could not detect $HOME environment variable. Cannot update shell config.");return}let n=[yt.default.join(t,".zshrc"),yt.default.join(t,".bashrc"),yt.default.join(t,".bash_profile")];for(let r of n)try{if(await on.promises.stat(r).then(()=>!0).catch(()=>!1)){(await on.promises.readFile(r,"utf8")).includes(e)||(await on.promises.appendFile(r,`
|
|
174
190
|
# Added by platform installer
|
|
175
191
|
${e}
|
|
176
|
-
`),m.log(`Added Bun path to ${
|
|
192
|
+
`),m.log(`Added Bun path to ${yt.default.basename(r)}`));return}}catch(o){m.error(`Failed to update ${r}: ${o.message}`)}m.warn("No shell config file (.zshrc, .bashrc, .bash_profile) found. Please add the following manually:"),m.log(br.default.cyan(e))};var I=require("node:fs"),Le=require("node:path");v();var kt=require("node:fs"),sn=require("node:path"),ta=require("@crossdelta/cloudevents"),ip=e=>e.isDirectory()&&e.name!=="node_modules",cp=(e,t)=>{let n=t.replace(".ts",""),r=(0,sn.join)(e,`${n}.mock.json`);return(0,kt.existsSync)(r)},lp=(e,t)=>t.endsWith(".ts")&&t!=="index.ts"&&cp(e,t),pp=(e,t)=>{let n=t.replace(".ts","");return`${(0,ta.singularize)(e)}.${n}`},mp=e=>(0,kt.readdirSync)(e,{withFileTypes:!0}).filter(ip).flatMap(r=>{let o=(0,sn.join)(e,r.name);return(0,kt.readdirSync)(o).filter(a=>lp(o,a)).map(a=>pp(r.name,a))}),Pr=()=>{try{let e=(0,sn.join)(process.cwd(),"packages","contracts","src","events");return mp(e).sort()}catch{return[]}},na=()=>Pr();var ra=require("node:fs"),oa=require("node:path"),vt=u(require("chalk"));v();var an=u(require("chalk")),ge=e=>{let t=Math.max(...e.commands.map(o=>o.name.length)),n=e.commands.map(o=>{let s=" ".repeat(t-o.name.length+3);return` ${an.default.cyan(o.name)}${s}${o.description}`}),r=e.footer||'Run "<command> --help" for more information';return[an.default.cyan.bold(`
|
|
177
193
|
${e.title}
|
|
178
194
|
`),`Available commands:
|
|
179
|
-
`,...n,"",
|
|
195
|
+
`,...n,"",an.default.dim(`${r}
|
|
180
196
|
`)].join(`
|
|
181
|
-
`)};var
|
|
197
|
+
`)};var dp=(e,t)=>t.some(n=>n.name()===e),up=(e,t)=>t.pf?.commands?.[e]??null,gp=(e,t)=>!!t.scripts?.[e],fp=(e,t)=>t.cwd?(0,oa.join)(e,t.cwd):e,hp=(e,t)=>t.command||e,yp=(e,t,n,r)=>{let o=fp(r,n),s=hp(e,n);if(n.cwd&&!(0,ra.existsSync)(o))return console.error(vt.default.red(`
|
|
182
198
|
\u2716 Directory not found: ${o}
|
|
183
|
-
`)),!0;let a=n.cwd?
|
|
199
|
+
`)),!0;let a=n.cwd?vt.default.dim(` in ${n.cwd}/`):"";return console.log(vt.default.dim(`Running ${s}${a}`)),Bt(s,t,{cwd:o}),!0},kp=(e,t,n)=>(console.log(vt.default.dim(`Running workspace script: ${e}`)),it(e,{args:t,cwd:n}),!0);async function vp(e,t,n){if(dp(e,n))return!1;let r;try{r=y()}catch{return!1}let o=G(r);if(!o)return!1;let s=up(e,o);return s?yp(e,t,s,r):gp(e,o)?kp(e,t,r):!1}function sa(){let e;try{e=G()}catch{return{configured:[],scripts:[]}}if(!e)return{configured:[],scripts:[]};let t=Object.keys(e.pf?.commands??{}),r=Object.keys(e.scripts??{}).filter(o=>!t.includes(o));return{configured:t,scripts:r}}function Tr(){let{configured:e,scripts:t}=sa();return[...e,...t]}function aa(){let{configured:e,scripts:t}=sa(),n=[...e,...t];if(n.length===0)return"";let o=G()?.pf?.commands||{},s=n.map(a=>({name:a,description:o[a]?.description||cn[a]||""}));return ge({title:"Workspace Commands",commands:s,footer:""})}function ia(e,t,n){let r=t.slice(2);if(r.length>0&&!r[0].startsWith("-")){let o=r[0],s=r.slice(1);if(o==="__workspace-commands"&&s.includes("--names-only")){let a=Tr();for(let i of a)console.log(i);return}vp(o,s,n).then(a=>{a||e.parse(t)})}else e.parse(t)}v();var ca={setup:"Configure platform settings",new:"Create a new project",dev:"Start development mode",event:"Event management commands",token:"Token management commands",audit:"Run security audit"},cn={build:"Build all packages",test:"Run tests",lint:"Lint codebase",format:"Format code",preview:"Preview application",prepare:"Prepare workspace",pulumi:"Run Pulumi commands","pub-sdk":"Publish platform SDK","pub-cloudevents":"Publish cloudevents package","check-versions":"Check internal version consistency","sync-versions":"Sync internal package versions","sync-templates":"Sync service templates","generate-env":"Generate environment files",dev:"Start development environment"},la=(e,t)=>t?`${e}:${t}`:e,Cp=()=>Object.entries(ca).map(([e,t])=>la(e,t)),xp=()=>{try{let e=Tr(),n=G()?.pf?.commands||{},r=Object.keys(ca);return e.filter(o=>!r.includes(o)).map(o=>{let s=n[o]?.description||cn[o]||"";return la(o,s)})}catch{return[]}},wp=()=>{try{return na()}catch{return[]}},bp=async()=>{try{let e=y();return await ds(e)}catch{return[]}},Er=async()=>({commands:[...Cp(),...xp()],events:wp(),services:await bp()});var Ct="node_modules/.cache/pf",xt="completion-cache";var Sp=e=>{let t=O.version||"0.0.0",n=e.commands.join("|"),r=e.events.join("|"),o=e.services.join("|");return`${t} ${n} ${r} ${o}`},pa=e=>{let t=e.split(" ");if(t.length===4){let[o,s,a,i]=t;return{version:o,commands:s?s.split("|"):[],events:a?a.split("|"):[],services:i?i.split("|"):[]}}if(t.length===3){let[o,s,a]=t;return{version:o,commands:s?s.split("|"):[],events:a?a.split("|"):[],services:[]}}let[n,r]=t;return{commands:n?n.split("|"):[],events:r?r.split("|"):[],services:[]}},ma=e=>{let t=(0,Le.join)(e,Ct);return(0,Le.join)(t,xt)},Pp=(e,t=!1)=>{if(t)return!0;let n=ma(e);if(!(0,I.existsSync)(n))return!0;let r=(0,I.readFileSync)(n,"utf-8").trim(),o=pa(r),s=O.version||"0.0.0";if(o.version!==s)return!0;let a=(0,Le.join)(e,"package.json");if(!(0,I.existsSync)(a))return!1;let i=(0,I.statSync)(n).mtimeMs;return(0,I.statSync)(a).mtimeMs>i},$r=e=>{let t=ma(e);if(!(0,I.existsSync)(t))return null;try{let n=(0,I.readFileSync)(t,"utf-8").trim();return pa(n)}catch{return null}},Tp=(e,t)=>{let n=(0,Le.join)(e,Ct),r=(0,Le.join)(n,xt);(0,I.existsSync)(n)||(0,I.mkdirSync)(n,{recursive:!0});let o=Sp(t);(0,I.writeFileSync)(r,o,"utf-8")},ln=async(e={})=>{let t;try{t=y()}catch{return!1}if(!t)return!1;if(!Pp(t,e.force))return e.verbose&&console.log("[completion] Cache is up to date"),!1;let n=await Er();return Tp(t,n),e.verbose&&console.log(`[completion] Cache regenerated: ${n.commands.length} commands, ${n.events.length} events`),!0},fe=async(e={})=>{await ln({...e,force:!0})};var ee=require("node:fs"),Ar=require("node:os"),pn=require("node:path"),Te=u(require("chalk"));var da=`${Ct}/${xt}`,ua=e=>`# ${e} completion (workspace-local cache)
|
|
184
200
|
# Generated: ${new Date().toISOString()}
|
|
185
201
|
|
|
186
202
|
# Cache file path (relative to workspace root)
|
|
187
|
-
_${e}_cache_path="${
|
|
203
|
+
_${e}_cache_path="${da}"
|
|
188
204
|
|
|
189
205
|
# Find workspace root (walk up to find monorepo package.json)
|
|
190
206
|
_${e}_find_workspace() {
|
|
@@ -223,16 +239,22 @@ _${e}_completions() {
|
|
|
223
239
|
cache_data=$(_${e}_read_cache "$ws_root")
|
|
224
240
|
fi
|
|
225
241
|
|
|
226
|
-
# Parse data: "version cmd1:desc1|cmd2:desc2 events"
|
|
242
|
+
# Parse data: "version cmd1:desc1|cmd2:desc2 events services"
|
|
227
243
|
# Split by tabs, skip first field (version)
|
|
228
244
|
local -a parts
|
|
229
245
|
parts=("\${(@s: :)cache_data}")
|
|
230
246
|
|
|
231
247
|
local commands_str=""
|
|
232
248
|
local events_str=""
|
|
249
|
+
local services_str=""
|
|
233
250
|
|
|
234
|
-
if [[ \${#parts[@]} -eq
|
|
235
|
-
# New format: version commands events
|
|
251
|
+
if [[ \${#parts[@]} -eq 4 ]]; then
|
|
252
|
+
# New format with services: version commands events services
|
|
253
|
+
commands_str="\${parts[2]}"
|
|
254
|
+
events_str="\${parts[3]}"
|
|
255
|
+
services_str="\${parts[4]}"
|
|
256
|
+
elif [[ \${#parts[@]} -eq 3 ]]; then
|
|
257
|
+
# Format without services: version commands events
|
|
236
258
|
commands_str="\${parts[2]}"
|
|
237
259
|
events_str="\${parts[3]}"
|
|
238
260
|
elif [[ \${#parts[@]} -eq 2 ]]; then
|
|
@@ -305,11 +327,11 @@ _${e}_completions() {
|
|
|
305
327
|
esac
|
|
306
328
|
}
|
|
307
329
|
|
|
308
|
-
compdef _${e}_completions ${e}`,
|
|
330
|
+
compdef _${e}_completions ${e}`,ga=e=>`# ${e} completion (workspace-local cache)
|
|
309
331
|
# Generated: ${new Date().toISOString()}
|
|
310
332
|
|
|
311
333
|
# Cache file path (relative to workspace root)
|
|
312
|
-
_${e}_cache_path="${
|
|
334
|
+
_${e}_cache_path="${da}"
|
|
313
335
|
|
|
314
336
|
# Find workspace root
|
|
315
337
|
_${e}_find_workspace() {
|
|
@@ -342,17 +364,23 @@ _${e}_completions() {
|
|
|
342
364
|
local cache_data=""
|
|
343
365
|
local commands_str=""
|
|
344
366
|
local events_str=""
|
|
367
|
+
local services_str=""
|
|
345
368
|
local in_workspace=0
|
|
346
369
|
|
|
347
370
|
if [[ -n "$ws_root" ]]; then
|
|
348
371
|
in_workspace=1
|
|
349
372
|
cache_data=$(_${e}_read_cache "$ws_root")
|
|
350
373
|
|
|
351
|
-
# Parse data: "version cmd1:desc1|cmd2:desc2 events"
|
|
374
|
+
# Parse data: "version cmd1:desc1|cmd2:desc2 events services"
|
|
352
375
|
IFS=$'\\t' read -ra parts <<< "$cache_data"
|
|
353
376
|
|
|
354
|
-
if [[ \${#parts[@]} -eq
|
|
355
|
-
# New format: version commands events
|
|
377
|
+
if [[ \${#parts[@]} -eq 4 ]]; then
|
|
378
|
+
# New format with services: version commands events services
|
|
379
|
+
commands_str="\${parts[1]}"
|
|
380
|
+
events_str="\${parts[2]}"
|
|
381
|
+
services_str="\${parts[3]}"
|
|
382
|
+
elif [[ \${#parts[@]} -eq 3 ]]; then
|
|
383
|
+
# Format without services: version commands events
|
|
356
384
|
commands_str="\${parts[1]}"
|
|
357
385
|
events_str="\${parts[2]}"
|
|
358
386
|
elif [[ \${#parts[@]} -eq 2 ]]; then
|
|
@@ -397,11 +425,11 @@ _${e}_completions() {
|
|
|
397
425
|
return 0
|
|
398
426
|
}
|
|
399
427
|
|
|
400
|
-
complete -F _${e}_completions ${e}`;var
|
|
428
|
+
complete -F _${e}_completions ${e}`;var Ep=(e,t)=>(0,pn.join)((0,Ar.homedir)(),`.${t}-completion.${e}`),ha=e=>{let t=(0,Ar.homedir)();return e==="zsh"?(0,pn.join)(t,".zshrc"):(0,pn.join)(t,".bashrc")},$p=e=>`[[ -f "${e}" ]] && source "${e}"`,Ap=(e,t)=>(0,ee.existsSync)(e)?(0,ee.readFileSync)(e,"utf-8").includes(t):!1,Ip=(e,t)=>{let n=(0,ee.existsSync)(e)?(0,ee.readFileSync)(e,"utf-8"):"",r=n.endsWith(`
|
|
401
429
|
`)?`${n}${t}
|
|
402
430
|
`:`${n}
|
|
403
431
|
${t}
|
|
404
|
-
`;(0,
|
|
432
|
+
`;(0,ee.writeFileSync)(e,r,"utf-8")},Np=(e,t)=>{let n=Ep(e,t),r=e==="zsh"?ua(t):ga(t);return(0,ee.writeFileSync)(n,r,"utf-8"),n},fa=(e,t,n)=>{let r=Np(e,t),o=ha(e),s=$p(r);return Ap(o,s)?(n&&console.log(Te.default.dim(`[${e}] Already configured in ${o}`)),!1):(Ip(o,s),n&&console.log(Te.default.green(`[${e}] Added source line to ${o}`)),!0)},Rp=()=>(process.env.SHELL||"").includes("zsh")?"zsh":"bash",Ir=(e,t=!1)=>{let n=Rp();t&&console.log(Te.default.cyan(`Installing ${n} completion...`)),fa(n,e,t);let r=n==="zsh"?"bash":"zsh",o=ha(r);(0,ee.existsSync)(o)&&fa(r,e,t),t&&(console.log(Te.default.green("\u2713 Shell completion installed")),console.log(Te.default.dim(` Run: ${Te.default.cyan("exec $SHELL")} to reload`)))};var j=u(require("chalk")),ya=require("execa"),ka=require("jiti");v();var Nr=async e=>{let{stdout:t}=await(0,ya.execa)("sh",["-c",e]);return t.trim()},Mp="pf-local-nats",jp="2.10-alpine",Fp=4222,Op=8222,_p=e=>({clientPort:e.clientPort??Fp,monitoringPort:e.monitoringPort??Op,containerName:e.containerName??Mp,version:e.version??jp}),Dp=e=>["run","--rm","--detach",`--name=${e.containerName}`,`-p=${e.clientPort}:4222`,`-p=${e.monitoringPort}:8222`,`nats:${e.version}`,"--jetstream","--store_dir=/data","--http_port=8222"],Lp=e=>({containerName:e.containerName,clientUrl:`nats://localhost:${e.clientPort}`,monitoringUrl:`http://localhost:${e.monitoringPort}`}),Hp=async()=>{try{return await Nr("docker info"),!0}catch{return!1}},Bp=async e=>{try{return(await Nr(`docker ps -q -f name=${e}`)).length>0}catch{return!1}};var Wp=async e=>{let t=Dp(e);try{return await Nr(`docker ${t.join(" ")}`),{success:!0,value:Lp(e)}}catch{return{success:!1}}},Gp=e=>{console.log(j.default.green("\u2713 NATS started")),console.log(j.default.dim(` Client: ${e.clientUrl}`)),console.log(j.default.dim(` Monitoring: ${e.monitoringUrl}`)),console.log(j.default.dim(" Streams: ephemeral, auto-created by services")),console.log("")},va=async(e={})=>{let t=_p(e);if(!await Hp())return console.log(j.default.yellow("\u26A0\uFE0F Docker not available - skipping NATS (services may fail)")),!1;if(await Bp(t.containerName))return console.log(j.default.dim("\u2713 NATS already running")),!0;console.log(j.default.cyan("\u{1F680} Starting development infrastructure...")),console.log(j.default.dim(" NATS with JetStream (ephemeral)"));let n=await Wp(t);return n.success?(Gp(n.value),!0):(console.error(j.default.red("\u2717 Failed to start NATS")),!1)},Up=e=>e.map(t=>({stream:t,subjects:[`${t.toLowerCase()}.*`],config:{storage:"memory",retention:"limits",maxAge:36e5}})),Jp=e=>Array.from(new Set(Object.values(e).filter(t=>t!==null&&typeof t=="object"&&"channel"in t).map(t=>t.channel?.stream).filter(t=>!!t))),Ca=async e=>{try{let{ensureJetStreams:t}=await import("@crossdelta/cloudevents"),{indexPath:n}=x(e),o=await(0,ka.createJiti)(e,{moduleCache:!1}).import(n,{default:!0}),s=Jp(o);if(s.length===0){console.log(j.default.dim(" No streams found in contracts"));return}let a=Up(s);await t({streams:a}),console.log(j.default.dim(` Created ${s.length} ephemeral stream(s): ${s.join(", ")}`))}catch(t){console.log(j.default.yellow(` \u26A0\uFE0F Stream creation failed: ${t instanceof Error?t.message:"Unknown error"}`)),console.log(j.default.dim(" Stream auto-creation will happen on first publish"))}};function xa(e,t){return`import type { K8sServiceConfig } from '@crossdelta/infrastructure'
|
|
405
433
|
import { ports } from '@crossdelta/infrastructure'
|
|
406
434
|
|
|
407
435
|
/**
|
|
@@ -422,7 +450,7 @@ const config: K8sServiceConfig = {
|
|
|
422
450
|
}
|
|
423
451
|
|
|
424
452
|
export default config
|
|
425
|
-
`}function
|
|
453
|
+
`}function wa(e,t){return`import type { K8sServiceConfig } from '@crossdelta/infrastructure'
|
|
426
454
|
import { ports } from '@crossdelta/infrastructure'
|
|
427
455
|
|
|
428
456
|
/**
|
|
@@ -443,91 +471,72 @@ const config: K8sServiceConfig = {
|
|
|
443
471
|
}
|
|
444
472
|
|
|
445
473
|
export default config
|
|
446
|
-
`}var
|
|
447
|
-
`))}};var
|
|
474
|
+
`}var te=u(require("chalk")),Pa=u(require("terminal-link"));g();var mn="integrations-run";var $=require("zod"),zp=$.z.object({name:$.z.string(),description:$.z.string(),link:$.z.string().url().optional(),install:$.z.union([$.z.string(),$.z.array($.z.string())]).transform(e=>Array.isArray(e)?e:[e]),installFlags:$.z.array($.z.string()).optional(),run:$.z.array($.z.string()).optional(),initial:$.z.boolean().optional(),interactive:$.z.boolean().optional()}),ba=$.z.array(zp);var Sa=e=>{try{return ba.parse(e)}catch(t){throw new Error(t.issues.map(n=>` - Path ${n.path.join(". ")} : ${n.message}`).join(`
|
|
475
|
+
`))}};var z=()=>{try{let e=at("bin/integration.collection.json");return Sa(e)}catch(e){throw new Error(`Failed to load integrations!
|
|
448
476
|
Check your integration.collection.json:
|
|
449
|
-
${e.message}`)}},
|
|
450
|
-
`))}))},
|
|
451
|
-
`),fn:()=>
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
`),e
|
|
455
|
-
\x1B[31m\u2716\x1B[0m Not in a workspace directory
|
|
456
|
-
|
|
457
|
-
Current directory: ${process.cwd()}
|
|
458
|
-
|
|
459
|
-
This command must be run from within a workspace created with \x1B[36mpf new workspace\x1B[0m
|
|
460
|
-
|
|
461
|
-
To create a new workspace, run:
|
|
462
|
-
|
|
463
|
-
\x1B[36mpf new workspace my-platform\x1B[0m
|
|
464
|
-
`);return e},J=e=>{let t=e??y();return hr((0,E.join)(t,"package.json"))},B=e=>{let t=J(e);if(!t?.pf?.paths)return ht;let{paths:n}=t.pf;return{services:on(n.services,ht.services),apps:on(n.apps,ht.apps),packages:on(n.packages,ht.packages),contracts:on(n.contracts,ht.contracts)}},C=e=>{let t=e??y(),n=B(t),r=(0,E.join)(t,n.contracts);return{packagePath:r,eventsPath:(0,E.join)(r,"src","events"),indexPath:(0,E.join)(r,"src","index.ts"),relativePath:n.contracts}},Ee=()=>{let e=y(),t=hr((0,E.join)(e,"package.json")),n=`@${$p(e)}`;return t?.name?t.name.startsWith("@")?t.name.split("/")[0]:`@${t.name}`:n},Np=(e,t)=>{let n=Qs(t),r=e;for(let o of n){if(r===null||typeof r!="object"||!(o in r))return;r=r[o]}return r},Rp=(e,t,n)=>{let r=Qs(t),o=r[r.length-1],s=e;for(let a of r.slice(0,-1))(!(a in s)||typeof s[a]!="object"||s[a]===null)&&(s[a]={}),s=s[a];s[o]=n},na=(e,t=process.cwd())=>{let n=(0,Ce.readJsonSync)((0,E.join)(t,"package.json"));return Np(n,e)},re=(e,t,n=process.cwd())=>{let r=(0,E.join)(n,"package.json"),o=(0,Ce.readJsonSync)(r);Rp(o,e,t),(0,Ce.writeJsonSync)(r,o,{spaces:2,EOL:`
|
|
465
|
-
`,encoding:"utf-8"})},Yt=e=>{let t=Zs();return(0,Ce.readJSONSync)((0,E.resolve)(t,e),{encoding:"utf-8"})},R=Yt("package.json"),st=()=>R.generatorConfig??Tp;var Mp=e=>e==="yarn"?["npm","audit"]:["audit"],sa=new oa.Command("audit").description("Run security audit on dependencies").allowUnknownOption(!0).action((e,t)=>{let n=y(),r=x(),o=Mp(r),s=t.args||[];console.log(ra.default.dim(`Running ${r} ${[...o,...s].join(" ")}`)),jt(r,[...o,...s],{cwd:n})});var de=require("@listr2/prompt-adapter-enquirer"),ae=u(require("chalk"));function sn(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}async function aa(e,t,n={},r=[],o=[]){if(!e){console.error("Subcommand is not defined.");return}let s=r.map(l=>t[l]).filter(l=>l!==void 0),a=o.map(l=>{let p=t[l];if(!(p===!1||p===void 0))return p===!0?`--${sn(String(l))}`:`--${sn(String(l))}=${String(p)}`}).filter(l=>l!==void 0),i=Object.entries(n).map(([l,p])=>{if(!(p===!1||p===void 0))return p===!0?`--${sn(l)}`:`--${sn(l)}=${String(p)}`}).filter(l=>l!==void 0),c=[...s,...a,...i].map(String);await e.parseAsync(c,{from:"user"})}var $a=require("node:path"),oe=u(require("chalk"));var ia=require("@listr2/prompt-adapter-enquirer"),Oe={title:"Confirm creation",enabled:e=>!e.userConfirmed,task:async(e,t)=>{if(e.userConfirmed=await t.prompt(ia.ListrEnquirerPromptAdapter).run({type:"Toggle",initial:!0,message:"\u{1F680} Ready to launch your project?"}),!e.userConfirmed)throw new Error("Project creation was canceled by the user.")}};var Y=require("node:fs"),_e=require("node:path");var jp=4001,Fp=4e3;function Op(e){let t=[],n=e.matchAll(/ports\(\)\.(?:http|https|grpc|primary)\((\d+)\)/g);for(let c of n)t.push(Number(c[1]));let r=e.matchAll(/\.add(?:Http|Grpc)?\((\d+)/g);for(let c of r)t.push(Number(c[1]));let o=e.match(/containerPort\s*:\s*(\d+)/);o&&t.push(Number(o[1]));let s=e.match(/internalPorts\s*:\s*\[([^\]]+)\]/);if(s){let c=s[1].match(/\d+/g);c&&t.push(...c.map(Number))}let a=e.match(/httpPort\s*:\s*(\d+)/);a&&t.push(Number(a[1]));let i=e.matchAll(/const\s+\w*[pP]ort\w*\s*=\s*(\d+)/g);for(let c of i)t.push(Number(c[1]));return t}function _p(e,t){let n=t?jp:Fp,r=new Set;if(!(0,Y.existsSync)(e))return n;let o=(0,Y.readdirSync)(e).filter(a=>a.endsWith(".ts"));for(let a of o){let i=(0,_e.join)(e,a);try{let c=(0,Y.readFileSync)(i,"utf-8"),l=Op(c);for(let p of l)r.add(p)}catch{}}let s=n;for(;r.has(s);)s++;return s}function Dp(e){return(0,_e.basename)(e)}var an={title:"Creating infrastructure service config",task:async(e,t)=>{let n=Dp(e.projectName),r=y(),o=(0,_e.join)(r,"infra","services");if(!(0,Y.existsSync)(o)){t.title="Skipping infra config (no infra/services directory found)";return}let s=(0,_e.join)(o,`${n}.ts`);if((0,Y.existsSync)(s)){t.title=`Service config already exists: infra/services/${n}.ts`;return}let a=_p(o,!0);e.assignedPort=a;let i=e.serviceType==="hono"?$s(n,a):Es(n,a);(0,Y.writeFileSync)(s,i),t.title=`Created infra/services/${n}.ts (port: ${a})`}};var yt=require("node:child_process"),ca=require("node:fs"),la=require("node:path"),Lp=()=>{try{return(0,yt.execSync)("git --version",{stdio:"ignore"}),!0}catch{return!1}},Hp=e=>(0,ca.existsSync)((0,la.join)(e,".git")),pa={title:"Initializing git repository",enabled:()=>Lp(),skip:e=>Hp(e.cwd)?"Already a git repository":!1,task:async(e,t)=>{try{(0,yt.execSync)("git init",{cwd:e.cwd,stdio:"ignore"}),(0,yt.execSync)("git add -A",{cwd:e.cwd,stdio:"ignore"}),(0,yt.execSync)('git commit -m "chore: initial commit"',{cwd:e.cwd,stdio:"ignore",env:{...process.env,GIT_AUTHOR_NAME:process.env.GIT_AUTHOR_NAME||"Platform SDK",GIT_AUTHOR_EMAIL:process.env.GIT_AUTHOR_EMAIL||"platform-sdk@localhost",GIT_COMMITTER_NAME:process.env.GIT_COMMITTER_NAME||"Platform SDK",GIT_COMMITTER_EMAIL:process.env.GIT_COMMITTER_EMAIL||"platform-sdk@localhost"}}),t.title="Git repository initialized with initial commit"}catch{t.title="Git initialization skipped (git error)"}}};var ma=require("@listr2/prompt-adapter-enquirer"),yr=u(require("chalk"));var De={title:"Installing Bun",enabled:e=>!!e.shouldInstallBun&&!sr(),task:async(e,t)=>P(t,async n=>{await is(t),e.elapsedTime+=n(),t.title=`Bun installed successfully. (${e.elapsedTime}s)`})},Le={enabled:e=>!sr()&&!e.shouldInstallBun&&!e.packageManager,task:async(e,t)=>{e.shouldInstallBun=await t.prompt(ma.ListrEnquirerPromptAdapter).run({type:"Toggle",message:"Would you like to use Bun? (recommended)",initial:!0,footer:["",`${yr.default.magenta.bold("Bun")} is a fast JavaScript runtime, package manager, bundler, and test runner: ${yr.default.underline("https://bun.sh")}`,cs(),ls()].join(`
|
|
466
|
-
`)}),e.shouldInstallBun&&(e.packageManager="bun")}};var da=require("@listr2/prompt-adapter-enquirer"),kr=u(require("chalk"));var cn={title:"Install integrations",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>P(t,async n=>{let{selectedIntegrations:r,cwd:o,packageManager:s}=e;await Ms({selectedIntegrations:r,packageManager:s,cwd:o,task:t}),e.elapsedTime+=n()}),rendererOptions:{outputBar:1e3}},ln={title:"Select integrations",enabled:e=>e.selectedIntegrations.length===0,task:async(e,t)=>{e.selectedIntegrations=await t.prompt(da.ListrEnquirerPromptAdapter).run({type:"MultiSelect",hint:`
|
|
467
|
-
Press <space> to select/deselect, <enter> to confirm, <i> to invert selection`,message:"Which integrations would you like to include?",initial:Me().map((n,r)=>r),choices:e.availableIntegrations.map(({name:n,description:r})=>({name:n,message:[kr.default.bold(n),r].join(" - "),value:n}))}),!e.selectedIntegrations||e.selectedIntegrations.length===0?t.title="No integrations selected.":t.title=["Selected integrations:",...e.selectedIntegrations.map(n=>kr.default.bold(`\u2022 ${n}`))].join(`
|
|
468
|
-
`)}};var ua={title:"Install Nest CLI",task:async(e,t)=>P(t,async n=>{await No({packages:["@nestjs/cli"],task:t,cwd:e.cwd}),e.elapsedTime+=n()}),rendererOptions:{outputBar:1e3}};var pn={title:"Install dependencies",task:async(e,t)=>P(t,async n=>{await H({cwd:e.cwd,task:t,packageManager:e.packageManager}),e.elapsedTime+=n()})};var ga=require("@listr2/prompt-adapter-enquirer"),fa=u(require("chalk"));var He={enabled:e=>!e.removeDir&&!rn(e.cwd),task:async(e,t)=>{if(e.removeDir=await t.prompt(ga.ListrEnquirerPromptAdapter).run({type:"Toggle",message:fa.default.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}),!e.removeDir)throw new Error("Project creation was canceled by the user.")}},Be={enabled:e=>!!e.removeDir,task:async e=>Ys(e.cwd)};var mn={title:"Run integration commands",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>P(t,async n=>{let{selectedIntegrations:r,cwd:o}=e;await Fs({selectedIntegrations:r,cwd:o,task:t,packageManager:e.packageManager}),e.elapsedTime+=n()}),rendererOptions:{outputBar:1}};var ha=require("@listr2/prompt-adapter-enquirer");var Bp=["services/my-hono-service","services/my-nest-service","my-platform"],We={enabled:e=>e.skipInputPrompts||e.userConfirmed?!1:e.projectName?Bp.includes(e.projectName):!0,task:async(e,t)=>{e.projectName=await t.prompt(ha.ListrEnquirerPromptAdapter).run({type:"Input",initial:e.projectName,message:"Enter project name",validate:n=>n?!0:"Project name is required."}),e.cwd&&(e.cwd=g(e.projectName))}};var ya=require("@listr2/prompt-adapter-enquirer"),vr=u(require("chalk"));var Ge={title:"Select Package manager",task:async(e,t)=>{if(e.packageManager??=Vn(),e.packageManager){t.title=`Using ${vr.default.bold(e.packageManager)} as package manager.`;return}e.packageManager=await t.prompt(ya.ListrEnquirerPromptAdapter).run({type:"Select",message:"Which package manager would you like to use?",initial:Zn(),choices:Io}),t.title=`Using ${vr.default.bold(e.packageManager)} as package manager.`}};var dn=require("@listr2/prompt-adapter-enquirer"),kt=u(require("chalk")),ka={title:"GitHub repository owner",task:async(e,t)=>{if(e.githubOwner){t.title=`GitHub owner: ${kt.default.bold(e.githubOwner)}`;return}e.githubOwner=await t.prompt(dn.ListrEnquirerPromptAdapter).run({type:"Input",message:"Enter GitHub organization or username",initial:"my-org",validate:n=>n?.trim()?!0:"GitHub owner is required."}),t.title=`GitHub owner: ${kt.default.bold(e.githubOwner)}`}},va={title:"Include GitHub CI/CD",task:async(e,t)=>{if(e.includeGitHubCI!==void 0){t.title=e.includeGitHubCI?"Including GitHub CI/CD workflows":"Skipping GitHub CI/CD";return}e.includeGitHubCI=await t.prompt(dn.ListrEnquirerPromptAdapter).run({type:"Toggle",message:"Include GitHub Actions workflows and CI/CD?",initial:!0,enabled:"Yes",disabled:"No"}),t.title=e.includeGitHubCI?"Including GitHub CI/CD workflows":"Skipping GitHub CI/CD"}};var Ca={title:"Pulumi stack name",task:async(e,t)=>{if(e.pulumiStackBase){t.title=`Pulumi stack: ${kt.default.bold(e.pulumiStackBase)}`;return}let n=e.githubOwner||"myorg",r=e.projectName?.replace(/[^a-zA-Z0-9-]/g,"-")||"myproject",o=`${n}/${r}`;e.pulumiStackBase=await t.prompt(dn.ListrEnquirerPromptAdapter).run({type:"Input",message:"Enter Pulumi stack base name (org/project)",initial:o,validate:s=>s?.trim()?s.includes("/")?!0:"Format should be org/project (e.g., myorg/myproject)":"Pulumi stack name is required."}),t.title=`Pulumi stack: ${kt.default.bold(e.pulumiStackBase)}`}};var _=require("node:fs"),j=require("node:path");var un=require("node:path");var Wp=()=>{let e=et();return je([(0,un.join)(__dirname,"templates","hono-microservice"),(0,un.join)(__dirname,"..","hono-microservice","templates"),(0,un.join)(e,"bin","templates","hono-microservice")],"Hono templates directory not found.")},vt=(e,t={})=>tn(Wp())(e,t);function xa(){return vt("tsconfig.json.hbs")}function wa(e="1.2.23"){return vt("Dockerfile.hbs",{bunVersion:e})}function ba(){return vt("biome.json.hbs")}function Sa(e){return vt("src/index.ts.hbs",{envKey:gt(e)})}function Pa(e){return vt("src/config/env.ts.hbs",{envKey:gt(e)})}var Gp=async({projectName:e,packageManager:t},n)=>{let r=t==="bun"?"bun":"nodejs";try{await te("create-hono@latest",[e,"--pm",t,"--template",r,"--install"],{task:n})}catch(s){let a=(0,j.join)(g(e),"package.json");if(!(0,_.existsSync)(a))throw new Error(`Failed to scaffold: ${s instanceof Error?s.message:String(s)}`)}let o=(0,j.join)(g(e),"package.json");if(!(0,_.existsSync)(o))throw new Error("Failed to scaffold Hono app structure - package.json not created")},Up=({projectName:e,packageManager:t})=>{let n=(0,j.basename)(e),r=Ee(),o=t==="npm"?"*":"workspace:*",s=g(e),a=na("scripts.dev",s);a&&re("scripts.start:dev",a,e),[{field:"name",value:`${r}/${n}`},{field:"scripts.test",value:"bun test"},{field:"scripts.lint",value:"biome lint --write ./src"},{field:`dependencies.${r}/contracts`,value:o},{field:"dependencies.@crossdelta/telemetry",value:"*"},{field:"dependencies.zod",value:"^4.0.0"},{field:"devDependencies.bun-types",value:"latest",condition:t!=="bun"},{field:"devDependencies.@biomejs/biome",value:"latest"}].filter(({condition:c})=>c??!0).map(({field:c,value:l})=>re(c,l,e))},Jp=({projectName:e})=>{let t=(0,j.basename)(e),n=(0,j.join)(g(e),"src","index.ts"),r=Sa(t);(0,_.writeFileSync)(n,r)},Kp=({projectName:e})=>{let t=(0,j.basename)(e),n=g(e),r=(0,j.join)(n,"src","config");(0,_.existsSync)(r)||(0,_.mkdirSync)(r,{recursive:!0});let o=(0,j.join)(r,"env.ts"),s=Pa(t);(0,_.writeFileSync)(o,s)},zp=({projectName:e})=>{let t=g(e),n=(0,j.join)(t,"tsconfig.json");(0,_.writeFileSync)(n,xa());let r=(0,j.join)(t,"Dockerfile");(0,_.writeFileSync)(r,wa());let o=(0,j.join)(t,"biome.json");(0,_.writeFileSync)(o,ba())},Ta={title:"Create Hono app structure",rendererOptions:{outputBar:1e3},task:async(e,t)=>P(t,async n=>{await Gp(e,t),Up(e),Jp(e),Kp(e),zp(e),e.elapsedTime+=n()})};var qp=e=>{let t=(e||"my-hono-service").trim();return t.includes("/")||t.startsWith(".")?t:`${B().services}/${t}`},Vp=async(e,t)=>{let{valid:n,config:r,error:o}=Ne();if(!n||!r){console.log(o);return}let s=qp(e.name),a=t.packageManager||x(),i=await Ht(t.description);if(Bt(s,r,i),await Wt({servicePath:s,description:i,serviceType:"hono",packageManager:a},r))console.log(oe.default.green.bold(`
|
|
477
|
+
${e.message}`)}},He=()=>z().reduce((t,n)=>(n.initial&&t.push(n.name),t),[]),Kp=e=>!!e?.name&&!!e?.link&&!!e?.description,dn=e=>{let t=z();if(!t?.length||!e?.length)return;let n=e.map(r=>t.find(o=>o.name===r)).filter(Kp);n.length&&(m.breakLine().log("\u{1F50C} Installed Integrations:"),n.forEach(({name:r,link:o,description:s})=>{let a=m.getStoredLogs(`${mn}:${r}`);o&&m.log(`${(0,Pa.default)(te.default.cyan(r),o)} - ${s}`),a.length&&m.log(a.map(i=>` \u203A ${te.default.dim(i.message)}`).join(`
|
|
478
|
+
`))}))},qp=e=>e.toUpperCase().replace(/-/g,"_"),Ta=(e,t)=>{let n=qp(e);m.breakLine().log(te.default.bold("Environment variables:")).log(te.default.dim(" Local:")).log(te.default.cyan(` ${n}_PORT=${t}`)).log(te.default.cyan(` ${n}_URL=http://localhost:${t}`)).breakLine().log(te.default.dim(" Production (auto-configured):")).log(te.default.cyan(` ${n}_PORT=${t}`)).log(te.default.cyan(` ${n}_URL=http://${e}:${t}`))};var Rr=u(require("chalk"));g();var Vp=e=>{let t=e.match(/^(@?[^@]+)@(.+)$/);return t?{name:t[1],version:t[2]}:{name:e,version:"latest"}},Ea=async e=>{let{selectedIntegrations:t,cwd:n,packageManager:r=S(),task:o}=e;if(!t?.length||!o)return;let s=Zp(t,n,r,o);await Lt(o,s)},Zp=(e,t,n,r)=>{let s=z()?.filter(i=>e.includes(i.name))?.flatMap(i=>i.install.map(c=>{let{name:l,version:p}=Vp(c);return{title:Rr.default.cyanBright(`Adding ${c} (${i.name})`),fn:async()=>{V(`dependencies.${l}`,p,t)}}})),a={title:Rr.default.cyanBright("Installing packages..."),fn:async()=>{await Z({cwd:t,packageManager:n,task:r})}};return[...s??[],a]};var $a=u(require("chalk"));g();var Aa=async e=>{let{selectedIntegrations:t,cwd:n,task:r}=e;if(!t?.length||!r)return;let o=Yp(t,n,r,e.packageManager);await Lt(r,o)},Yp=(e,t,n,r)=>z().filter(s=>e.includes(s.name)&&s.run?.length).flatMap(s=>(s.run||[]).map(a=>({title:$a.default.cyanBright(`Running "${a}" for ${s.name}
|
|
479
|
+
`),fn:()=>Xp(s,a,t,n,r)}))),Xp=async(e,t,n,r,o)=>{let s=`${mn}:${e.name}`;try{if(e.interactive)return Ko(t,[],{cwd:n,context:s,task:r,manager:o});await se(t,[],{cwd:n,task:r,context:s})}catch(a){m.error(`Failed to run command "${t}" for ${e.name}: ${a.message}`)}};var un=require("node:fs"),wt=require("node:path");g();var gn=(e,t)=>{try{let n=(0,un.readFileSync)(e,"utf-8"),r=JSON.parse(n);t(r),(0,un.writeFileSync)(e,JSON.stringify(r,null,2),"utf-8")}catch{}},Qp=e=>{let t=(0,wt.join)(f(e),"tsconfig.json");gn(t,n=>{n.compilerOptions.module="ESNext",n.compilerOptions.moduleResolution="bundler",n.compilerOptions.resolvePackageJsonExports=!0,n.compilerOptions.types=n.compilerOptions.types||[],n.compilerOptions.types.includes("bun-types")||n.compilerOptions.types.push("bun-types"),n.exclude=["node_modules","dist"]})},em=e=>{let t=(0,wt.join)(f(e),"tsconfig.build.json");gn(t,n=>{n.exclude=["node_modules","test","dist","**/*.spec.ts","**/*.test.ts"]})},tm=e=>{let t=(0,wt.join)(f(e),"nest-cli.json");gn(t,n=>{n.compilerOptions=n.compilerOptions||{},n.compilerOptions.tsConfigPath="tsconfig.build.json"})},nm=e=>{let t=(0,wt.join)(f(e),"package.json");gn(t,n=>{delete n.jest})},Ia=e=>{Qp(e),em(e),tm(e),nm(e)};var Na=require("node:path");g();var rm=(e,t)=>{let n=vr(e);if(n){for(let{className:r,importPath:o}of t)xr(n,o,[r]),wr(n,r);Cr(n)}},Ra=e=>{let t=(0,Na.join)(f(e),"src","app.module.ts");rm(t,[{className:"EventsModule",importPath:"./events/events.module"}])};var om=require("fs-extra");g();var am=u(require("chalk")),im=u(require("cli-table3"));var Ma=require("node:fs"),ja=require("node:path"),Fa=u(require("handlebars"));var Be=(e,t)=>ms(e,t??`Templates directory not found. Searched in: ${e.join(", ")}`),Mr=(e,t={})=>{let n=(0,Ma.readFileSync)(e,"utf-8");return Fa.default.compile(n)(t)},fn=e=>(t,n={})=>{let r=(0,ja.join)(e,t);return Mr(r,n)};var bt=e=>e.toUpperCase().replace(/-/g,"_");var Oa=e=>e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ");g();function hn(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}async function _a(e,t,n={},r=[],o=[]){if(!e){console.error("Subcommand is not defined.");return}let s=r.map(l=>t[l]).filter(l=>l!==void 0),a=o.map(l=>{let p=t[l];if(!(p===!1||p===void 0))return p===!0?`--${hn(String(l))}`:`--${hn(String(l))}=${String(p)}`}).filter(l=>l!==void 0),i=Object.entries(n).map(([l,p])=>{if(!(p===!1||p===void 0))return p===!0?`--${hn(l)}`:`--${hn(l)}=${String(p)}`}).filter(l=>l!==void 0),c=[...s,...a,...i].map(String);await e.parseAsync(c,{from:"user"})}var oi=require("node:path"),ie=u(require("chalk"));v();var Da=require("@listr2/prompt-adapter-enquirer"),We={title:"Confirm creation",enabled:e=>!e.userConfirmed,task:async(e,t)=>{if(e.userConfirmed=await t.prompt(Da.ListrEnquirerPromptAdapter).run({type:"Toggle",initial:!0,message:"\u{1F680} Ready to launch your project?"}),!e.userConfirmed)throw new Error("Project creation was canceled by the user.")}};var ne=require("node:fs"),Ge=require("node:path");var cm=4001,lm=4e3;function pm(e){let t=[],n=e.matchAll(/ports\(\)\.(?:http|https|grpc|primary)\((\d+)\)/g);for(let c of n)t.push(Number(c[1]));let r=e.matchAll(/\.add(?:Http|Grpc)?\((\d+)/g);for(let c of r)t.push(Number(c[1]));let o=e.match(/containerPort\s*:\s*(\d+)/);o&&t.push(Number(o[1]));let s=e.match(/internalPorts\s*:\s*\[([^\]]+)\]/);if(s){let c=s[1].match(/\d+/g);c&&t.push(...c.map(Number))}let a=e.match(/httpPort\s*:\s*(\d+)/);a&&t.push(Number(a[1]));let i=e.matchAll(/const\s+\w*[pP]ort\w*\s*=\s*(\d+)/g);for(let c of i)t.push(Number(c[1]));return t}function mm(e,t){let n=t?cm:lm,r=new Set;if(!(0,ne.existsSync)(e))return n;let o=(0,ne.readdirSync)(e).filter(a=>a.endsWith(".ts"));for(let a of o){let i=(0,Ge.join)(e,a);try{let c=(0,ne.readFileSync)(i,"utf-8"),l=pm(c);for(let p of l)r.add(p)}catch{}}let s=n;for(;r.has(s);)s++;return s}function dm(e){return(0,Ge.basename)(e)}var yn={title:"Creating infrastructure service config",task:async(e,t)=>{let n=dm(e.projectName),r=y(),o=(0,Ge.join)(r,"infra","services");if(!(0,ne.existsSync)(o)){t.title="Skipping infra config (no infra/services directory found)";return}let s=(0,Ge.join)(o,`${n}.ts`);if((0,ne.existsSync)(s)){t.title=`Service config already exists: infra/services/${n}.ts`;return}let a=mm(o,!0);e.assignedPort=a;let i=e.serviceType==="hono"?xa(n,a):wa(n,a);(0,ne.writeFileSync)(s,i),t.title=`Created infra/services/${n}.ts (port: ${a})`}};var St=require("node:child_process"),La=require("node:fs"),Ha=require("node:path"),um=()=>{try{return(0,St.execSync)("git --version",{stdio:"ignore"}),!0}catch{return!1}},gm=e=>(0,La.existsSync)((0,Ha.join)(e,".git")),Ba={title:"Initializing git repository",enabled:()=>um(),skip:e=>gm(e.cwd)?"Already a git repository":!1,task:async(e,t)=>{try{(0,St.execSync)("git init",{cwd:e.cwd,stdio:"ignore"}),(0,St.execSync)("git add -A",{cwd:e.cwd,stdio:"ignore"}),(0,St.execSync)('git commit -m "chore: initial commit"',{cwd:e.cwd,stdio:"ignore",env:{...process.env,GIT_AUTHOR_NAME:process.env.GIT_AUTHOR_NAME||"Platform SDK",GIT_AUTHOR_EMAIL:process.env.GIT_AUTHOR_EMAIL||"platform-sdk@localhost",GIT_COMMITTER_NAME:process.env.GIT_COMMITTER_NAME||"Platform SDK",GIT_COMMITTER_EMAIL:process.env.GIT_COMMITTER_EMAIL||"platform-sdk@localhost"}}),t.title="Git repository initialized with initial commit"}catch{t.title="Git initialization skipped (git error)"}}};var Wa=require("@listr2/prompt-adapter-enquirer"),jr=u(require("chalk"));g();var Ue={title:"Installing Bun",enabled:e=>!!e.shouldInstallBun&&!Sr(),task:async(e,t)=>T(t,async n=>{await Xs(t),e.elapsedTime+=n(),t.title=`Bun installed successfully. (${e.elapsedTime}s)`})},Je={enabled:e=>!Sr()&&!e.shouldInstallBun&&!e.packageManager,task:async(e,t)=>{e.shouldInstallBun=await t.prompt(Wa.ListrEnquirerPromptAdapter).run({type:"Toggle",message:"Would you like to use Bun? (recommended)",initial:!0,footer:["",`${jr.default.magenta.bold("Bun")} is a fast JavaScript runtime, package manager, bundler, and test runner: ${jr.default.underline("https://bun.sh")}`,Qs(),ea()].join(`
|
|
480
|
+
`)}),e.shouldInstallBun&&(e.packageManager="bun")}};var Ga=require("@listr2/prompt-adapter-enquirer"),Fr=u(require("chalk"));g();var kn={title:"Install integrations",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>T(t,async n=>{let{selectedIntegrations:r,cwd:o,packageManager:s}=e;await Ea({selectedIntegrations:r,packageManager:s,cwd:o,task:t}),e.elapsedTime+=n()}),rendererOptions:{outputBar:1e3}},vn={title:"Select integrations",enabled:e=>e.selectedIntegrations.length===0,task:async(e,t)=>{e.selectedIntegrations=await t.prompt(Ga.ListrEnquirerPromptAdapter).run({type:"MultiSelect",hint:`
|
|
481
|
+
Press <space> to select/deselect, <enter> to confirm, <i> to invert selection`,message:"Which integrations would you like to include?",initial:He().map((n,r)=>r),choices:e.availableIntegrations.map(({name:n,description:r})=>({name:n,message:[Fr.default.bold(n),r].join(" - "),value:n}))}),!e.selectedIntegrations||e.selectedIntegrations.length===0?t.title="No integrations selected.":t.title=["Selected integrations:",...e.selectedIntegrations.map(n=>Fr.default.bold(`\u2022 ${n}`))].join(`
|
|
482
|
+
`)}};g();var Ua={title:"Install Nest CLI",task:async(e,t)=>T(t,async n=>{await zo({packages:["@nestjs/cli"],task:t,cwd:e.cwd}),e.elapsedTime+=n()}),rendererOptions:{outputBar:1e3}};g();var Cn={title:"Install dependencies",task:async(e,t)=>T(t,async n=>{await Z({cwd:e.cwd,task:t,packageManager:e.packageManager}),e.elapsedTime+=n()})};var Ja=require("@listr2/prompt-adapter-enquirer"),za=u(require("chalk"));g();var ze={enabled:e=>!e.removeDir&&!Dt(e.cwd),task:async(e,t)=>{if(e.removeDir=await t.prompt(Ja.ListrEnquirerPromptAdapter).run({type:"Toggle",message:za.default.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}),!e.removeDir)throw new Error("Project creation was canceled by the user.")}},Ke={enabled:e=>!!e.removeDir,task:async e=>To(e.cwd)};g();var xn={title:"Run integration commands",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>T(t,async n=>{let{selectedIntegrations:r,cwd:o}=e;await Aa({selectedIntegrations:r,cwd:o,task:t,packageManager:e.packageManager}),e.elapsedTime+=n()}),rendererOptions:{outputBar:1}};var Ka=require("@listr2/prompt-adapter-enquirer");g();var fm=["services/my-hono-service","services/my-nest-service","my-platform"],qe={enabled:e=>e.skipInputPrompts||e.userConfirmed?!1:e.projectName?fm.includes(e.projectName):!0,task:async(e,t)=>{e.projectName=await t.prompt(Ka.ListrEnquirerPromptAdapter).run({type:"Input",initial:e.projectName,message:"Enter project name",validate:n=>n?!0:"Project name is required."}),e.cwd&&(e.cwd=f(e.projectName))}};var qa=require("@listr2/prompt-adapter-enquirer"),Or=u(require("chalk"));var Ve={title:"Select Package manager",task:async(e,t)=>{if(e.packageManager??=Zn(),e.packageManager){t.title=`Using ${Or.default.bold(e.packageManager)} as package manager.`;return}e.packageManager=await t.prompt(qa.ListrEnquirerPromptAdapter).run({type:"Select",message:"Which package manager would you like to use?",initial:Yn(),choices:Jo}),t.title=`Using ${Or.default.bold(e.packageManager)} as package manager.`}};var wn=require("@listr2/prompt-adapter-enquirer"),Pt=u(require("chalk")),Va={title:"GitHub repository owner",task:async(e,t)=>{if(e.githubOwner){t.title=`GitHub owner: ${Pt.default.bold(e.githubOwner)}`;return}e.githubOwner=await t.prompt(wn.ListrEnquirerPromptAdapter).run({type:"Input",message:"Enter GitHub organization or username",initial:"my-org",validate:n=>n?.trim()?!0:"GitHub owner is required."}),t.title=`GitHub owner: ${Pt.default.bold(e.githubOwner)}`}},Za={title:"Include GitHub CI/CD",task:async(e,t)=>{if(e.includeGitHubCI!==void 0){t.title=e.includeGitHubCI?"Including GitHub CI/CD workflows":"Skipping GitHub CI/CD";return}e.includeGitHubCI=await t.prompt(wn.ListrEnquirerPromptAdapter).run({type:"Toggle",message:"Include GitHub Actions workflows and CI/CD?",initial:!0,enabled:"Yes",disabled:"No"}),t.title=e.includeGitHubCI?"Including GitHub CI/CD workflows":"Skipping GitHub CI/CD"}};var Ya={title:"Pulumi stack name",task:async(e,t)=>{if(e.pulumiStackBase){t.title=`Pulumi stack: ${Pt.default.bold(e.pulumiStackBase)}`;return}let n=e.githubOwner||"myorg",r=e.projectName?.replace(/[^a-zA-Z0-9-]/g,"-")||"myproject",o=`${n}/${r}`;e.pulumiStackBase=await t.prompt(wn.ListrEnquirerPromptAdapter).run({type:"Input",message:"Enter Pulumi stack base name (org/project)",initial:o,validate:s=>s?.trim()?s.includes("/")?!0:"Format should be org/project (e.g., myorg/myproject)":"Pulumi stack name is required."}),t.title=`Pulumi stack: ${Pt.default.bold(e.pulumiStackBase)}`}};g();var B=require("node:fs"),_=require("node:path");g();var bn=require("node:path");var hm=()=>{let e=dt();return Be([(0,bn.join)(__dirname,"templates","hono-microservice"),(0,bn.join)(__dirname,"..","hono-microservice","templates"),(0,bn.join)(e,"bin","templates","hono-microservice")],"Hono templates directory not found.")},Tt=(e,t={})=>fn(hm())(e,t);function Xa(){return Tt("tsconfig.json.hbs")}function Qa(e="1.2.23"){return Tt("Dockerfile.hbs",{bunVersion:e})}function ei(){return Tt("biome.json.hbs")}function ti(e){return Tt("src/index.ts.hbs",{envKey:bt(e)})}function ni(e){return Tt("src/config/env.ts.hbs",{envKey:bt(e)})}var ym=async({projectName:e,packageManager:t},n)=>{let r=t==="bun"?"bun":"nodejs";try{await se("create-hono@latest",[e,"--pm",t,"--template",r,"--install"],{task:n})}catch(s){let a=(0,_.join)(f(e),"package.json");if(!(0,B.existsSync)(a))throw new Error(`Failed to scaffold: ${s instanceof Error?s.message:String(s)}`)}let o=(0,_.join)(f(e),"package.json");if(!(0,B.existsSync)(o))throw new Error("Failed to scaffold Hono app structure - package.json not created")},km=({projectName:e,packageManager:t})=>{let n=(0,_.basename)(e),r=xe(),o=t==="npm"?"*":"workspace:*",s=f(e),a=Un("scripts.dev",s);a&&V("scripts.start:dev",a,e),[{field:"name",value:`${r}/${n}`},{field:"scripts.test",value:"bun test"},{field:"scripts.lint",value:"biome lint --write ./src"},{field:`dependencies.${r}/contracts`,value:o},{field:"dependencies.@crossdelta/telemetry",value:"*"},{field:"dependencies.zod",value:"^4.0.0"},{field:"devDependencies.bun-types",value:"latest",condition:t!=="bun"},{field:"devDependencies.@biomejs/biome",value:"latest"}].filter(({condition:c})=>c??!0).map(({field:c,value:l})=>V(c,l,e))},vm=({projectName:e})=>{let t=(0,_.basename)(e),n=(0,_.join)(f(e),"src","index.ts"),r=ti(t);(0,B.writeFileSync)(n,r)},Cm=({projectName:e})=>{let t=(0,_.basename)(e),n=f(e),r=(0,_.join)(n,"src","config");(0,B.existsSync)(r)||(0,B.mkdirSync)(r,{recursive:!0});let o=(0,_.join)(r,"env.ts"),s=ni(t);(0,B.writeFileSync)(o,s)},xm=({projectName:e})=>{let t=f(e),n=(0,_.join)(t,"tsconfig.json");(0,B.writeFileSync)(n,Xa());let r=(0,_.join)(t,"Dockerfile");(0,B.writeFileSync)(r,Qa());let o=(0,_.join)(t,"biome.json");(0,B.writeFileSync)(o,ei())},ri={title:"Create Hono app structure",rendererOptions:{outputBar:1e3},task:async(e,t)=>T(t,async n=>{await ym(e,t),km(e),vm(e),Cm(e),xm(e),e.elapsedTime+=n()})};var wm=e=>{let t=(e||"my-hono-service").trim();return t.includes("/")||t.startsWith(".")?t:`${E().services}/${t}`},bm=async(e,t)=>{let{valid:n,config:r,error:o}=De();if(!n||!r){console.log(o);return}let s=wm(e.name),a=t.packageManager||S(),i=await tn(t.description);if(nn(s,r,i),await rn({servicePath:s,description:i,serviceType:"hono",packageManager:a},r))console.log(ie.default.green.bold(`
|
|
469
483
|
\u2705 Service generated successfully!
|
|
470
|
-
`)),console.log(
|
|
471
|
-
${
|
|
484
|
+
`)),console.log(ie.default.dim("Next steps:")),console.log(ie.default.dim(` ${ie.default.cyan("pf dev")} - Start all services`)),console.log(ie.default.dim(` ${ie.default.cyan(`cd ${s} && bun dev`)} - Start this service only`)),console.log();else throw new Error("Service generation failed")},si=q({name:"hono-micro",description:"Create a new Hono microservice with the Crossdelta setup. Use --ai for AI-powered generation.",arguments:[["[name]","Name or path of the service"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["--ai","Use AI to generate service code based on a description"],["-d, --description <description>","Service description for AI generation (requires --ai)"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:'platform new hono-micro my-service --ai -d "Payment processing service"',shouldSkipWorkflow:(e,t)=>!!t.ai,onSkipWorkflow:bm,buildContext:async(e,t)=>{let n=(e.name??"my-hono-service").trim();!n.includes("/")&&!n.startsWith(".")&&(n=`${E().services}/${n}`);let r=f(n),o=t.packageManager??(t.yes&&S()),s=z(),a=t.yes?He():[],i=t.packageManager==="bun",c=!!t.yes||!!e.name&&e.name!=="my-hono-service";return{cwd:r,projectName:n,packageManager:o,shouldInstallBun:i,availableIntegrations:s,selectedIntegrations:a,serviceType:"hono",elapsedTime:0,userConfirmed:!!t.yes,skipInputPrompts:c,removeDir:!!t.removeDir||!!t.yes}},prompts:[qe,ze,Je,Ve,vn,We],actions:[Ke,Ue,ri,yn,kn,xn],onComplete:({projectName:e,packageManager:t,selectedIntegrations:n,assignedPort:r})=>{m.breakLine().log(ie.default.bold.green("Hono Microservice created successfully!")),dn(n),Ta((0,oi.basename)(e),r??8080);let o=t??S();m.breakLine().log(`To start the project, run:
|
|
485
|
+
${ie.default.bold(`cd ${e} && ${o} run dev`)}`).breakLine().log("Happy shipping with Hono! \u26A1\uFE0F").breakLine()}});var ce=u(require("chalk"));v();g();var K=require("node:fs"),D=require("node:path");g();var Dr=require("node:path");var Sm=()=>Be([(0,Dr.join)(__dirname,"templates","nest-microservice"),(0,Dr.join)(__dirname,"..","nest-microservice","templates")],"NestJS templates directory not found."),Ze=(e,t={})=>fn(Sm())(e,t);function Sn(e,t=3e3){return Ze("src/main.ts.hbs",{serviceName:e,envKey:bt(e),displayName:Oa(e),defaultPort:t})}function ai(){return Ze("src/app.context.ts.hbs",{})}function ii(){return Ze("src/events/events.module.ts.hbs",{})}function ci(e){return Ze("src/events/events.service.ts.hbs",{serviceName:e})}function li(e="24",t="1.2.23"){return Ze("Dockerfile.hbs",{nodeVersion:e,bunVersion:t})}function pi(){return Ze("biome.json.hbs",{})}var Pm=async(e,t)=>{await se("@nestjs/cli",["new",e.projectName,"--skip-install","--skip-git","--package-manager",e.packageManager],{task:t})},Tm=({projectName:e,packageManager:t})=>{let n=(0,D.basename)(e),r=xe(),o=t==="npm"?"*":"workspace:*";[{field:"name",value:`${r}/${n}`},{field:"type",value:"module"},{field:"scripts.start",value:"bun src/main.ts"},{field:"scripts.start:dev",value:"bun --hot src/main.ts"},{field:"scripts.start:prod",value:"node dist/main.js"},{field:"scripts.test",value:"bun test"},{field:"scripts.lint",value:"biome lint --write ./src"},{field:`dependencies.${r}/contracts`,value:o},{field:"dependencies.@crossdelta/telemetry",value:"*"},{field:"dependencies.@nestjs/config",value:"^4"},{field:"devDependencies.bun-types",value:"latest"},{field:"devDependencies.@biomejs/biome",value:"latest"}].map(({field:i,value:c})=>V(i,c,e)),["jest","@types/jest","ts-jest","@nestjs/testing","supertest","@types/supertest","ts-node","tsconfig-paths","@nestjs/schematics","@nestjs/cli"].map(i=>V(`devDependencies.${i}`,void 0,e))},Em=({projectName:e})=>{let t=["eslint.config.mjs","src/app.controller.spec.ts"];for(let n of t)try{(0,K.unlinkSync)((0,D.join)(f(e),n))}catch{}},$m=({projectName:e})=>{let t=f(e),n=(0,D.join)(t,"Dockerfile");(0,K.writeFileSync)(n,li());let r=(0,D.join)(t,"biome.json");(0,K.writeFileSync)(r,pi())},Am=({projectName:e})=>{let t=(0,D.join)(f(e),"src","app.context.ts");(0,K.writeFileSync)(t,ai())},Im=({projectName:e})=>{let t=(0,D.basename)(e),n=(0,D.join)(f(e),"src","events");(0,K.mkdirSync)(n,{recursive:!0}),(0,K.writeFileSync)((0,D.join)(n,"events.module.ts"),ii()),(0,K.writeFileSync)((0,D.join)(n,"events.service.ts"),ci(t)),Ra(e)},Nm=({projectName:e})=>{let t=(0,D.basename)(e),n=(0,D.join)(f(e),"src","main.ts");(0,K.writeFileSync)(n,Sn(t))},mi={title:"Create NestJS app structure",rendererOptions:{outputBar:1e3},task:async(e,t)=>T(t,async n=>{await Pm(e,t),Tm(e),Ia(e.projectName),Em(e),$m(e),Am(e),Im(e),Nm(e),e.elapsedTime+=n()})};var di=require("node:fs"),Pn=require("node:path");g();var ui={title:"Patch main.ts with PORT pattern",task:async(e,t)=>T(t,async n=>{let r=(0,Pn.basename)(e.projectName),o=e.assignedPort??3e3,s=(0,Pn.join)(f(e.projectName),"src","main.ts");(0,di.writeFileSync)(s,Sn(r,o)),t.title=`Patched main.ts with PORT || ${r.toUpperCase().replace(/-/g,"_")}_PORT`,e.elapsedTime+=n()})};var Rm=e=>{let t=(e||"my-nest-service").trim();return t.includes("/")||t.startsWith(".")?t:`${E().services}/${t}`},Mm=async(e,t)=>{let{valid:n,config:r,error:o}=De();if(!n||!r){console.log(o);return}let s=Rm(e.name),a=t.packageManager||S(),i=await tn(t.description);if(nn(s,r,i),await rn({servicePath:s,description:i,serviceType:"nest",packageManager:a},r))console.log(ce.default.green.bold(`
|
|
472
486
|
\u2705 Service generated successfully!
|
|
473
|
-
`)),console.log(
|
|
474
|
-
${se.default.bold(`cd ${e} && ${t} run start:dev`)}`).breakLine().log("Happy coding! \u{1F389}").breakLine()}});var za=require("@listr2/prompt-adapter-enquirer"),D=u(require("chalk"));var Ba=require("node:child_process"),A=require("node:fs"),Je=require("node:path");var Da=require("node:fs"),Ct=require("node:path");var wr=()=>{let e=et();return je([(0,Ct.join)(__dirname,"templates","workspace"),(0,Ct.join)(__dirname,"..","..","..","..","templates","workspace"),(0,Ct.join)(e,"bin","templates","workspace")],"Workspace templates directory not found.")},La=()=>{let e=wr(),t=(0,Ct.join)(e,"packages","contracts");if(!(0,Da.existsSync)(t))throw new Error(`Contracts templates directory not found at: ${t}`);return t},hn=(e,t)=>ur(e,t);var Ha=e=>{e.endsWith(".sh")&&(0,A.chmodSync)(e,493)},am=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"pnpm-workspace.yaml.hbs",output:"pnpm-workspace.yaml",forPackageManager:"pnpm"},{template:"biome.json.hbs",output:"biome.json"},{template:"turbo.json.hbs",output:"turbo.json"},{template:"bunfig.toml.hbs",output:"bunfig.toml"},{template:"gitignore.hbs",output:".gitignore"},{template:"editorconfig.hbs",output:".editorconfig"},{template:"npmrc.hbs",output:".npmrc"},{template:".vscode/settings.json",output:".vscode/settings.json",isStatic:!0},{template:".vscode/extensions.json",output:".vscode/extensions.json",isStatic:!0},{template:"infra/package.json.hbs",output:"infra/package.json"},{template:"infra/index.ts.hbs",output:"infra/index.ts"},{template:"infra/tsconfig.json.hbs",output:"infra/tsconfig.json"},{template:"infra/Pulumi.yaml.hbs",output:"infra/Pulumi.yaml"},{template:"infra/Pulumi.dev.yaml.hbs",output:"infra/Pulumi.dev.yaml"},{template:"apps/.gitkeep",output:"apps/.gitkeep",isStatic:!0},{template:"services/.gitkeep",output:"services/.gitkeep",isStatic:!0},{template:"packages/.gitkeep",output:"packages/.gitkeep",isStatic:!0},{template:"docs/.gitkeep",output:"docs/.gitkeep",isStatic:!0},{template:"infra/services/.gitkeep",output:"infra/services/.gitkeep",isStatic:!0},{template:".github/README.md",output:".github/README.md",isStatic:!0,isGitHubCI:!0},{template:".github/dependabot.yml",output:".github/dependabot.yml",isStatic:!0,isGitHubCI:!0},{template:".github/workflows/lint-and-tests.yml.hbs",output:".github/workflows/lint-and-tests.yml",isGitHubCI:!0},{template:".github/workflows/build-and-deploy.yml.hbs",output:".github/workflows/build-and-deploy.yml",isGitHubCI:!0},{template:".github/workflows/publish-packages.yml",output:".github/workflows/publish-packages.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/setup-bun-install/action.yml.hbs",output:".github/actions/setup-bun-install/action.yml",isGitHubCI:!0},{template:".github/actions/check-image-tag-exists/action.yml",output:".github/actions/check-image-tag-exists/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-image-tag-exists/index.js",output:".github/actions/check-image-tag-exists/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-path-changes/action.yml",output:".github/actions/check-path-changes/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-path-changes/index.js",output:".github/actions/check-path-changes/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/detect-skipped-services/action.yml",output:".github/actions/detect-skipped-services/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/action.yml",output:".github/actions/generate-scope-matrix/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/index.js",output:".github/actions/generate-scope-matrix/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/prepare-build-context/action.yml",output:".github/actions/prepare-build-context/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/resolve-scope-tags/action.yml",output:".github/actions/resolve-scope-tags/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/resolve-scope-tags/index.js",output:".github/actions/resolve-scope-tags/index.js",isStatic:!0,isGitHubCI:!0}],Wa={title:"Creating workspace structure",task:async(e,t)=>{if((0,A.existsSync)(e.cwd)){t.title="Workspace directory already exists, skipping...";return}let n=wr(),r=e.includeGitHubCI??!0,o=e.packageManager||"bun",s=c=>{try{let d=(0,Ba.spawnSync)(c,["--version"],{encoding:"utf-8",timeout:5e3}).stdout?.trim();if(d&&/^\d+\.\d+/.test(d))return`${c}@${d}`}catch{}return{bun:"bun@1.2.7",npm:"npm@10.9.2",yarn:"yarn@4.6.0",pnpm:"pnpm@9.15.2"}[c]||`${c}@latest`},a={projectName:e.projectName,scope:`@${e.projectName}`,githubOwner:e.githubOwner||"",pulumiStackBase:e.pulumiStackBase||e.projectName,packageManager:o,packageManagerVersion:s(o)},i=am.filter(c=>!(c.isGitHubCI&&!r||c.forPackageManager&&c.forPackageManager!==o));for(let c of i){let l=(0,Je.join)(e.cwd,c.output),p=(0,Je.dirname)(l);if((0,A.existsSync)(p)||(0,A.mkdirSync)(p,{recursive:!0}),c.isStatic){let d=(0,Je.join)(n,c.template);(0,A.existsSync)(d)?(0,A.writeFileSync)(l,(0,A.readFileSync)(d)):(0,A.writeFileSync)(l,""),Ha(l)}else{let d=(0,Je.join)(n,c.template),k=hn(d,a);(0,A.writeFileSync)(l,k),Ha(l)}}t.title="Workspace structure created"}};var X=require("node:fs"),xt=require("node:path"),Ga=u(require("chalk"));var im=()=>{let e=(0,xt.join)(process.cwd(),"package.json");if(!(0,X.existsSync)(e))throw new Error("Root package.json not found. Please run this command from the workspace root.");let n=JSON.parse((0,X.readFileSync)(e,"utf-8")).name;if(!n)throw new Error('package.json must have a "name" field');return n.startsWith("@")?n:`@${n}`},cm=()=>{let e=im(),{relativePath:t,packagePath:n}=C();if((0,X.existsSync)(n))throw new Error(`${t} already exists. Remove it first if you want to regenerate.`);let r=La(),o={scope:e,workspaceName:e.replace("@","").replace("/","-")};(0,X.mkdirSync)(n,{recursive:!0}),(0,X.mkdirSync)((0,xt.join)(n,"src","events"),{recursive:!0});let s=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"README.md.hbs",output:"README.md"},{template:"src/index.ts",output:"src/index.ts"},{template:"src/stream-policies.ts.hbs",output:"src/stream-policies.ts"},{template:"src/events/index.ts",output:"src/events/index.ts"}];for(let a of s){let i=(0,xt.join)(r,a.template),c=(0,xt.join)(n,a.output),l=hn(i,o);(0,X.writeFileSync)(c,l,"utf-8")}},Ua={title:"Initializing contracts package",task:(e,t)=>{let n=process.cwd();try{process.chdir(e.cwd),cm(),t.title="Contracts package initialized"}catch(r){throw t.title=Ga.default.red(`Contracts package failed: ${r.message}`),r}finally{process.chdir(n)}}};var Ja=u(require("chalk"));var Ka={title:"Registering shell completion",task:(e,t)=>{let n=process.cwd();try{process.chdir(e.cwd),ye(),t.title="Shell completion registered"}catch{t.title=Ja.default.dim("Shell completion skipped")}finally{process.chdir(n)}}};var qa=me({name:"workspace",description:"Create a new workspace with infrastructure setup",arguments:[["[name]","Name or path of the workspace"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["-o, --github-owner <owner>","GitHub organization or username"],["-s, --pulumi-stack <name>","Pulumi stack base name (org/project)"],["--no-github","Skip GitHub CI/CD workflows"],["--remove-dir","Remove existing directory before creating (internal use)"]],exampleUsage:"pf new workspace my-platform -o my-org",buildContext:(e,t)=>{let n=(e.name??"my-platform").trim(),r=g(n),o=!!t.yes,s=t.packageManager??(o?x():void 0),a=t.packageManager==="bun",i=t.githubOwner??(o?"my-org":void 0),c=t.pulumiStack??(o?`${i}/${n}`:void 0),l=t.github===!1?!1:o?!0:void 0,p=!!e.name,d=t.removeDir||o;return{cwd:r,projectName:n,shouldInstallBun:a,packageManager:s,elapsedTime:0,userConfirmed:o,skipInputPrompts:p&&!o,removeDir:d,githubOwner:i,pulumiStackBase:c,includeGitHubCI:l}},prompts:[{enabled:e=>!e.userConfirmed,task:async(e,t)=>{try{let n=y();if(!await t.prompt(za.ListrEnquirerPromptAdapter).run({type:"toggle",message:`\u26A0\uFE0F You are inside an existing workspace (${n}). Create a nested workspace anyway?`,enabled:"Yes",disabled:"No",initial:!1}))throw new Error("Workspace creation cancelled - already inside a workspace");t.title=D.default.yellow("Warning: Creating nested workspace")}catch(n){if(n.message?.includes("cancelled"))throw n;t.title="No existing workspace detected"}}},We,He,ka,va,Ca,Le,Ge,Oe],actions:[Be,De,Wa,Ua,pn,pa,Ka],onComplete:({projectName:e,includeGitHubCI:t})=>{m.breakLine().log(D.default.bold.green("Workspace created successfully!")),m.breakLine().log(D.default.bold("Next steps:")).log(` 1. ${D.default.cyan(`cd ${e}`)}`).log(` 2. ${D.default.cyan("exec $SHELL")} ${D.default.dim("(enable tab completion)")}`),t&&m.breakLine().log(D.default.bold("GitHub Setup:")).log(" Configure these secrets in your GitHub repository:").log(` \u2022 ${D.default.yellow("PULUMI_ACCESS_TOKEN")} - Pulumi Cloud access token`).log(` \u2022 ${D.default.yellow("DIGITALOCEAN_TOKEN")} - DigitalOcean API token`).log(` \u2022 ${D.default.yellow("NPM_TOKEN")} - (optional) NPM token for private packages`),m.breakLine().log(D.default.bold("Structure created:")).log(" apps/ # Frontend applications").log(" services/ # Backend microservices").log(" packages/").log(" \u2514\u2500\u2500 contracts/ # Shared event contracts").log(" infra/").log(" \u251C\u2500\u2500 index.ts # Pulumi entry point").log(" \u251C\u2500\u2500 services/ # Service configs").log(" \u251C\u2500\u2500 Pulumi.yaml # Pulumi project config").log(" \u2514\u2500\u2500 Pulumi.dev.yaml # Dev stack config"),t&&m.log(" .github/").log(" \u251C\u2500\u2500 workflows/ # CI/CD workflows").log(" \u2514\u2500\u2500 actions/ # Custom actions"),m.breakLine().log("Happy coding! \u{1F389}").breakLine()}});var wt=[{name:"Hono Microservice",value:"hono-micro",command:Ea,supportsAi:!0},{name:"Nest Microservice",value:"nest-micro",command:_a,supportsAi:!0},{name:"Workspace (Infrastructure)",value:"workspace",command:qa,supportsAi:!1}],Va=()=>{let e=me({name:"new",description:"Create a new project",arguments:[["[type]","Type of the project (e.g., nest-micro, hono-micro, workspace)"]],exampleUsage:"platform new hono-micro test-service",buildContext:t=>({projectType:t.type??"",useAi:!1,aiDescription:"",elapsedTime:0,cwd:process.cwd()}),prompts:[{enabled:t=>!t.projectType,task:async(t,n)=>{let r=await n.prompt(de.ListrEnquirerPromptAdapter).run({type:"select",message:"Select Project type",choices:wt});t.projectType=wt.find(o=>o.name===r)?.value||"",n.title=`Using ${ae.default.bold(r)}`}},{enabled:t=>t.projectType!=="workspace"&&t.projectType!=="",task:async(t,n)=>{try{y(),n.title="Workspace detected"}catch{let r=["Not in a workspace directory","",`Current directory: ${process.cwd()}`,"","This command must be run from within a workspace created with pf new workspace","","To create a new workspace, run:",""," pf new workspace my-platform"].join(`
|
|
475
|
-
`);throw new Error(r)}}},{enabled:t=>t.projectType==="workspace",task:async(t,n)=>{try{let r=y();if(!await n.prompt(
|
|
476
|
-
`),
|
|
487
|
+
`)),console.log(ce.default.dim("Next steps:")),console.log(ce.default.dim(` ${ce.default.cyan("pf dev")} - Start all services`)),console.log(ce.default.dim(` ${ce.default.cyan(`cd ${s} && bun run start:dev`)} - Start this service only`)),console.log();else throw new Error("Service generation failed")},gi=q({name:"nest-micro",description:"Create a new NestJS microservice with the Crossdelta setup. Use --ai for AI-powered generation.",arguments:[["[name]","Name or path of the service"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["--ai","Use AI to generate service code based on a description"],["-d, --description <description>","Service description for AI generation (requires --ai)"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:'platform new nest-micro my-service --ai -d "User authentication service"',shouldSkipWorkflow:(e,t)=>!!t.ai,onSkipWorkflow:Mm,buildContext:async(e,t)=>{let n=(e.name??"my-nest-service").trim();!n.includes("/")&&!n.startsWith(".")&&(n=`${E().services}/${n}`);let r=f(n),o=t.packageManager??(t.yes&&S()),s=t.packageManager==="bun",a=z(),i=t.yes?He():[],c=!!t.yes||!!e.name;return{cwd:r,projectName:n,shouldInstallBun:s,packageManager:o,availableIntegrations:a,selectedIntegrations:i,serviceType:"nest",elapsedTime:0,userConfirmed:!!t.yes,skipInputPrompts:c,removeDir:!!t.removeDir||!!t.yes}},prompts:[qe,ze,Je,Ve,vn,We],actions:[Ke,Ue,mi,yn,ui,Cn,Ua,kn,xn],onComplete:({projectName:e,packageManager:t,selectedIntegrations:n})=>{m.breakLine().log(ce.default.bold.green("NestJS Microservice created successfully!")),dn(n),m.breakLine().log(`To start the project, run:
|
|
488
|
+
${ce.default.bold(`cd ${e} && ${t} run start:dev`)}`).breakLine().log("Happy coding! \u{1F389}").breakLine()}});var Si=require("@listr2/prompt-adapter-enquirer"),W=u(require("chalk"));g();var ki=require("node:child_process"),F=require("node:fs"),Ye=require("node:path");var fi=require("node:fs"),Et=require("node:path");var Lr=()=>{let e=dt();return Be([(0,Et.join)(__dirname,"templates","workspace"),(0,Et.join)(__dirname,"..","..","..","..","templates","workspace"),(0,Et.join)(e,"bin","templates","workspace")],"Workspace templates directory not found.")},hi=()=>{let e=Lr(),t=(0,Et.join)(e,"packages","contracts");if(!(0,fi.existsSync)(t))throw new Error(`Contracts templates directory not found at: ${t}`);return t},Tn=(e,t)=>Mr(e,t);var yi=e=>{e.endsWith(".sh")&&(0,F.chmodSync)(e,493)},jm=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"pnpm-workspace.yaml.hbs",output:"pnpm-workspace.yaml",forPackageManager:"pnpm"},{template:"biome.json.hbs",output:"biome.json"},{template:"turbo.json.hbs",output:"turbo.json"},{template:"bunfig.toml.hbs",output:"bunfig.toml"},{template:"gitignore.hbs",output:".gitignore"},{template:"editorconfig.hbs",output:".editorconfig"},{template:"npmrc.hbs",output:".npmrc"},{template:".vscode/settings.json",output:".vscode/settings.json",isStatic:!0},{template:".vscode/extensions.json",output:".vscode/extensions.json",isStatic:!0},{template:"infra/package.json.hbs",output:"infra/package.json"},{template:"infra/index.ts.hbs",output:"infra/index.ts"},{template:"infra/tsconfig.json.hbs",output:"infra/tsconfig.json"},{template:"infra/Pulumi.yaml.hbs",output:"infra/Pulumi.yaml"},{template:"infra/Pulumi.dev.yaml.hbs",output:"infra/Pulumi.dev.yaml"},{template:"apps/.gitkeep",output:"apps/.gitkeep",isStatic:!0},{template:"services/.gitkeep",output:"services/.gitkeep",isStatic:!0},{template:"packages/.gitkeep",output:"packages/.gitkeep",isStatic:!0},{template:"docs/.gitkeep",output:"docs/.gitkeep",isStatic:!0},{template:"infra/services/.gitkeep",output:"infra/services/.gitkeep",isStatic:!0},{template:".github/README.md",output:".github/README.md",isStatic:!0,isGitHubCI:!0},{template:".github/dependabot.yml",output:".github/dependabot.yml",isStatic:!0,isGitHubCI:!0},{template:".github/workflows/lint-and-tests.yml.hbs",output:".github/workflows/lint-and-tests.yml",isGitHubCI:!0},{template:".github/workflows/build-and-deploy.yml.hbs",output:".github/workflows/build-and-deploy.yml",isGitHubCI:!0},{template:".github/workflows/publish-packages.yml",output:".github/workflows/publish-packages.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/setup-bun-install/action.yml.hbs",output:".github/actions/setup-bun-install/action.yml",isGitHubCI:!0},{template:".github/actions/check-image-tag-exists/action.yml",output:".github/actions/check-image-tag-exists/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-image-tag-exists/index.js",output:".github/actions/check-image-tag-exists/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-path-changes/action.yml",output:".github/actions/check-path-changes/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-path-changes/index.js",output:".github/actions/check-path-changes/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/detect-skipped-services/action.yml",output:".github/actions/detect-skipped-services/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/action.yml",output:".github/actions/generate-scope-matrix/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/index.js",output:".github/actions/generate-scope-matrix/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/prepare-build-context/action.yml",output:".github/actions/prepare-build-context/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/resolve-scope-tags/action.yml",output:".github/actions/resolve-scope-tags/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/resolve-scope-tags/index.js",output:".github/actions/resolve-scope-tags/index.js",isStatic:!0,isGitHubCI:!0}],vi={title:"Creating workspace structure",task:async(e,t)=>{if((0,F.existsSync)(e.cwd)){t.title="Workspace directory already exists, skipping...";return}let n=Lr(),r=e.includeGitHubCI??!0,o=e.packageManager||"bun",s=c=>{try{let d=(0,ki.spawnSync)(c,["--version"],{encoding:"utf-8",timeout:5e3}).stdout?.trim();if(d&&/^\d+\.\d+/.test(d))return`${c}@${d}`}catch{}return{bun:"bun@1.2.7",npm:"npm@10.9.2",yarn:"yarn@4.6.0",pnpm:"pnpm@9.15.2"}[c]||`${c}@latest`},a={projectName:e.projectName,scope:`@${e.projectName}`,githubOwner:e.githubOwner||"",pulumiStackBase:e.pulumiStackBase||e.projectName,packageManager:o,packageManagerVersion:s(o)},i=jm.filter(c=>!(c.isGitHubCI&&!r||c.forPackageManager&&c.forPackageManager!==o));for(let c of i){let l=(0,Ye.join)(e.cwd,c.output),p=(0,Ye.dirname)(l);if((0,F.existsSync)(p)||(0,F.mkdirSync)(p,{recursive:!0}),c.isStatic){let d=(0,Ye.join)(n,c.template);(0,F.existsSync)(d)?(0,F.writeFileSync)(l,(0,F.readFileSync)(d)):(0,F.writeFileSync)(l,""),yi(l)}else{let d=(0,Ye.join)(n,c.template),C=Tn(d,a);(0,F.writeFileSync)(l,C),yi(l)}}t.title="Workspace structure created"}};var re=require("node:fs"),$t=require("node:path"),Ci=u(require("chalk"));v();var Fm=()=>{let e=(0,$t.join)(process.cwd(),"package.json");if(!(0,re.existsSync)(e))throw new Error("Root package.json not found. Please run this command from the workspace root.");let n=JSON.parse((0,re.readFileSync)(e,"utf-8")).name;if(!n)throw new Error('package.json must have a "name" field');return n.startsWith("@")?n:`@${n}`},Om=()=>{let e=Fm(),{relativePath:t,packagePath:n}=x();if((0,re.existsSync)(n))throw new Error(`${t} already exists. Remove it first if you want to regenerate.`);let r=hi(),o={scope:e,workspaceName:e.replace("@","").replace("/","-")};(0,re.mkdirSync)(n,{recursive:!0}),(0,re.mkdirSync)((0,$t.join)(n,"src","events"),{recursive:!0});let s=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"README.md.hbs",output:"README.md"},{template:"src/index.ts",output:"src/index.ts"},{template:"src/stream-policies.ts.hbs",output:"src/stream-policies.ts"},{template:"src/events/index.ts",output:"src/events/index.ts"}];for(let a of s){let i=(0,$t.join)(r,a.template),c=(0,$t.join)(n,a.output),l=Tn(i,o);(0,re.writeFileSync)(c,l,"utf-8")}},xi={title:"Initializing contracts package",task:(e,t)=>{let n=process.cwd();try{process.chdir(e.cwd),Om(),t.title="Contracts package initialized"}catch(r){throw t.title=Ci.default.red(`Contracts package failed: ${r.message}`),r}finally{process.chdir(n)}}};var wi=u(require("chalk"));var bi={title:"Registering shell completion",task:async(e,t)=>{let n=process.cwd();try{process.chdir(e.cwd),await fe(),t.title="Shell completion registered"}catch{t.title=wi.default.dim("Shell completion skipped")}finally{process.chdir(n)}}};var Pi=q({name:"workspace",description:"Create a new workspace with infrastructure setup",arguments:[["[name]","Name or path of the workspace"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["-o, --github-owner <owner>","GitHub organization or username"],["-s, --pulumi-stack <name>","Pulumi stack base name (org/project)"],["--no-github","Skip GitHub CI/CD workflows"],["--remove-dir","Remove existing directory before creating (internal use)"]],exampleUsage:"pf new workspace my-platform -o my-org",buildContext:(e,t)=>{let n=(e.name??"my-platform").trim(),r=f(n),o=!!t.yes,s=t.packageManager??(o?S():void 0),a=t.packageManager==="bun",i=t.githubOwner??(o?"my-org":void 0),c=t.pulumiStack??(o?`${i}/${n}`:void 0),l=t.github===!1?!1:o?!0:void 0,p=!!e.name,d=t.removeDir||o;return{cwd:r,projectName:n,shouldInstallBun:a,packageManager:s,elapsedTime:0,userConfirmed:o,skipInputPrompts:p&&!o,removeDir:d,githubOwner:i,pulumiStackBase:c,includeGitHubCI:l}},prompts:[{enabled:e=>!e.userConfirmed,task:async(e,t)=>{try{let n=y();if(!await t.prompt(Si.ListrEnquirerPromptAdapter).run({type:"toggle",message:`\u26A0\uFE0F You are inside an existing workspace (${n}). Create a nested workspace anyway?`,enabled:"Yes",disabled:"No",initial:!1}))throw new Error("Workspace creation cancelled - already inside a workspace");t.title=W.default.yellow("Warning: Creating nested workspace")}catch(n){if(n.message?.includes("cancelled"))throw n;t.title="No existing workspace detected"}}},qe,ze,Va,Za,Ya,Je,Ve,We],actions:[Ke,Ue,vi,xi,Cn,Ba,bi],onComplete:({projectName:e,includeGitHubCI:t})=>{m.breakLine().log(W.default.bold.green("Workspace created successfully!")),m.breakLine().log(W.default.bold("Next steps:")).log(` 1. ${W.default.cyan(`cd ${e}`)}`).log(` 2. ${W.default.cyan("exec $SHELL")} ${W.default.dim("(enable tab completion)")}`),t&&m.breakLine().log(W.default.bold("GitHub Setup:")).log(" Configure these secrets in your GitHub repository:").log(` \u2022 ${W.default.yellow("PULUMI_ACCESS_TOKEN")} - Pulumi Cloud access token`).log(` \u2022 ${W.default.yellow("DIGITALOCEAN_TOKEN")} - DigitalOcean API token`).log(` \u2022 ${W.default.yellow("NPM_TOKEN")} - (optional) NPM token for private packages`),m.breakLine().log(W.default.bold("Structure created:")).log(" apps/ # Frontend applications").log(" services/ # Backend microservices").log(" packages/").log(" \u2514\u2500\u2500 contracts/ # Shared event contracts").log(" infra/").log(" \u251C\u2500\u2500 index.ts # Pulumi entry point").log(" \u251C\u2500\u2500 services/ # Service configs").log(" \u251C\u2500\u2500 Pulumi.yaml # Pulumi project config").log(" \u2514\u2500\u2500 Pulumi.dev.yaml # Dev stack config"),t&&m.log(" .github/").log(" \u251C\u2500\u2500 workflows/ # CI/CD workflows").log(" \u2514\u2500\u2500 actions/ # Custom actions"),m.breakLine().log("Happy coding! \u{1F389}").breakLine()}});var At=[{name:"Hono Microservice",value:"hono-micro",command:si,supportsAi:!0},{name:"Nest Microservice",value:"nest-micro",command:gi,supportsAi:!0},{name:"Workspace (Infrastructure)",value:"workspace",command:Pi,supportsAi:!1}],Ti=()=>{let e=q({name:"new",description:"Create a new project",arguments:[["[type]","Type of the project (e.g., nest-micro, hono-micro, workspace)"]],exampleUsage:"platform new hono-micro test-service",buildContext:t=>({projectType:t.type??"",useAi:!1,aiDescription:"",elapsedTime:0,cwd:process.cwd()}),prompts:[{enabled:t=>!t.projectType,task:async(t,n)=>{let r=await n.prompt(he.ListrEnquirerPromptAdapter).run({type:"select",message:"Select Project type",choices:At});t.projectType=At.find(o=>o.name===r)?.value||"",n.title=`Using ${le.default.bold(r)}`}},{enabled:t=>t.projectType!=="workspace"&&t.projectType!=="",task:async(t,n)=>{try{y(),n.title="Workspace detected"}catch{let r=["Not in a workspace directory","",`Current directory: ${process.cwd()}`,"","This command must be run from within a workspace created with pf new workspace","","To create a new workspace, run:",""," pf new workspace my-platform"].join(`
|
|
489
|
+
`);throw new Error(r)}}},{enabled:t=>t.projectType==="workspace",task:async(t,n)=>{try{let r=y();if(!await n.prompt(he.ListrEnquirerPromptAdapter).run({type:"toggle",message:`\u26A0\uFE0F You are inside an existing workspace (${r}). Create a nested workspace anyway?`,enabled:"Yes",disabled:"No",initial:!1}))throw new Error("Workspace creation cancelled - already inside a workspace");n.title=le.default.yellow("Warning: Creating nested workspace")}catch(r){if(r.message?.includes("cancelled"))throw r;n.title="No existing workspace detected"}}},{enabled:t=>!!t.projectType,task:async(t,n)=>{let o={"hono-micro":"services/my-hono-service","nest-micro":"services/my-nest-service",workspace:"my-platform"}[t.projectType]||"my-project",s=t.projectType==="workspace"?"\u{1F4E6} Workspace name:":"\u{1F4E6} Service path (e.g., services/my-service):",a=await n.prompt(he.ListrEnquirerPromptAdapter).run({type:"input",message:s,initial:o});t.servicePath=a.trim(),n.title=`Path: ${le.default.dim(a)}`}},{enabled:t=>!!At.find(r=>r.value===t.projectType)?.supportsAi&&De().valid,task:async(t,n)=>{let r=await n.prompt(he.ListrEnquirerPromptAdapter).run({type:"toggle",message:"Use AI to generate service code?",enabled:"Yes",disabled:"No",initial:!1});t.useAi=r,n.title=r?le.default.cyan("\u{1F916} AI-powered generation"):"Standard scaffolding"}},{enabled:t=>t.useAi,task:async(t,n)=>{let r=await n.prompt(he.ListrEnquirerPromptAdapter).run({type:"input",message:"Describe what this service should do:"});t.aiDescription=r,n.title=`Description: ${le.default.dim(r.slice(0,50))}${r.length>50?"...":""}`}},{enabled:t=>{if(!t.servicePath)return!1;let n=f(t.servicePath);return!Dt(n)},task:async(t,n)=>{if(!await n.prompt(he.ListrEnquirerPromptAdapter).run({type:"toggle",message:le.default.bold("\u26A0\uFE0F Overwrite existing directory?"),enabled:"Yes",disabled:"No",initial:!1}))throw new Error("Project creation was canceled by the user.");t.shouldRemoveDir=!0,n.title=le.default.yellow("Will overwrite existing directory")}},{title:"Confirm creation",enabled:t=>t.projectType!=="workspace",task:async(t,n)=>{if(!await n.prompt(he.ListrEnquirerPromptAdapter).run({type:"Toggle",initial:!0,message:"\u{1F680} Ready to launch your project?"}))throw new Error("Project creation was canceled by the user.")}}],actions:[],onComplete:async t=>{At.find(s=>s.value===t.projectType)||e.error(le.default.red(`Project type ${t.projectType} is not supported.`));let n=e.commands.find(s=>s.name()===t.projectType),r={};t.projectType!=="workspace"&&(r.yes=!0);let o=[];t.servicePath&&o.push("servicePath"),t.shouldRemoveDir&&(r.removeDir=!0),t.useAi&&(r.ai=!0,r.description=t.aiDescription),await _a(n,t,r,o)}});for(let t of At)e.addCommand(t.command);return e};var Ai=require("commander");g();var pe=require("node:fs"),It=require("node:path");v();var _m=e=>{let t=(0,It.join)(e,"infra","services");if(!(0,pe.existsSync)(t))return[];let n=(0,pe.readdirSync)(t).filter(i=>i.endsWith(".ts")&&i!=="index.ts").map(i=>i.replace(".ts","")),r=E(e),o=i=>{let c=(0,It.join)(e,i);return(0,pe.existsSync)(c)?(0,pe.readdirSync)(c).filter(l=>(0,pe.existsSync)((0,It.join)(c,l,"package.json"))):[]},s=[...o(r.services),...o(r.apps)],a=n.filter(i=>!s.includes(i));for(let i of a)(0,pe.unlinkSync)((0,It.join)(t,`${i}.ts`));return a},Hr=async e=>{let t=_m(e);t.length>0&&console.log(`\u{1F9F9} Cleaned ${t.length} orphaned infra config(s): ${t.join(", ")}`),await Z({cwd:e,quiet:!0}),await it("generate-env",{cwd:e})},Br=async e=>{await va()&&await Ca(e)};var Wr=u(require("chalk"));Rt();var Gr=e=>new Promise(t=>setTimeout(t,e)),Ei=e=>process.stdout.write(`${e}
|
|
490
|
+
`),Dm=()=>{process.stdout.write("\x1B[2J\x1B[3J\x1B[H"),process.stdout.isTTY&&process.stdout.write("\x1Bc")},$i=()=>({turboProcess:null,isRestarting:!1,isShuttingDown:!1}),Ur=async(e,t)=>{let n=_o(".env.local",t);n.length>0&&(await Bo(n),await Gr(50)),Ei(Wr.default.cyan("\u{1F525} Starting services...")),Ei(Wr.default.dim(` Command: turbo run ${Rn} --continue`)),e.isShuttingDown=!1,e.isRestarting=!1,e.turboProcess=Ho("turbo",["run",Rn,"--continue","--no-daemon"],{cwd:t,envFile:".env.local",onExit:r=>{e.isRestarting||e.isShuttingDown||r===1&&process.exit(0)}})},Jr=async e=>{let t=e.turboProcess?.pid;if(t){e.isShuttingDown=!0;try{try{process.kill(-t,"SIGTERM")}catch{e.turboProcess?.kill("SIGTERM")}await Gr(200);try{process.kill(-t,"SIGKILL")}catch{}await Gr(30)}catch{}e.turboProcess=null,Dm()}};var Ii=new Ai.Command("dev").description("Start development mode with auto-reload").action(async()=>{let e=y(),t=$i(),n=async()=>{await Hr(e),await Br(e),await Ur(t,e)},o=Ot(async()=>{t.isRestarting||t.isShuttingDown||(t.isRestarting=!0,console.log(`
|
|
477
491
|
\u{1F504} Change detected, restarting...
|
|
478
|
-
`),await
|
|
479
|
-
\u{1F6D1} Shutting down...`)
|
|
492
|
+
`),await Jr(t),await Hr(e),await Br(e),await Ur(t,e),t.isRestarting=!1)},300),s=async()=>{t.isShuttingDown||(console.log(`
|
|
493
|
+
\u{1F6D1} Shutting down...`),await Jr(t),process.exit(0))};process.removeAllListeners("SIGINT"),process.removeAllListeners("SIGTERM"),process.on("SIGINT",s),process.on("SIGTERM",s),await n(),go(e,o),console.log(`
|
|
480
494
|
\u{1F440} Watching for changes...`),console.log(` Press Ctrl+C twice to exit (first stops Turbo, second triggers cleanup)
|
|
481
|
-
`)});var
|
|
482
|
-
`))
|
|
483
|
-
\
|
|
484
|
-
`))
|
|
485
|
-
\u26A0
|
|
486
|
-
|
|
487
|
-
\u{1F4E6}
|
|
488
|
-
`));let{created:s,skipped:a,warnings:i}=await um(e,{schema:r,servicePath:o,force:t.force});gm(s,a,i),console.log(),s.length>0&&ye({force:!0}),t.service||(console.log(Q.default.yellow(`\u{1F4A1} Tip: Use --service to also create an event handler:
|
|
489
|
-
`)),console.log(Q.default.dim(` pf event add ${e} --service services/my-service
|
|
490
|
-
`)))},wk=new oi.Command("event:add").description("Add event contract, handler, and mock").argument("<event-type>","Event type (e.g., orders.created)").option("-s, --service <path>","Service path to create handler in (e.g., services/orders)").option("-f, --fields <fields>","Schema fields (e.g., orderId:string,total:number,customerId:string)").option("--schema <json>",`Schema fields as JSON (e.g., '{"orderId":"string","total":"number"}')`).option("--force","Overwrite existing files",!1).action(Pr);var ii=require("commander");var si=require("fs-extra"),ai=require("globby"),ue=require("zod");var fm=["**/node_modules/**","**/.nats-data/**","**/dist/**","**/build/**","**/.git/**","**/coverage/**"],hm=ue.z.record(ue.z.string()),ym=ue.z.object({description:ue.z.string().optional(),eventName:ue.z.string(),faker:hm.optional(),data:ue.z.record(ue.z.any())}),Ke=(e=process.cwd())=>(0,ai.globbySync)("**/*.mock.json",{cwd:e,absolute:!0,gitignore:!0,ignore:fm}).map(n=>{try{let r=(0,si.readJSONSync)(n,{encoding:"utf8"}),o=ym.safeParse(r);return o.success?{eventName:o.data.eventName,path:n,schema:o.data}:(m.warn(`\u26A0\uFE0F Invalid schema in ${n}`),console.log(o.error.format()),null)}catch{return m.warn(`\u26A0\uFE0F Failed to read or parse ${n}`),null}}).filter(n=>n!==null);var Tr=null,ci=async()=>{if(!Tr){let{faker:e}=await import("@faker-js/faker");Tr=e}return Tr},$r=async(e,t)=>{let n=await ci(),o=Ke().find(p=>p.eventName===e);if(!o){m.error(`Event "${e}" not found. Use "pf event list" to see available events.`);return}let s=o.schema,a=t.fake?await km(s):s.data,c={message:{data:Buffer.from(JSON.stringify({...a,type:s.eventName})).toString("base64"),messageId:n.string.uuid(),attributes:{source:"platform-sdk"}}};if(t.print){console.dir(c,{colors:!0});return}let l=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)});if(!l.ok){let p=await l.text();throw new Error(`Request failed: ${l.status} \u2013 ${p}`)}m.success("Event sent successfully.")},Ek=new ii.Command("event:http").description("Send via HTTP Pub/Sub endpoint").argument("<eventName>","The name of the event").option("--endpoint <url>","Target HTTP endpoint","http://localhost:3000").option("--fake","Apply fake values to fakeable fields").option("--print","Print the generated Pub/Sub event without sending").action($r),km=async e=>{let t=structuredClone(e.data);return e.faker&&await Promise.all(Object.entries(e.faker).map(async([n,r])=>{let o=await vm(r);nn(t,n,o)})),t},vm=async e=>{let t=await ci();switch(e){case"uuid":return t.string.uuid();case"email":return t.internet.email();case"string":return t.lorem.word();case"number":return t.number.int();case"boolean":return t.datatype.boolean();case"date":return new Date().toISOString();case"productName":return t.commerce.productName();case"productDescription":return t.commerce.productDescription();case"firstName":return t.person.firstName();case"lastName":return t.person.lastName();case"url":return t.internet.url();case"phoneNumber":return t.phone.number();case"streetAddress":return t.location.streetAddress();case"city":return t.location.city();case"state":return t.location.state();case"country":return t.location.country();case"companyName":return t.company.name();case"zipCode":return t.location.zipCode();case"password":return t.internet.password();default:return null}};var fi=require("commander");var Er=require("node:fs"),li=require("node:path"),Ar=require("globby");var Cm=["**/node_modules/**","**/.nats-data/**","**/dist/**","**/build/**","**/.git/**","**/coverage/**"],xm=e=>{let t=e.split("/"),n=t.indexOf("services");return n!==-1&&n+1<t.length?t[n+1]:"unknown"},wm=(e,t)=>{try{let{eventsPath:n}=C(t),o=(0,Ar.globbySync)("**/*.ts",{cwd:n,absolute:!0}).map(a=>({file:a,content:(0,Er.readFileSync)(a,"utf-8")})).find(({content:a})=>a.includes(`export const ${e}`));if(!o)return null;let s=o.content.match(/type:\s*['"]([^'"]+)['"]/);return s?s[1]:null}catch{return null}},bm=e=>e.replace(/Contract$/,"").replace(/([A-Z])/g,(t,n,r)=>(r>0?".":"")+n.toLowerCase()),Sm=(e,t)=>{let n=e.match(/handleEvent\s*\(\s*\{\s*[^}]*type:\s*['"]([^'"]+)['"]/s);if(n)return n[1];let r=e.match(/handleEvent\s*\(\s*['"]([^'"]+)['"]/s);if(r)return r[1];let o=e.match(/import\s+(?:type\s+)?{[^}]*?(\w+Contract)[^}]*?}\s+from/);if(!o)return null;let s=o[1];return wm(s,t)||bm(s)},Pm=(e,t)=>{try{let n=(0,Er.readFileSync)(e,"utf-8"),r=Sm(n,t);return r?{serviceName:xm(e),handlerPath:(0,li.relative)(t,e),eventType:r}:null}catch{return null}},pi=(e=process.cwd())=>(0,Ar.globbySync)("services/**/src/events/*.handler.ts",{cwd:e,absolute:!0,gitignore:!0,ignore:Cm}).map(n=>Pm(n,e)).filter(n=>n!==null),mi=e=>e.reduce((t,n)=>{let r=t.get(n.eventType)||[];return t.set(n.eventType,[...r,n]),t},new Map);var ui=u(require("cli-table3"));var di=(e,t)=>{let n=t.get(e)||[],r=[...new Set(n.map(o=>o.serviceName))];return r.length>0?r.join(", "):"-"};var gi=(e,t)=>{let n=new ui.default({head:["name","description","consumers"],style:{head:["dim","bold"],compact:!0}});for(let{eventName:r,schema:o}of e)n.push([r,o.description||"-",di(r,t)]);return n.toString()};var Tm=e=>{for(let t of e)console.log(t)},$m=()=>{let e=ar();Tm(e)},Em=()=>{let e=Ke();if(e.length===0){m.error("No event schemas found.");return}let t=pi(),n=mi(t),r=gi(e,n);console.log(r)},Ir=e=>{if(!ta()){if(e.namesOnly)return;m.error("This command must be run from within a workspace."),m.info("To create a new workspace, run: pf new workspace my-platform"),process.exit(1)}e.namesOnly?$m():Em()},Bk=new fi.Command("event:list").description("List all available event mocks").option("--names-only","Output only event names (for completion)").action(Ir);var hi=require("node:path"),yi=require("commander");var Rm={},Nr=null,Rr=null,ki=async()=>{if(!Nr){let{faker:e}=await import("@faker-js/faker");Nr=e}return Nr},Am=async()=>{if(!Rr)try{let{createJiti:e}=await import("jiti"),t=e(Rm.url),n=y(),r=C(n),o=(0,hi.join)(r.packagePath,"node_modules","@crossdelta","cloudevents");Rr=(await t.import(o)).publish}catch{throw new Error(`@crossdelta/cloudevents is required for event:publish.
|
|
491
|
-
Install it in your contracts package with: cd packages/contracts && bun add @crossdelta/cloudevents`)}return Rr},Mr=async(e,t)=>{let n=await ki(),o=Ke().find(i=>i.eventName===e||i.path.includes(`${e}.mock.json`));if(!o){m.error(`Event "${e}" not found. Use "pf event list" to see available events.`);return}let s=o.schema,a=t.fake?await Im(s):s.data;if(t.print){console.log(`
|
|
492
|
-
\u{1F4E6} Event Type:`,s.eventName),console.log("\u{1F4C4} Payload:"),console.dir(a,{colors:!0,depth:null});return}try{let i=await Am();if(!i)throw new Error("Failed to load publish function from cloudevents");await i(s.eventName,a,{source:"platform-sdk-cli",subject:n.string.uuid()}),m.success(`Event "${s.eventName}" published successfully to NATS JetStream.`),await new Promise(c=>setTimeout(c,100)),process.exit(0)}catch(i){m.error(`Failed to publish event: ${i instanceof Error?i.message:String(i)}`),m.info("Make sure NATS is running and NATS_URL is configured."),process.exit(1)}},Kk=new yi.Command("event:publish").description("Publish to NATS JetStream").argument("<eventName>","The name of the event (e.g., order-created)").option("--fake","Apply fake values to fakeable fields").option("--print","Print the generated event data without publishing").action(Mr),Im=async e=>{let t=structuredClone(e.data);return e.faker&&await Promise.all(Object.entries(e.faker).map(async([n,r])=>{let o=await Nm(r);nn(t,n,o)})),t},Nm=async e=>{let t=await ki();switch(e.toLowerCase()){case"uuid":return t.string.uuid();case"email":return t.internet.email();case"firstname":return t.person.firstName();case"lastname":return t.person.lastName();case"name":return t.person.fullName();case"url":return t.internet.url();case"phone":return t.phone.number();case"date":return t.date.recent().toISOString();case"boolean":return t.datatype.boolean();case"number":return t.number.int({min:1,max:1e3});case"string":return t.lorem.word();case"text":return t.lorem.sentence();default:return e}};var ze=new vi.Command("event").description("Event management commands");ze.command("add").description("Add event contract, handler, and mock").argument("<event-type>","Event type (e.g., orders.created)").option("-s, --service <path>","Service path to create handler in (e.g., services/orders)").option("--schema <fields>",`Schema fields as JSON (e.g., '{"orderId":"string","total":"number"}')`).option("--force","Overwrite existing files",!1).action(Pr);ze.command("list").description("List all available event mocks").option("--names-only","Output only event names (for completion)").action(Ir);ze.command("publish").description("Publish to NATS JetStream").argument("<eventName>","Event name to publish").option("--fake","Apply fake values to fakeable fields").option("--print","Print the generated event data without publishing").action(Mr);ze.command("http").description("Send via HTTP Pub/Sub endpoint").argument("<eventName>","Event name to send").option("--endpoint <url>","Target HTTP endpoint","http://localhost:3000").option("--fake","Apply fake values to fakeable fields").option("--print","Print the generated Pub/Sub event without sending").action($r);ze.action(()=>{let e=pe({title:"\u{1F4EC} Event Management",commands:[{name:"add",description:"Add event contract, handler, and mock"},{name:"list",description:"List all available event mocks"},{name:"publish",description:"Publish to NATS JetStream"},{name:"http",description:"Send via HTTP Pub/Sub endpoint"}],footer:'Run "pf event <command> --help" for more information'});console.log(e)});var Ci=ze;var Or=u(require("chalk")),Pi=require("commander");var qe=require("node:fs"),Fr=u(require("node:path")),yn=u(require("chalk")),xi=require("commander"),wi=u(require("os"));var{name:Mm,publishConfig:jm}=R,Fm=jm?.registry,Om=Mm?.split("/")[0],nv=new xi.Command("token:set").description(yn.default.bold("Set a registry auth token in a .npmrc file")).argument("<token>","Authentication token (e.g. GitHub or npm token)").option("--scope <scope>","Package scope (e.g. @my-workspace)",Om).option("--registry <registry>","Registry URL",Fm).option("--local","Write token to a local .npmrc in the current directory",!1).option("--force","Force overwrite existing token if already present",!1).action((e,t)=>bi(e,t.scope||"",t.registry||"",t.local,t.force)).addHelpText("after",()=>`${yn.default.cyan(`
|
|
495
|
+
`)});var Ki=require("commander");var zr=require("node:fs"),Kr=require("node:path"),En=require("@listr2/prompt-adapter-enquirer"),ye=u(require("chalk"));v();g();var Lm=e=>{if(e)try{return JSON.parse(e)}catch{return}},Ni=e=>{if(!e)return;let t={},n=e.split(",").map(r=>r.trim()).filter(Boolean);for(let r of n){let[o,s]=r.split(":").map(a=>a.trim());o&&s&&(t[o]=s)}return Object.keys(t).length>0?t:void 0},Hm=(e,t)=>{if(!t)return;let n=t.startsWith("/")?t:(0,Kr.resolve)(e,t);return(0,zr.existsSync)(n)?n:void 0},Bm=async e=>{let{eventType:t,schema:n,servicePath:r,force:o}=e,s=[],a=[],i=[];if(zt(t)&&!o)a.push("Contract (already exists)");else{let l=er(t,n);s.push(`Contract: ${l}`)}lr(t)&&s.push("Export: packages/contracts/src/index.ts");let c=await Vt(t);if(c&&s.push(`Mock: ${c}`),r){let l=or(t,r);l?s.push(`Handler: ${l}`):a.push("Handler (already exists)");let p=rr(r,t);p.added?s.push(`Stream: ${p.streamName} added to index.ts`):p.warning&&i.push(p.warning)}return{created:s,skipped:a,warnings:i}},Wm=()=>{try{let e=y();return $r(e)?.services??[]}catch{return[]}},Gm={title:"Event configuration",enabled:e=>!e.eventType,task:async(e,t)=>{e.eventType=await t.prompt(En.ListrEnquirerPromptAdapter).run({type:"Input",message:"Event type (e.g., order.created):",validate:n=>n?n.includes(".")?!0:"Event type must include a namespace (e.g., order.created)":"Event type is required"})}},Um={title:"Service selection",enabled:e=>!e.servicePath,task:async(e,t)=>{let n=Wm();if(n.length===0){t.skip("No services found in workspace");return}let r=await t.prompt(En.ListrEnquirerPromptAdapter).run({type:"Select",message:"Select service to create handler in (or skip):",choices:[{name:"skip",message:ye.default.dim("Skip handler creation"),value:""},...n.map(o=>({name:o,message:o,value:o}))]});if(r){let o=(0,Kr.resolve)(e.workspaceRoot,r);(0,zr.existsSync)(o)&&(e.servicePath=o)}}},Jm={title:"Schema fields",enabled:e=>!e.schema&&!zt(e.eventType),task:async(e,t)=>{let n=await t.prompt(En.ListrEnquirerPromptAdapter).run({type:"Input",message:"Schema fields (e.g., orderId:string,total:number) or leave empty:",initial:""});n.trim()&&(e.schema=Ni(n)),t.skip(n?`Fields: ${n}`:"No schema defined")}},zm={title:"Creating event files",task:async(e,t)=>{let n=await Bm(e);return t.title=[ye.default.green("Event created successfully"),...n.created.map(r=>ye.default.dim(` ${r}`)),...n.skipped.map(r=>ye.default.yellow(` \u2139 ${r}`)),...n.warnings.map(r=>ye.default.yellow(` \u26A0 ${r}`))].join(`
|
|
496
|
+
`),n}},Ri=q({name:"add",description:"Add event contract, handler, and mock (interactive)",arguments:[["[event-type]","Event type (e.g., order.created)"]],options:[["-s, --service <path>","Service path to create handler in (e.g., services/orders)"],["-f, --fields <fields>","Schema fields (e.g., orderId:string,total:number,customerId:string)"],["--schema <json>",`Schema fields as JSON (e.g., '{"orderId":"string","total":"number"}')`],["--force","Overwrite existing files"],["-i, --interactive","Run in interactive mode with prompts"]],exampleUsage:"pf event add order.created --interactive",buildContext:async(e,t)=>{let n=y();await fe({force:!1});let r=Ni(t.fields)||Lm(t.schema),o;return t.service&&(o=Hm(n,t.service)),{eventType:e["event-type"]||"",schema:r,servicePath:o,force:t.force??!1,workspaceRoot:n}},prompts:[Gm,Um,Jm],actions:[zm],onComplete:async e=>{await fe({force:!0}),e.servicePath||(console.log(ye.default.yellow(`
|
|
497
|
+
\u{1F4A1} Tip: Use --service to also create an event handler:
|
|
498
|
+
`)),console.log(ye.default.dim(` pf event add ${e.eventType} --service services/my-service
|
|
499
|
+
`)))}});var Fi=require("commander");g();var Mi=require("fs-extra"),ji=require("globby"),ke=require("zod");g();var Km=["**/node_modules/**","**/.nats-data/**","**/dist/**","**/build/**","**/.git/**","**/coverage/**"],qm=ke.z.record(ke.z.string()),Vm=ke.z.object({description:ke.z.string().optional(),eventName:ke.z.string(),faker:qm.optional(),data:ke.z.record(ke.z.any())}),Xe=(e=process.cwd())=>(0,ji.globbySync)("**/*.mock.json",{cwd:e,absolute:!0,gitignore:!0,ignore:Km}).map(n=>{try{let r=(0,Mi.readJSONSync)(n,{encoding:"utf8"}),o=Vm.safeParse(r);return o.success?{eventName:o.data.eventName,path:n,schema:o.data}:(m.warn(`\u26A0\uFE0F Invalid schema in ${n}`),console.log(o.error.format()),null)}catch{return m.warn(`\u26A0\uFE0F Failed to read or parse ${n}`),null}}).filter(n=>n!==null);var qr=null,Oi=async()=>{if(!qr){let{faker:e}=await import("@faker-js/faker");qr=e}return qr},Vr=async(e,t)=>{let n=await Oi(),o=Xe().find(p=>p.eventName===e);if(!o){m.error(`Event "${e}" not found. Use "pf event list" to see available events.`);return}let s=o.schema,a=t.fake?await Zm(s):s.data,c={message:{data:Buffer.from(JSON.stringify({...a,type:s.eventName})).toString("base64"),messageId:n.string.uuid(),attributes:{source:"platform-sdk"}}};if(t.print){console.dir(c,{colors:!0});return}let l=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)});if(!l.ok){let p=await l.text();throw new Error(`Request failed: ${l.status} \u2013 ${p}`)}m.success("Event sent successfully.")},pv=new Fi.Command("event:http").description("Send via HTTP Pub/Sub endpoint").argument("<eventName>","The name of the event").option("--endpoint <url>","Target HTTP endpoint","http://localhost:3000").option("--fake","Apply fake values to fakeable fields").option("--print","Print the generated Pub/Sub event without sending").action(Vr),Zm=async e=>{let t=structuredClone(e.data);return e.faker&&await Promise.all(Object.entries(e.faker).map(async([n,r])=>{let o=await Ym(r);_t(t,n,o)})),t},Ym=async e=>{let t=await Oi();switch(e){case"uuid":return t.string.uuid();case"email":return t.internet.email();case"string":return t.lorem.word();case"number":return t.number.int();case"boolean":return t.datatype.boolean();case"date":return new Date().toISOString();case"productName":return t.commerce.productName();case"productDescription":return t.commerce.productDescription();case"firstName":return t.person.firstName();case"lastName":return t.person.lastName();case"url":return t.internet.url();case"phoneNumber":return t.phone.number();case"streetAddress":return t.location.streetAddress();case"city":return t.location.city();case"state":return t.location.state();case"country":return t.location.country();case"companyName":return t.company.name();case"zipCode":return t.location.zipCode();case"password":return t.internet.password();default:return null}};var Gi=require("commander");g();var Zr=require("node:fs"),_i=require("node:path"),Yr=require("globby");v();var Xm=["**/node_modules/**","**/.nats-data/**","**/dist/**","**/build/**","**/.git/**","**/coverage/**"],Qm=e=>{let t=e.split("/"),n=t.indexOf("services");return n!==-1&&n+1<t.length?t[n+1]:"unknown"},ed=(e,t)=>{try{let{eventsPath:n}=x(t),o=(0,Yr.globbySync)("**/*.ts",{cwd:n,absolute:!0}).map(a=>({file:a,content:(0,Zr.readFileSync)(a,"utf-8")})).find(({content:a})=>a.includes(`export const ${e}`));if(!o)return null;let s=o.content.match(/type:\s*['"]([^'"]+)['"]/);return s?s[1]:null}catch{return null}},td=e=>e.replace(/Contract$/,"").replace(/([A-Z])/g,(t,n,r)=>(r>0?".":"")+n.toLowerCase()),nd=(e,t)=>{let n=e.match(/handleEvent\s*\(\s*\{\s*[^}]*type:\s*['"]([^'"]+)['"]/s);if(n)return n[1];let r=e.match(/handleEvent\s*\(\s*['"]([^'"]+)['"]/s);if(r)return r[1];let o=e.match(/import\s+(?:type\s+)?{[^}]*?(\w+Contract)[^}]*?}\s+from/);if(!o)return null;let s=o[1];return ed(s,t)||td(s)},rd=(e,t)=>{try{let n=(0,Zr.readFileSync)(e,"utf-8"),r=nd(n,t);return r?{serviceName:Qm(e),handlerPath:(0,_i.relative)(t,e),eventType:r}:null}catch{return null}},Di=(e=process.cwd())=>{let t=E(e),n=[`${t.services}/**/src/events/*.handler.ts`,`${t.apps}/**/src/events/*.handler.ts`];return(0,Yr.globbySync)(n,{cwd:e,absolute:!0,gitignore:!0,ignore:Xm}).map(o=>rd(o,e)).filter(o=>o!==null)},Li=e=>e.reduce((t,n)=>{let r=t.get(n.eventType)||[];return t.set(n.eventType,[...r,n]),t},new Map);var Bi=u(require("cli-table3"));var Hi=(e,t)=>{let n=t.get(e)||[],r=[...new Set(n.map(o=>o.serviceName))];return r.length>0?r.join(", "):"-"};var Wi=(e,t)=>{let n=new Bi.default({head:["name","description","consumers"],style:{head:["dim","bold"],compact:!0}});for(let{eventName:r,schema:o}of e)n.push([r,o.description||"-",Hi(r,t)]);return n.toString()};var od=e=>{for(let t of e)console.log(t)},sd=()=>{let e=Pr();od(e)},ad=()=>{let e=Xe();if(e.length===0){m.error("No event schemas found.");return}let t=Di(),n=Li(t),r=Wi(e,n);console.log(r)},Xr=e=>{if(!Gn()){if(e.namesOnly)return;m.error("This command must be run from within a workspace."),m.info("To create a new workspace, run: pf new workspace my-platform"),process.exit(1)}e.namesOnly?sd():ad()},bv=new Gi.Command("event:list").description("List all available event mocks").option("--names-only","Output only event names (for completion)").action(Xr);var Ui=require("node:path"),Ji=require("commander");g();var pd={},Qr=null,eo=null,zi=async()=>{if(!Qr){let{faker:e}=await import("@faker-js/faker");Qr=e}return Qr},id=async()=>{if(!eo)try{let{createJiti:e}=await import("jiti"),t=e(pd.url),n=y(),r=x(n),o=(0,Ui.join)(r.packagePath,"node_modules","@crossdelta","cloudevents");eo=(await t.import(o)).publish}catch{throw new Error(`@crossdelta/cloudevents is required for event:publish.
|
|
500
|
+
Install it in your contracts package with: cd packages/contracts && bun add @crossdelta/cloudevents`)}return eo},to=async(e,t)=>{let n=await zi(),o=Xe().find(i=>i.eventName===e||i.path.includes(`${e}.mock.json`));if(!o){m.error(`Event "${e}" not found. Use "pf event list" to see available events.`);return}let s=o.schema,a=t.fake?await cd(s):s.data;if(t.print){console.log(`
|
|
501
|
+
\u{1F4E6} Event Type:`,s.eventName),console.log("\u{1F4C4} Payload:"),console.dir(a,{colors:!0,depth:null});return}try{let i=await id();if(!i)throw new Error("Failed to load publish function from cloudevents");await i(s.eventName,a,{source:"platform-sdk-cli",subject:n.string.uuid()}),m.success(`Event "${s.eventName}" published successfully to NATS JetStream.`),await new Promise(c=>setTimeout(c,100)),process.exit(0)}catch(i){m.error(`Failed to publish event: ${i instanceof Error?i.message:String(i)}`),m.info("Make sure NATS is running and NATS_URL is configured."),process.exit(1)}},$v=new Ji.Command("event:publish").description("Publish to NATS JetStream").argument("<eventName>","The name of the event (e.g., order-created)").option("--fake","Apply fake values to fakeable fields").option("--print","Print the generated event data without publishing").action(to),cd=async e=>{let t=structuredClone(e.data);return e.faker&&await Promise.all(Object.entries(e.faker).map(async([n,r])=>{let o=await ld(r);_t(t,n,o)})),t},ld=async e=>{let t=await zi();switch(e.toLowerCase()){case"uuid":return t.string.uuid();case"email":return t.internet.email();case"firstname":return t.person.firstName();case"lastname":return t.person.lastName();case"name":return t.person.fullName();case"url":return t.internet.url();case"phone":return t.phone.number();case"date":return t.date.recent().toISOString();case"boolean":return t.datatype.boolean();case"number":return t.number.int({min:1,max:1e3});case"string":return t.lorem.word();case"text":return t.lorem.sentence();default:return e}};var Qe=new Ki.Command("event").description("Event management commands");Qe.addCommand(Ri);Qe.command("list").description("List all available event mocks").option("--names-only","Output only event names (for completion)").action(Xr);Qe.command("publish").description("Publish to NATS JetStream").argument("<eventName>","Event name to publish").option("--fake","Apply fake values to fakeable fields").option("--print","Print the generated event data without publishing").action(to);Qe.command("http").description("Send via HTTP Pub/Sub endpoint").argument("<eventName>","Event name to send").option("--endpoint <url>","Target HTTP endpoint","http://localhost:3000").option("--fake","Apply fake values to fakeable fields").option("--print","Print the generated Pub/Sub event without sending").action(Vr);Qe.action(()=>{let e=ge({title:"\u{1F4EC} Event Management",commands:[{name:"add",description:"Add event contract, handler, and mock"},{name:"list",description:"List all available event mocks"},{name:"publish",description:"Publish to NATS JetStream"},{name:"http",description:"Send via HTTP Pub/Sub endpoint"}],footer:'Run "pf event <command> --help" for more information'});console.log(e)});var qi=Qe;var oo=u(require("chalk")),Qi=require("commander");var et=require("node:fs"),ro=u(require("node:path")),$n=u(require("chalk")),Vi=require("commander"),Zi=u(require("os"));g();var{name:md,publishConfig:dd}=O,ud=dd?.registry,gd=md?.split("/")[0],Dv=new Vi.Command("token:set").description($n.default.bold("Set a registry auth token in a .npmrc file")).argument("<token>","Authentication token (e.g. GitHub or npm token)").option("--scope <scope>","Package scope (e.g. @my-workspace)",gd).option("--registry <registry>","Registry URL",ud).option("--local","Write token to a local .npmrc in the current directory",!1).option("--force","Force overwrite existing token if already present",!1).action((e,t)=>Yi(e,t.scope||"",t.registry||"",t.local,t.force)).addHelpText("after",()=>`${$n.default.cyan(`
|
|
493
502
|
Example:`)}
|
|
494
|
-
${
|
|
495
|
-
`),
|
|
496
|
-
//${r}/:_authToken=${e}`:`//${r}/:_authToken=${e}`},
|
|
497
|
-
`),m.success(`Created new .npmrc and set token for ${i}`);return}if(l.test(c)){if(!o){m.warn(`Token for ${i} already exists in ${s}. Use --force to overwrite.`);return}c=c.replace(l,a),
|
|
503
|
+
${$n.default.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
|
|
504
|
+
`),fd=e=>e?ro.default.join(process.cwd(),".npmrc"):ro.default.join(Zi.default.homedir(),".npmrc"),hd=(e,t,n)=>{let r=new URL(n).host;return t?`${t}:registry=https://${r}
|
|
505
|
+
//${r}/:_authToken=${e}`:`//${r}/:_authToken=${e}`},yd=e=>(0,et.existsSync)(e)?(0,et.readFileSync)(e,"utf8"):"",no=(e,t)=>(0,et.writeFileSync)(e,t),Yi=(e,t,n,r=!1,o=!1)=>{let s=fd(r),a=hd(e,t,n),i=new URL(n).host,c=yd(s),l=new RegExp(`//${i}/:_authToken=\\S+`);if(!c){no(s,`${a}
|
|
506
|
+
`),m.success(`Created new .npmrc and set token for ${i}`);return}if(l.test(c)){if(!o){m.warn(`Token for ${i} already exists in ${s}. Use --force to overwrite.`);return}c=c.replace(l,a),no(s,c),m.success(`Overwrote existing token for ${i} in ${s}`);return}c+=`
|
|
498
507
|
${a}
|
|
499
|
-
`,
|
|
508
|
+
`,no(s,c),m.success(`Appended token for ${i} to ${s}`)},Xi=(e,t)=>Yi(e,t.scope||"",t.registry||"",t.local,t.force);var{name:kd,publishConfig:vd}=O,Cd=vd?.registry,xd=kd?.split("/")[0],so=new Qi.Command("token").description("Token management commands");so.command("set").description("Set a registry auth token in a .npmrc file").argument("<token>","Authentication token (e.g. GitHub or npm token)").option("--scope <scope>","Package scope (e.g. @my-workspace)",xd).option("--registry <registry>","Registry URL",Cd).option("--local","Write token to a local .npmrc in the current directory",!1).option("--force","Force overwrite existing token if already present",!1).action(Xi).addHelpText("after",()=>`${oo.default.cyan(`
|
|
500
509
|
Example:`)}
|
|
501
|
-
${
|
|
502
|
-
`);
|
|
503
|
-
`)),e}catch{return console.log(
|
|
504
|
-
`)),null}}async function
|
|
505
|
-
\u{1F4CB} Get your ${e} API key here:`)),console.log(
|
|
506
|
-
`)),(0,
|
|
510
|
+
${oo.default.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
|
|
511
|
+
`);so.action(()=>{let e=ge({title:"\u{1F511} Token Management",commands:[{name:"set",description:"Set a registry auth token in a .npmrc file"}],footer:'Run "pf token <command> --help" for more information'});console.log(e)});var ec=so;var An=u(require("chalk")),oc=require("commander");v();Rt();var Jv={AI_GENERATION:!0,DEBUG:process.env.PF_DEBUG==="true"};var oe=require("@inquirer/prompts"),b=u(require("chalk"));var wd=[/embed/i,/whisper/i,/tts/i,/dall-e/i,/davinci/i,/babbage/i,/curie/i,/ada(?!-)/i,/moderation/i,/realtime/i,/audio/i,/transcription/i,/search/i],bd=async(e,t,n=1e4)=>{let r=new AbortController,o=setTimeout(()=>r.abort(),n);try{return await fetch(e,{...t,signal:r.signal})}finally{clearTimeout(o)}},Sd=e=>e.replace(/-(\d{8})$/," ($1)").replace(/^claude-/,"Claude ").replace(/^gpt-/,"GPT-").replace(/-/g," ").replace(/(\d)\.(\d)/g,"$1.$2").replace(/\s+/g," ").split(" ").map(t=>/^\d/.test(t)||/^\(\d+\)$/.test(t)?t:t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join(" ").trim(),Pd=async(e,t)=>{let n=lt(e),r=await bd(n.modelsApiUrl,{headers:n.buildHeaders(t)});if(!r.ok)throw new Error(`${n.name} API error: ${r.status}`);let o=await r.json(),s=n.parseModelsResponse(o);if(!Array.isArray(s)||s.length===0)throw new Error(`No models returned from ${n.name} API`);let a=s.filter(i=>{let c=n.modelFilters.some(p=>p.test(i.id)),l=wd.some(p=>p.test(i.id));return c&&!l}).sort((i,c)=>{let l=typeof i.created=="number"?i.created:new Date(i.created).getTime();return(typeof c.created=="number"?c.created:new Date(c.created).getTime())-l}).map(i=>({name:Sd(i.id),value:i.id}));if(a.length===0)throw new Error(`No chat models found from ${n.name} API`);return a};async function tc(e,t){if(!t)throw new Error("API key is required to fetch available models");return{models:await Pd(e,t),fromApi:!0}}function Td(){if(!pt())return null;try{let e=Ut();return console.log(b.default.dim(`Found existing configuration at ${be}
|
|
512
|
+
`)),e}catch{return console.log(b.default.yellow(`Found corrupted configuration, starting fresh.
|
|
513
|
+
`)),null}}async function Ed(e,t){return console.log(b.default.dim(`
|
|
514
|
+
\u{1F4CB} Get your ${e} API key here:`)),console.log(b.default.cyan(` ${t}
|
|
515
|
+
`)),(0,oe.password)({message:`Enter your ${e} API key:`,mask:"*",validate:n=>n.trim()?n.length<10?"API key seems too short":!0:"API key cannot be empty"})}async function $d(e,t,n){let r=await(0,oe.select)({message:"Select model:",choices:e,default:t?.provider===n?t.model:void 0});return await(0,oe.confirm)({message:"Enter a custom model ID instead?",default:!1})?(0,oe.input)({message:"Enter custom model ID:",default:r,validate:s=>s.trim()?!0:"Model ID cannot be empty"}):r}function nc(e){return e.length<=12?"****":`${e.slice(0,4)}...${e.slice(-4)}`}function Ad(e,t){console.log(b.default.green.bold(`
|
|
507
516
|
\u2705 AI configuration saved successfully!
|
|
508
|
-
`)),console.log(
|
|
509
|
-
`)),console.log(
|
|
510
|
-
`))}async function
|
|
517
|
+
`)),console.log(b.default.dim(`Configuration file: ${be}`)),console.log(b.default.dim("API Key: Stored securely in system keychain")),console.log(b.default.dim(`Provider: ${e.provider}`)),console.log(b.default.dim(`Model: ${e.model}`)),console.log(b.default.dim(`API Key: ${nc(t)}
|
|
518
|
+
`)),console.log(b.default.cyan("You can now use AI-powered service generation:")),console.log(b.default.dim(` pf new hono-micro services/my-service --ai
|
|
519
|
+
`))}async function Id(e){let t=await Gt(e);if(t)return t;let n=lt(e);return process.env[n.defaultApiKeyEnvVar]??null}async function rc(){console.log(b.default.cyan.bold(`
|
|
511
520
|
\u{1F916} AI Configuration Setup
|
|
512
|
-
`));let e=
|
|
513
|
-
\u2713 Found existing API key: ${
|
|
514
|
-
Fetching available models...`));let s;try{s=(await
|
|
515
|
-
`))}catch(c){console.error(
|
|
516
|
-
\u274C Failed to fetch models: ${c.message}`)),console.log(
|
|
521
|
+
`));let e=Td();try{let t=await(0,oe.select)({message:"Select AI provider:",choices:os(),default:e?.provider??Qn.provider}),n=lt(t),r,o=await Id(t);o&&(console.log(b.default.green(`
|
|
522
|
+
\u2713 Found existing API key: ${nc(o)}`)),await(0,oe.confirm)({message:"Use this existing API key?",default:!0})&&(r=o)),r||(r=await Ed(n.name,n.apiKeyUrl)),console.log(b.default.dim(`
|
|
523
|
+
Fetching available models...`));let s;try{s=(await tc(t,r)).models,console.log(b.default.green(`\u2713 Loaded ${s.length} models from ${n.name} API
|
|
524
|
+
`))}catch(c){console.error(b.default.red(`
|
|
525
|
+
\u274C Failed to fetch models: ${c.message}`)),console.log(b.default.yellow(`
|
|
517
526
|
Please check your API key and try again.
|
|
518
|
-
`)),process.exit(1)}let a=await
|
|
527
|
+
`)),process.exit(1)}let a=await $d(s,e,t),i={provider:t,model:a.trim()};is(i),await cs(t,r),Ad(i,r)}catch(t){throw t.name==="ExitPromptError"&&(console.log(b.default.yellow(`
|
|
519
528
|
Setup cancelled.
|
|
520
|
-
`)),process.exit(0)),t}}var
|
|
529
|
+
`)),process.exit(0)),t}}var ao=async(e,t=!1)=>{try{return Ir(e,t),await fe({verbose:t}),!0}catch{return!1}};var In=e=>{let t=new oc.Command("setup").description("Configure platform settings");return t.command("completion").description("Install shell autocompletion").option("--verbose","Enable verbose logging").addHelpText("after",`
|
|
521
530
|
Examples:
|
|
522
531
|
$ pf setup completion
|
|
523
532
|
$ pf setup completion --verbose
|
|
524
|
-
`).action(n=>{
|
|
525
|
-
\u2714 Shell autocompletion installed!`)),console.log(
|
|
526
|
-
`)),console.log(
|
|
533
|
+
`).action(async n=>{await ao(e,n.verbose),n.verbose||(console.log(An.default.green(`
|
|
534
|
+
\u2714 Shell autocompletion installed!`)),console.log(An.default.dim(` Restart your shell:
|
|
535
|
+
`)),console.log(An.default.cyan(` exec $SHELL
|
|
527
536
|
`)))}),t.command("ai").description("Configure AI provider and API key for code generation").addHelpText("after",`
|
|
528
537
|
Example:
|
|
529
538
|
$ pf setup ai
|
|
530
|
-
`).action(async()=>{await
|
|
531
|
-
\u2716 An unexpected error occurred:`)),console.error(e),process.exit(1)});var
|
|
539
|
+
`).action(async()=>{await rc()}),t.action(()=>{let n=ge({title:"\u2699\uFE0F Platform Setup",commands:[{name:"completion",description:"Install shell autocompletion"},{name:"ai",description:"Configure AI provider"}],footer:'Run "pf setup <command> --help" for more information'});console.log(n)}),t},Rd=In("pf");ln();process.on("SIGINT",()=>{process.exit(0)});process.on("unhandledRejection",e=>{throw(e.name==="ExitPromptError"||e.message?.includes("ERR_USE_AFTER_CLOSE")||e.message?.includes("Cancelled prompt"))&&process.exit(0),e});process.on("uncaughtException",e=>{(e.name==="ExitPromptError"||e.message?.includes("ERR_USE_AFTER_CLOSE")||e.message?.includes("Cancelled prompt"))&&process.exit(0),(e.message?.includes("Not in a workspace directory")||e.message?.includes("Could not locate workspace root"))&&(console.error(e.message),process.exit(1)),console.error(Ee.default.red(`
|
|
540
|
+
\u2716 An unexpected error occurred:`)),console.error(e),process.exit(1)});var Nt=new mc.Command,sc=Object.keys(O.bin||{}),[co="pf",io]=sc.length>0?sc:["pf"],{description:ac,version:Md,repository:ic,homepage:jd}=O,cc=ac?.split(/ —|,|\./)[0]||ac||"Platform CLI",uc=ic?.url?`https://${ic.url.replace(/^(git\+|git@)/,"").replace(/\.git$/,"").replace(":","/")}`:null,lc=uc||jd,Fd=uc?"GitHub":"README",Od=lc?[Ee.default.bold(cc),`
|
|
532
541
|
|
|
533
|
-
`,
|
|
542
|
+
`,Ee.default.cyan("See more at: "),Ee.default.bold((0,dc.default)(Fd,String(lc)))].join(""):Ee.default.bold(cc),gc=[In(co),Ti(),Ii,qi,ec,Xo];Nt.name(co).description(Od).version(Md||"0.0.1").helpCommand(!1).configureHelp({subcommandTerm:e=>Ee.default.cyan(e.name())}).addHelpText("after",aa);io&&io!==co&&Nt.alias(io);gc.forEach(e=>{Nt.addCommand(e)});Nt.command("__workspace-hash",{hidden:!0}).action(()=>{let e=process.cwd(),t=Math.abs(e.split("").reduce((n,r)=>(n<<5)-n+r.charCodeAt(0)|0,0));console.log(t)});ia(Nt,pc.argv,gc);
|