@crossdelta/platform-sdk 0.26.6 → 0.26.8
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 +22 -0
- package/bin/cli.mjs +46 -46
- package/bin/templates/workspace/.github/workflows/publish-packages.yml +2 -0
- package/bin/templates/workspace/infra/package.json.hbs +2 -2
- package/bin/templates/workspace/packages/contracts/package.json.hbs +2 -2
- package/dist/facade.js +31 -35
- package/dist/facade.mjs +31 -35
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,28 @@ All notable changes to `@crossdelta/platform-sdk` will be documented in this fil
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.26.8] - 2026-10-25
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- **The workspace template's `publish-packages.yml` keeps publishing the other packages when one
|
|
12
|
+
fails.** The publish matrix sets `fail-fast: false`, so one package failing (an npm 404 for a
|
|
13
|
+
missing Trusted Publisher, say) no longer cancels the publish of every other package in the run.
|
|
14
|
+
|
|
15
|
+
## [0.26.7] - 2026-10-25
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- **The CLI's task helpers type the Listr task wrapper as `BaseTaskWrapper<Ctx>` instead of
|
|
19
|
+
`ListrTaskWrapper<Ctx, any, any>`.** `debounce` takes the argument list as a type parameter
|
|
20
|
+
(`Args extends unknown[]`), `setDeep` takes `unknown`, and `executeGeneration` types its task.
|
|
21
|
+
These are internal to the CLI; the published entry points (`.`, `./plugin`, `./facade`) are
|
|
22
|
+
unchanged.
|
|
23
|
+
- **The workspace template pins `@crossdelta/cloudevents` `^0.10.1` and `@crossdelta/infrastructure`
|
|
24
|
+
`^0.19.0`.**
|
|
25
|
+
- **`generate-service.task.ts` compares through typed constants instead of string literals, no
|
|
26
|
+
behaviour change.**
|
|
27
|
+
- **Comments trimmed, no behaviour change.**
|
|
28
|
+
- **`function` declarations are arrow functions, no behaviour change.**
|
|
29
|
+
|
|
8
30
|
## [0.26.6] - 2026-10-24
|
|
9
31
|
|
|
10
32
|
### Changed
|
package/bin/cli.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var $s=Object.defineProperty;var xt=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var C=(e,t)=>()=>(e&&(t=e(e=0)),t);var Rs=(e,t)=>{for(var r in t)$s(e,r,{get:t[r],enumerable:!0})};var k,le=C(()=>{"use strict";k={SUCCESS:0,GENERAL_ERROR:1,USAGE_ERROR:2,WORKSPACE_ERROR:64,VALIDATION_ERROR:65,CONFIG_ERROR:66,IO_ERROR:74,PERMISSION_ERROR:77,CANCELLED:130}});var W,Re,wt=C(()=>{"use strict";le();W=class extends Error{exitCode;category;hint;cause;constructor(t,r=k.GENERAL_ERROR,n={}){super(t),this.name="CliError",this.exitCode=r,this.category=n.category??"process",this.hint=n.hint,this.cause=n.cause}toUserMessage(){let t=[this.message];return this.hint&&t.push(`
|
|
3
|
-
Hint: ${this.hint}`),t.join("")}},Re=class extends W{constructor(t="Operation cancelled",r={}){super(t,k.CANCELLED,{...r,category:"user"}),this.name="CancelledError"}}});import
|
|
4
|
-
Hint: ${e.hint}`)),n&&process.exit(As(e))}});var J=C(()=>{"use strict";wt();Nr();le()});var
|
|
5
|
-
`)}
|
|
3
|
+
Hint: ${this.hint}`),t.join("")}},Re=class extends W{constructor(t="Operation cancelled",r={}){super(t,k.CANCELLED,{...r,category:"user"}),this.name="CancelledError"}}});import B from"chalk";var Ie,Rr,Ir,Is,Ns,Ne,Os,As,A,Nr=C(()=>{"use strict";wt();le();Ie=e=>e instanceof Error,Rr=["ExitPromptError"],Ir=["Cancelled prompt","User force closed"],Is=["ERR_USE_AFTER_CLOSE"],Ns=e=>Rr.some(t=>e.name?.includes(t))||Ir.some(t=>e.message?.includes(t)),Ne=e=>{if(e instanceof Re)return!0;if(!(e instanceof Error))return!1;if(Rr.some(r=>e.name?.includes(r))||Ir.some(r=>e.message?.includes(r)))return!0;let t=e.code;return t&&Is.includes(t)?Ns(e):!1},Os=e=>{if(e instanceof W){let r=e.toUserMessage();return B.red(`\u2716 ${r||"Unexpected error (re-run with DEBUG=true for details)"}`)}if(e instanceof Error){let r=e.message?.trim();return r?B.red(`\u2716 ${r}`):B.red("\u2716 Unexpected error (re-run with DEBUG=true for details)")}let t=String(e);return!t||t==="undefined"||t==="null"?B.red("\u2716 Unexpected error (re-run with DEBUG=true for details)"):B.red(`\u2716 ${t}`)},As=e=>e instanceof W?e.exitCode:Ne(e)?k.CANCELLED:k.GENERAL_ERROR,A=(e,t={})=>{let{debug:r=process.env.DEBUG==="true",exit:n=!0,logger:o=console.error}=t;if(Ne(e)){n&&process.exit(k.CANCELLED);return}o(Os(e)),r&&e instanceof Error&&e.stack&&o(B.dim(e.stack)),e instanceof W&&e.hint&&o(B.dim(`
|
|
4
|
+
Hint: ${e.hint}`)),n&&process.exit(As(e))}});var J=C(()=>{"use strict";wt();Nr();le()});var ym,Or,Pt,Oe=C(()=>{"use strict";ym=process.env.npm_package_version||"0.0.0",Or=["bun.lock","bun.lockb","package-lock.json","yarn.lock","pnpm-lock.yaml"],Pt="start:dev"});import Ae from"chalk";var _s,Ds,bt,Ar=C(()=>{"use strict";_s=e=>e?Ae[e]("\u2587"):"\u2587",Ds=(e,t,r,n,o,s)=>{let i=Math.round(e.value/t*r),a=e.barColor?Ae[e.barColor](n.repeat(i)):n.repeat(i),c=e.color??s;return`${Ae.bold(c?Ae[c](e.label.padEnd(12)):e.label.padEnd(12))} ${a} ${e.value.toLocaleString()}${o?` ${o}`:""}`},bt=(e,t)=>{if(e.length===0)return"No entries to display.";let r=t?.title||"Benchmark Results",n=t?.footer||"",o=t?.maxBarWidth||50,s=t?.unit||"",i=Math.max(...e.map(c=>c.value)),a=[];a.push(""),a.push(r),a.push("");for(let c of e){let p=_s(c.barColor??t?.barColor),l=Ds(c,i,o,p,s,t?.labelColor);a.push(l)}return n&&(a.push(""),a.push(n)),a.join(`
|
|
5
|
+
`)}});import{existsSync as Tt,unlinkSync as Ms,writeFileSync as js}from"fs";import{join as Et}from"path";import St from"chokidar";var Ls,_e,Fs,_r,$t,Ws,Dr,Rt=C(()=>{"use strict";h();v();Ls=".pf-generating",_e=e=>Et(e,Ls),Fs=e=>Tt(_e(e)),_r=e=>{js(_e(e),"","utf-8")},$t=e=>{let t=_e(e);Tt(t)&&Ms(t)},Ws=e=>{let r=$(e)?.pf?.paths;return r?Object.values(r).filter(n=>typeof n=="object"&&n!==null&&n.watch===!0&&typeof n.path=="string"):[{path:"services"},{path:"apps"}]},Dr=(e,t)=>{$t(e);let r=Ws(e),n=_e(e),s=z(async()=>{Fs(e)||await t()},300),i=[];i.push(St.watch(n,{ignoreInitial:!0}).on("unlink",()=>t()));for(let a of r){let c=Et(e,a.path);if(!Tt(c))continue;let p=a.ignorePatterns?.map(l=>Et(c,l));i.push(St.watch(c,{ignoreInitial:!0,depth:0,ignored:p,usePolling:!0,interval:1e3}).on("addDir",l=>l!==c&&s()).on("unlinkDir",l=>l!==c&&s())),i.push(St.watch(`${c}/*/package.json`,{ignoreInitial:!0,ignored:p}).on("add",s).on("change",s))}return async()=>{await Promise.all(i.map(a=>a.close()))}}});import Mr from"chalk";import{Command as Bs}from"commander";import{Listr as jr}from"listr2";var M,Hs,Lr,Fr=C(()=>{"use strict";J();Rt();v();M=e=>{let t=new Bs(e.name).description(e.description).showHelpAfterError();e.arguments?.forEach(([o,s])=>{t.argument(o,s)}),e.options?.forEach(([o,s])=>{t.option(o,s)}),e.exampleUsage&&t.addHelpText("after",()=>`${Mr.cyan.bold(`
|
|
6
6
|
Example:`)}
|
|
7
|
-
${
|
|
8
|
-
`),e.additionalInfo&&t.addHelpText("after",()=>(typeof e.additionalInfo=="function"?e.additionalInfo():e.additionalInfo)??"");let r=async o=>{e.prompts?.length&&await new
|
|
9
|
-
`,"utf-8"),oi=["@crossdelta/cloudevents"],
|
|
7
|
+
${Mr.bold(e.exampleUsage)}
|
|
8
|
+
`),e.additionalInfo&&t.addHelpText("after",()=>(typeof e.additionalInfo=="function"?e.additionalInfo():e.additionalInfo)??"");let r=async o=>{e.prompts?.length&&await new jr(Lr(e.prompts,o),{rendererOptions:{lazy:!0,showErrorMessage:!1}}).run(o),await new jr(Lr(e.actions,o),{rendererOptions:{lazy:!1,showErrorMessage:!1}}).run(o),await e.onComplete?.(o)},n=()=>{try{let o=u();return _r(o),o}catch{return null}};return t.action(async(...o)=>{let s=null;try{let i=o.at(-1),a=i.args,c=i.opts(),p=Hs(e.arguments??[],a),l=await e.buildContext(p,c);s=n(),await r(l)}catch(i){A(i,{exit:!1})}finally{s&&$t(s)}}),t},Hs=(e,t)=>{let r=e.map(([n],o)=>[n.replace(/[<>[\]]/g,""),t[o]]);return Object.fromEntries(r)},Lr=(e,t)=>e.map(r=>typeof r=="function"?r(t):r)});var z,Wr=C(()=>{"use strict";z=(e,t)=>{let r=null;return(...n)=>(r&&clearTimeout(r),new Promise(o=>{r=setTimeout(async()=>{r=null,await e(...n),o()},t)}))}});var Br=C(()=>{"use strict"});import{execaSync as Gs}from"execa";var me,It=C(()=>{"use strict";me=e=>{try{return Gs(e,["--version"]),!0}catch{return!1}}});var Hr=C(()=>{"use strict";It()});import{readdirSync as Us}from"fs";import{dirname as Gr,isAbsolute as Gm,join as Vs,normalize as Um,resolve as Vm,sep as Jm}from"path";import{fileURLToPath as Js}from"url";import{packageUpSync as zs}from"package-up";import{rimraf as Ks}from"rimraf";var qs,_,De,Ur,Vr,Jr=C(()=>{"use strict";J();v();qs=()=>typeof import.meta?.url=="string"?Js(import.meta.url):process.cwd(),_=e=>{let t=Nt()?u():process.cwd();return Vs(t,e)},De=e=>{try{return Us(e).length===0}catch{return!0}},Ur=()=>{let e=zs({cwd:Gr(qs())});if(!e)throw new Error("Could not find package.json");return Gr(e)},Vr=e=>Ks(e)});import de from"chalk";var zr,Ys,Zs,Me,m,Kr=C(()=>{"use strict";zr={debug:0,info:1,warn:2,error:3,silent:4},Ys=e=>e==="debug"||e==="info"||e==="warn"||e==="error"||e==="silent",Zs=()=>{let e=process.env.LOG_LEVEL;return Ys(e)?e:process.env.DEBUG==="true"||process.env.VERBOSE==="true"?"debug":"info"},Me=e=>{let t=Zs();return zr[e]>=zr[t]},m={logs:[],breakLine:()=>(console.log(),m),success:(e,...t)=>(console.log(de.green(`\u2714 ${e}`),...t),m),info:(e,...t)=>(Me("info")&&console.log(de.cyan(`\u{1F6C8} ${e}`),...t),m),warn:(e,...t)=>(Me("warn")&&console.warn(de.yellow(`\u26A0\uFE0E ${e}`),...t),m),error:(e,...t)=>(Me("error")&&console.error(de.red(`\u2716 ${e}`),...t),m),debug:(e,...t)=>(Me("debug")&&console.log(de.dim(`[debug] ${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 qr=C(()=>{"use strict"});import Xs from"chalk";var R,je,Yr=C(()=>{"use strict";R=async(e,t)=>{let r=Date.now(),n=e.title,o=()=>Math.floor((Date.now()-r)/1e3),s=setInterval(()=>{o()>1&&(e.title=`${n} (${o()}s)`)},1e3);try{return await t(o)}finally{clearInterval(s)}},je=async(e,t,r)=>{for(let n=0;n<t.length;n++){let o=t[n];e.output=Xs.dim(`[${n+1}/${t.length}] ${o.title}`),await o.fn(r??{},e)}}});var h=C(()=>{"use strict";Ar();Fr();Wr();Br();Hr();Jr();Kr();qr();It();Yr()});var rn={};Rs(rn,{discoverAvailableServices:()=>Be,findWorkspaceRoot:()=>u,getContractsConfig:()=>x,getPackageJsonField:()=>mi,getPfConfig:()=>fe,getPkgJson:()=>tn,getRootPackageScope:()=>en,getWorkspacePackageJson:()=>$,getWorkspacePathsConfig:()=>I,isInWorkspace:()=>Nt,pkgJson:()=>E,readPackageConfig:()=>he,updatePackageJsonField:()=>We});import{existsSync as ge,readdirSync as Qs,readFileSync as Zr,writeFileSync as ei}from"fs";import{join as S,resolve as ti}from"path";var At,ri,ni,oi,ue,Fe,Le,si,ii,Xr,ai,ci,Qr,Nt,u,$,I,fe,x,en,pi,li,mi,We,he,Ot,tn,E,Be,v=C(()=>{"use strict";Oe();h();At=e=>JSON.parse(Zr(e,"utf-8")),ri=At,ni=(e,t,r)=>ei(e,`${JSON.stringify(t,null,2)}
|
|
9
|
+
`,"utf-8"),oi=["@crossdelta/cloudevents"],ue={services:"services",apps:"apps",packages:"packages",contracts:"packages/contracts"},Fe=e=>{if(!ge(e))return null;try{return JSON.parse(Zr(e,"utf-8"))}catch{return null}},Le=(e,t)=>typeof e=="string"?e:typeof e=="object"&&e!==null&&"path"in e?e.path:t,si=e=>e.split("/").pop()||"workspace",ii=e=>{let t=e.slice(0,e.lastIndexOf("/"));return t===e?null:t},Xr=e=>e.split("."),ai=(e,t)=>{if(!e.workspaces)return!1;if(e.pf||ge(S(t,"turbo.json")))return!0;let r=Or.some(o=>ge(S(t,o))),n=ge(S(t,"infra"));return r&&n},ci=e=>{let t=Fe(S(e,"package.json"));return t?ai(t,e):!1},Qr=e=>{let t=e;for(;t;){if(ci(t))return t;t=ii(t)}return null},Nt=()=>Qr(process.cwd())!==null,u=()=>{let e=Qr(process.cwd());if(!e)throw new Error(`
|
|
10
10
|
\x1B[31m\u2716\x1B[0m Not in a workspace directory
|
|
11
11
|
|
|
12
12
|
Current directory: ${process.cwd()}
|
|
@@ -16,23 +16,23 @@ This command must be run from within a workspace created with \x1B[36mpf new wor
|
|
|
16
16
|
To create a new workspace, run:
|
|
17
17
|
|
|
18
18
|
\x1B[36mpf new workspace my-platform\x1B[0m
|
|
19
|
-
`);return e},$=e=>{let t=e??
|
|
20
|
-
`,encoding:"utf-8"})},he=e=>{let t=Ur();return ri(ti(t,e))},Ot=null,tn=()=>(Ot||(Ot=he("package.json")),Ot),E=new Proxy({},{get:(e,t)=>tn()[t]}),
|
|
21
|
-
`).filter(Boolean);for(let s of o)try{process.kill(Number.parseInt(s,10),"SIGKILL")}catch{}}catch{}}v();var
|
|
19
|
+
`);return e},$=e=>{let t=e??u();return Fe(S(t,"package.json"))},I=e=>{let t=$(e);if(!t?.pf?.paths)return ue;let{paths:r}=t.pf;return{services:Le(r.services,ue.services),apps:Le(r.apps,ue.apps),packages:Le(r.packages,ue.packages),contracts:Le(r.contracts,ue.contracts)}},fe=e=>{let t=$(e);return{plugins:t?.pf?.plugins??oi,dev:{filter:t?.pf?.dev?.filter??[]}}},x=e=>{let t=e??u(),r=I(t),n=S(t,r.contracts),s=Fe(S(n,"package.json"))?.name??`${en()}/contracts`;return{packagePath:n,eventsPath:S(n,"src","events"),indexPath:S(n,"src","index.ts"),relativePath:r.contracts,packageName:s}},en=()=>{let e=u(),t=Fe(S(e,"package.json")),r=`@${si(e)}`;return t?.name?t.name.startsWith("@")?t.name.split("/")[0]:`@${t.name}`:r},pi=(e,t)=>{let r=Xr(t),n=e;for(let o of r){if(n===null||typeof n!="object"||!(o in n))return;n=n[o]}return n},li=(e,t,r)=>{let n=Xr(t),o=n[n.length-1],s=e;for(let i of n.slice(0,-1))(!(i in s)||typeof s[i]!="object"||s[i]===null)&&(s[i]={}),s=s[i];s[o]=r},mi=(e,t=process.cwd())=>{let r=At(S(t,"package.json"));return pi(r,e)},We=(e,t,r=process.cwd())=>{let n=S(r,"package.json"),o=At(n);li(o,e,t),ni(n,o,{spaces:2,EOL:`
|
|
20
|
+
`,encoding:"utf-8"})},he=e=>{let t=Ur();return ri(ti(t,e))},Ot=null,tn=()=>(Ot||(Ot=he("package.json")),Ot),E=new Proxy({},{get:(e,t)=>tn()[t]}),Be=e=>{let t=e??u(),r=I(t),n=S(t,r.services);if(!ge(n))return[];try{return Qs(n,{withFileTypes:!0}).filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>`${r.services}/${s.name}`).sort()}catch{return[]}}});import{argv as ql}from"process";import Te from"chalk";import{Command as Yl}from"commander";import Zl from"terminal-link";J();v();import Oi from"chalk";import{Command as Ai}from"commander";h();import{existsSync as Ei}from"fs";import{join as Ti}from"path";import{cwd as ln}from"process";import{execaSync as $i}from"execa";h();import{spawn as Mt}from"child_process";import{resolve as ki}from"path";import{execa as Ci}from"execa";import{existsSync as di,readFileSync as ui}from"fs";import{resolve as gi}from"path";import{parseEnvContent as fi}from"@crossdelta/infrastructure/env-file";var _t=(e,t)=>{let r=gi(t,e);return di(r)?fi(ui(r,"utf8")):{}},hi=e=>`${(e.includes("/")?e.split("/").pop()??e:e).toUpperCase().replace(/-/g,"_")}_PORT`,nn=(e,t)=>{let r=_t(e,t),n=[];for(let[o,s]of Object.entries(r))if(o.endsWith("_PORT")&&s){let i=Number.parseInt(s,10);!Number.isNaN(i)&&i>0&&n.push({key:o,port:i})}return n},yi=65535,vi=e=>{if(!e||!/^\d+$/.test(e))return;let t=Number.parseInt(e,10);return t>0&&t<=yi?t:void 0},on=(e,t,r)=>{let n=t.filter(i=>!i.startsWith("!"));if(n.length===0)return e.map(i=>i.port);let o=vi(r);if(o!==void 0&&n.length===1)return[o];let s=new Set(n.map(hi));return[...new Set(e.filter(i=>s.has(i.key)).map(i=>i.port))]};var Dt={...process.env,NODE_NO_WARNINGS:"1"},xi=(e,t,r)=>e?"pipe":t||r?["ignore","pipe","pipe"]:"inherit",wi=(e,t,r)=>e?{...Dt,...e}:t||r?{...Dt,CI:"true"}:{...Dt},Pi=e=>e.includes("EEXIST")||e.includes("failed to link package"),K=async(e,t,{cwd:r=process.cwd(),task:n,shell:o,context:s=e,quiet:i=!1,nonInteractive:a=!1,env:c}={})=>{try{t.length===0&&(t=e.split(" ").slice(1));let p=Ci(e,t,{cwd:r,stdio:xi(i,n,a),all:n||a?!0:void 0,shell:o??!0,env:wi(c,n,a)});p.all&&p.all.on("data",l=>{let d=l.toString().trim();n?(n.output=d,d.length&&m.storeLog(d,s)):a&&d.length&&console.log(d)}),await p}catch(p){let l=p instanceof Error?p.message:String(p);if(Pi(l))return;throw new Error(bi(l))}};var bi=e=>{let t=e.match(/error: (.+)/);return t?t[1].trim():e},sn=(e,t,r={})=>{let{cwd:n=process.cwd(),envFile:o,detached:s=!0,pipeStdout:i=!1,onStdout:a,onStderr:c,onExit:p}=r,l=o?_t(o,n):{},d=ki(n,"node_modules",".bin"),T=process.env.PATH||"",Ct=`${d}:${T}`,Ts={...process.env,...l,PATH:Ct,FORCE_COLOR:"1"},$e=Mt(e,t,{cwd:n,env:Ts,stdio:["inherit",i?"pipe":"inherit","pipe"],detached:s});return a&&i&&$e.stdout?.on("data",a),c&&$e.stderr?.on("data",c),p&&$e.on("exit",p),$e},an=(e,t,r={})=>{let{cwd:n=process.cwd()}=r;Mt(e,t,{cwd:n,stdio:"inherit"}).on("exit",s=>process.exit(s||0))},cn=(e,t,r={})=>{let{cwd:n=process.cwd()}=r,o=t.length>0?`${e} ${t.join(" ")}`:e;Mt(o,[],{cwd:n,env:process.env,stdio:"inherit",shell:!0}).on("exit",i=>process.exit(i||0))},pn=async e=>{let{execSync:t}=await import("child_process");for(let r of e)try{let o=t(`lsof -ti:${r}`,{encoding:"utf8",stdio:"pipe"}).trim().split(`
|
|
21
|
+
`).filter(Boolean);for(let s of o)try{process.kill(Number.parseInt(s,10),"SIGKILL")}catch{}}catch{}};v();var He=e=>me(e);var jt=(e=process.cwd())=>{let t=r=>Ei(Ti(e,r));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"},w=e=>jt(e)??Ri(),Ri=()=>He("bun")?"bun":He("pnpm")?"pnpm":He("yarn")?"yarn":"npm",mn=()=>["bun","pnpm","yarn","npm"].filter(He),dn=e=>{let r={bun:"bunx",pnpm:"npx",yarn:"npx",npm:"npx"}[e];if(!r)throw new Error(`No executor found for the detected package manager: ${e}`);let[n,...o]=r.split(" ");return{command:n,args:o}},Ii=(e,t)=>Array.isArray(e)?{packages:e,mergedOptions:{...t,packages:e}}:{packages:e.packages??[],mergedOptions:e},un=(e,t)=>Array.isArray(e)?{args:e,mergedOptions:t??{}}:{args:[],mergedOptions:e},Ni=(e,t)=>typeof e=="string"?{script:e,mergedOptions:t??{}}:{script:e.script,mergedOptions:e},j=async(e,t)=>{let r=Ii(e,t),{mergedOptions:n,packages:o}=r,{cwd:s=process.cwd(),flags:i=[],task:a,quiet:c}=n,p=n.packageManager??w(),l=[],d=Array.isArray(o)?o:[o];p==="bun"&&(d=d.map(Ct=>Ct.replace("git+ssh://",""))),p==="pnpm"&&(l.push("--config.engine-strict=false"),l.push("--no-frozen-lockfile")),["yarn","npm"].includes(p)&&l.push("--ignore-engines");let T=d.length?p==="npm"?["install",...i,...l,...d]:["add",...i,...l,...d]:["install",...i,...l];await K(p,T,{cwd:s,task:a,quiet:c})},gn=async e=>{let t=["-g"],r=[...e.flags??[],...t];await j({...e,flags:r,packageManager:e.packageManager??w()})},fn=(e,t,r)=>{let{args:n,mergedOptions:o}=un(t??[],r),s=o.manager??w(),{command:i,args:a}=dn(s);console.log(`
|
|
22
22
|
Running command: ${i} ${[...a,e,...n].join(" ")}
|
|
23
|
-
`),$i(i,[...a,e,...n],{cwd:o.cwd??ln(),stdio:"inherit",preferLocal:!0})}async
|
|
23
|
+
`),$i(i,[...a,e,...n],{cwd:o.cwd??ln(),stdio:"inherit",preferLocal:!0})},Lt=async(e,t,r)=>{let{args:n,mergedOptions:o}=un(t??[],r),s=o.manager??w(),{command:i,args:a}=dn(s);await K(i,[...a,e,...n],o)},ye=async(e,t)=>{let{script:r,mergedOptions:n}=Ni(e,t),o=n.packageManager??w();await K(o,["run",r,...n.args??[]],{cwd:n.cwd??ln(),task:n.task})};var _i=e=>e==="yarn"?["npm","audit"]:["audit"],hn=new Ai("audit").description("Run security audit on dependencies").allowUnknownOption(!0).action((e,t)=>{try{let r=u(),n=w(),o=_i(n),s=t.args||[];console.log(Oi.dim(`Running ${n} ${[...o,...s].join(" ")}`)),an(n,[...o,...s],{cwd:r})}catch(r){A(r)}});import pe from"chalk";h();import{promises as Ft}from"fs";import Ge from"path";import yn from"chalk";var vn=async e=>{await K("bash",["-c",`
|
|
24
24
|
curl -fsSL https://bun.sh/install | bash && if [ -f "$HOME/.bun/bin/bun" ]; then export PATH="$HOME/.bun/bin:$PATH"; fi
|
|
25
25
|
`],{task:e,shell:!0}),await Di()},Wt=()=>me("bun"),kn=()=>bt([{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"}),Cn=()=>bt([{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:yn.blackBright("* Installing dependencies from cache for a Remix app."),barColor:"blackBright"}),Di=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 r=[Ge.join(t,".zshrc"),Ge.join(t,".bashrc"),Ge.join(t,".bash_profile")];for(let n of r)try{if(await Ft.stat(n).then(()=>!0).catch(()=>!1)){(await Ft.readFile(n,"utf8")).includes(e)||(await Ft.appendFile(n,`
|
|
26
26
|
# Added by platform installer
|
|
27
27
|
${e}
|
|
28
|
-
`),m.log(`Added Bun path to ${Ge.basename(n)}`));return}}catch(o){m.error(`Failed to update ${n}: ${o.message}`)}m.warn("No shell config file (.zshrc, .bashrc, .bash_profile) found. Please add the following manually:"),m.log(yn.cyan(e))};v();import{existsSync as Je,mkdirSync as ta,readFileSync as ra,renameSync as na,statSync as Rn,unlinkSync as oa,writeFileSync as sa}from"fs";import{join as Ce}from"path";import{existsSync as
|
|
28
|
+
`),m.log(`Added Bun path to ${Ge.basename(n)}`));return}}catch(o){m.error(`Failed to update ${n}: ${o.message}`)}m.warn("No shell config file (.zshrc, .bashrc, .bash_profile) found. Please add the following manually:"),m.log(yn.cyan(e))};v();import{existsSync as Je,mkdirSync as ta,readFileSync as ra,renameSync as na,statSync as Rn,unlinkSync as oa,writeFileSync as sa}from"fs";import{join as Ce}from"path";import{existsSync as Mi}from"fs";import{join as ji}from"path";import Ue from"chalk";v();import Bt from"chalk";var q=e=>{let t=Math.max(...e.commands.map(o=>o.name.length)),r=e.commands.map(o=>{let s=" ".repeat(t-o.name.length+3);return` ${Bt.cyan(o.name)}${s}${o.description}`}),n=e.footer||'Run "<command> --help" for more information';return[Bt.cyan.bold(`
|
|
29
29
|
${e.title}
|
|
30
30
|
`),`Available commands:
|
|
31
|
-
`,...r,"",
|
|
31
|
+
`,...r,"",Bt.dim(`${n}
|
|
32
32
|
`)].join(`
|
|
33
|
-
`)};var
|
|
33
|
+
`)};var Li=(e,t)=>t.some(r=>r.name()===e),Fi=(e,t)=>t.pf?.commands?.[e]??null,Wi=(e,t)=>!!t.scripts?.[e],Bi=(e,t)=>t.cwd?ji(e,t.cwd):e,Hi=(e,t)=>t.command||e,Gi=(e,t,r,n)=>{let o=Bi(n,r),s=Hi(e,r);if(r.cwd&&!Mi(o))return console.error(Ue.red(`
|
|
34
34
|
\u2716 Directory not found: ${o}
|
|
35
|
-
`)),!0;let i=r.cwd?Ue.dim(` in ${r.cwd}/`):"";return console.log(Ue.dim(`Running ${s}${i}`)),cn(s,t,{cwd:o}),!0},Ui=(e,t,r)=>(console.log(Ue.dim(`Running workspace script: ${e}`)),ye(e,{args:t,cwd:r}),!0)
|
|
35
|
+
`)),!0;let i=r.cwd?Ue.dim(` in ${r.cwd}/`):"";return console.log(Ue.dim(`Running ${s}${i}`)),cn(s,t,{cwd:o}),!0},Ui=(e,t,r)=>(console.log(Ue.dim(`Running workspace script: ${e}`)),ye(e,{args:t,cwd:r}),!0),Vi=async(e,t,r)=>{if(Li(e,r))return!1;let n;try{n=u()}catch{return!1}let o=$(n);if(!o)return!1;let s=Fi(e,o);return s?Gi(e,t,s,n):Wi(e,o)?Ui(e,t,n):!1},xn=()=>{let e;try{e=$()}catch{return{configured:[],scripts:[]}}if(!e)return{configured:[],scripts:[]};let t=Object.keys(e.pf?.commands??{}),n=Object.keys(e.scripts??{}).filter(o=>!t.includes(o));return{configured:t,scripts:n}},Ht=()=>{let{configured:e,scripts:t}=xn();return[...e,...t]},wn=()=>{let{configured:e,scripts:t}=xn(),r=[...e,...t];if(r.length===0)return"";let o=$()?.pf?.commands||{},s=r.map(i=>({name:i,description:o[i]?.description||Ve[i]||""}));return q({title:"Workspace Commands",commands:s,footer:""})},Pn=(e,t,r)=>{let n=t.slice(2);if(n.length>0&&!n[0].startsWith("-")){let o=n[0],s=n.slice(1);if(o==="__workspace-commands"&&s.includes("--names-only")){let i=Ht();for(let a of i)console.log(a);return}Vi(o,s,r).then(i=>{i||e.parse(t)})}else e.parse(t)};import{existsSync as Gt,readdirSync as Ki}from"fs";import{dirname as qi,join as bn}from"path";import{dirname as Ji}from"path";import{fileURLToPath as zi}from"url";var L=e=>Ji(zi(e));Rt();var Yi=()=>typeof import.meta?.url=="string"?L(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),H=e=>{let t=e??Yi(),r=o=>Gt(bn(o,"package.json")),n=qi(t);if(r(t))return t;if(t==="/")throw new Error("Could not find package.json (package root)");return H(n)},Sn=(e,t)=>{let r=e.find(Gt);if(!r)throw new Error(t??`Directory not found. Searched in: ${e.join(", ")}`);return r},En=async e=>{let{getWorkspacePathsConfig:t}=await Promise.resolve().then(()=>(v(),rn)),r=t(e);return[r.services,r.apps].flatMap(o=>{let s=bn(e,o);if(!Gt(s))return[];try{return Ki(s,{withFileTypes:!0}).filter(i=>i.isDirectory()&&i.name!==".gitkeep").map(i=>`${o}/${i.name}`)}catch{return[]}})};v();var Tn={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"},Ve={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"},$n=(e,t)=>t?`${e}:${t}`:e,Zi=()=>Object.entries(Tn).map(([e,t])=>$n(e,t)),Xi=()=>{try{let e=Ht(),r=$()?.pf?.commands||{},n=Object.keys(Tn);return e.filter(o=>!n.includes(o)).map(o=>{let s=r[o]?.description||Ve[o]||"";return $n(o,s)})}catch{return[]}},Qi=()=>{try{let e=u(),t=x(e),r=`${e}/${t.relativePath}/src`,{discoverEventTypes:n}=xt("@crossdelta/cloudevents");return n(r)}catch{return[]}},ea=async()=>{try{let e=u();return await En(e)}catch{return[]}},Ut=async()=>({commands:[...Zi(),...Xi()],events:Qi(),services:await ea()});var ve="node_modules/.cache/pf",ke="completion-cache";var ia=e=>{let t=E.version||"0.0.0",r=e.commands.join("|"),n=e.events.join("|"),o=e.services.join("|");return`${t} ${r} ${n} ${o}`},aa=e=>{let t=e.split(" ");if(t.length===4){let[o,s,i,a]=t;return{version:o,commands:s?s.split("|"):[],events:i?i.split("|"):[],services:a?a.split("|"):[]}}if(t.length===3){let[o,s,i]=t;return{version:o,commands:s?s.split("|"):[],events:i?i.split("|"):[],services:[]}}let[r,n]=t;return{commands:r?r.split("|"):[],events:n?n.split("|"):[],services:[]}},ca=e=>{let t=Ce(e,ve);return Ce(t,ke)},pa=(e,t=!1)=>{if(t)return!0;let r=ca(e);if(!Je(r))return!0;let n=ra(r,"utf-8").trim(),o=aa(n),s=E.version||"0.0.0";if(o.version!==s)return!0;let i=Ce(e,"package.json");if(!Je(i))return!1;let a=Rn(r).mtimeMs;return Rn(i).mtimeMs>a};var la=(e,t)=>{let r=Ce(e,ve),n=Ce(r,ke),o=`${n}.tmp.${process.pid}`;Je(r)||ta(r,{recursive:!0});let s=ia(t);try{sa(o,s,"utf-8"),na(o,n)}catch(i){try{Je(o)&&oa(o)}catch{}throw i}},ze=async(e={})=>{let t;try{t=u()}catch{return!1}if(!t)return!1;if(!pa(t,e.force))return e.verbose&&console.log("[completion] Cache is up to date"),!1;let r=await Ut();return la(t,r),e.verbose&&console.log(`[completion] Cache regenerated: ${r.commands.length} commands, ${r.events.length} events`),!0},xe=async(e={})=>{await ze({...e,force:!0})};import{existsSync as Jt,readFileSync as _n,writeFileSync as Dn}from"fs";import{homedir as Mn}from"os";import{join as Vt}from"path";import Y from"chalk";var In=`${ve}/${ke}`,Nn=e=>`# ${e} completion (workspace-local cache)
|
|
36
36
|
# Generated: ${new Date().toISOString()}
|
|
37
37
|
|
|
38
38
|
# Cache file path (relative to workspace root)
|
|
@@ -261,13 +261,13 @@ _${e}_completions() {
|
|
|
261
261
|
return 0
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
-
complete -F _${e}_completions ${e}`;var ma=(e,t)=>Vt(
|
|
264
|
+
complete -F _${e}_completions ${e}`;var ma=(e,t)=>Vt(Mn(),`.${t}-completion.${e}`),jn=e=>{let t=Mn();return e==="zsh"?Vt(t,".zshrc"):Vt(t,".bashrc")},da=e=>`[[ -f "${e}" ]] && source "${e}"`,ua=(e,t)=>Jt(e)?_n(e,"utf-8").includes(t):!1,ga=(e,t)=>{let r=Jt(e)?_n(e,"utf-8"):"",n=r.endsWith(`
|
|
265
265
|
`)?`${r}${t}
|
|
266
266
|
`:`${r}
|
|
267
267
|
${t}
|
|
268
|
-
`;Dn(e,n,"utf-8")},fa=(e,t)=>{let r=ma(e,t),n=e==="zsh"?Nn(t):On(t);return Dn(r,n,"utf-8"),r},An=(e,t,r)=>{let n=fa(e,t),o=
|
|
268
|
+
`;Dn(e,n,"utf-8")},fa=(e,t)=>{let r=ma(e,t),n=e==="zsh"?Nn(t):On(t);return Dn(r,n,"utf-8"),r},An=(e,t,r)=>{let n=fa(e,t),o=jn(e),s=da(n);return ua(o,s)?(r&&console.log(Y.dim(`[${e}] Already configured in ${o}`)),!1):(ga(o,s),r&&console.log(Y.green(`[${e}] Added source line to ${o}`)),!0)},ha=()=>(process.env.SHELL||"").includes("zsh")?"zsh":"bash",zt=(e,t=!1)=>{let r=ha();t&&console.log(Y.cyan(`Installing ${r} completion...`)),An(r,e,t);let n=r==="zsh"?"bash":"zsh",o=jn(n);Jt(o)&&An(n,e,t),t&&(console.log(Y.green("\u2713 Shell completion installed")),console.log(Y.dim(` Run: ${Y.cyan("exec $SHELL")} to reload`)))};J();import{readdir as qf}from"fs/promises";import{dirname as Zf,join as Xf}from"path";import{fileURLToPath as eh}from"url";import{runFlow as rh}from"@crossdelta/flowcore";var ya={debug:()=>{},info:console.log,warn:console.warn,error:console.error},Ln=e=>e!==null&&typeof e=="object",Fn=e=>typeof e=="string"&&e.length>0,Wn=e=>typeof e=="string",Kt=e=>typeof e=="function",va=(e,t)=>Ln(e)?[!Fn(e.name)&&`commands[${t}]: missing or invalid 'name'`,!Wn(e.description)&&`commands[${t}]: missing or invalid 'description'`,!Array.isArray(e.args)&&`commands[${t}]: missing 'args' array`,!Array.isArray(e.options)&&`commands[${t}]: missing 'options' array`,!Kt(e.run)&&`commands[${t}]: missing 'run' function`].filter(r=>r!==!1):[`commands[${t}]: must be an object`];var Bn=e=>{if(!Ln(e))return["Plugin must be an object"];let t=[!Fn(e.name)&&"Missing or invalid 'name'",!Wn(e.version)&&"Missing or invalid 'version'",!Array.isArray(e.commands)&&"Missing 'commands' array",!Array.isArray(e.flows)&&"Missing 'flows' array",!Kt(e.setup)&&"Missing 'setup' function"].filter(n=>n!==!1),r=Array.isArray(e.commands)?e.commands.flatMap((n,o)=>va(n,o)):[];return[...t,...r]},Ke=(e,t=ya)=>({workspace:e,logger:t}),qe=async(e,t)=>{let{logger:r}=t;r.debug(`Loading plugin from module: ${e}`);let n=await import(e),o=n.createPfPlugin||n.default?.createPfPlugin;if(!Kt(o))throw new Error(`Module ${e} does not export createPfPlugin`);let s=o({contractsPath:t.workspace.contracts.path,contractsPackage:t.workspace.contracts.packageName,availableServices:t.workspace.availableServices}),i=Bn(s);if(i.length>0)throw new Error(`Plugin from ${e} does not conform to PfPlugin interface:
|
|
269
269
|
- ${i.join(`
|
|
270
|
-
- `)}`);let a=s;return r.debug(`Loaded plugin: ${a.name} v${a.version}`),await a.setup(t),{plugin:a,source:e}};import{deriveEventNames as
|
|
270
|
+
- `)}`);let a=s;return r.debug(`Loaded plugin: ${a.name} v${a.version}`),await a.setup(t),{plugin:a,source:e}};import{deriveEventNames as ih}from"@crossdelta/cloudevents";import{z as f}from"zod";var Ye=f.object({dependencies:f.record(f.string(),f.string()).default({}),envVars:f.array(f.object({key:f.string(),description:f.string(),required:f.boolean().default(!0)})).default([]),adapterFile:f.string().optional()}),ka=f.object({push:f.string().optional(),email:f.string().optional(),slack:f.string().optional(),sms:f.string().optional()}).optional(),Ca=f.object({defaults:ka,providers:f.object({push:f.record(f.string(),Ye).optional(),email:f.record(f.string(),Ye).optional(),slack:f.record(f.string(),Ye).optional(),sms:f.record(f.string(),Ye).optional()}).optional()}),Zu=f.object({notifier:Ca.optional()});import{z as g}from"zod";var xa=g.object({type:g.literal("event"),eventType:g.string(),stream:g.string().optional()}),wa=g.object({type:g.literal("http"),method:g.enum(["GET","POST","PUT","DELETE","PATCH"]).optional(),path:g.string().optional()}),Hn=g.discriminatedUnion("type",[xa,wa]),Pa=g.object({type:g.literal("emit.event"),eventType:g.string()}),ba=g.object({type:g.literal("notify"),channel:g.enum(["push","email","slack","sms"]),provider:g.string().optional()}),Sa=g.object({type:g.literal("call.http"),name:g.string().optional(),baseUrl:g.string().optional()}),Ea=g.object({type:g.literal("persist"),store:g.enum(["db","kv","cache"]),entity:g.string().optional()}),Gn=g.discriminatedUnion("type",[Pa,ba,Sa,Ea]),Un=g.object({serviceName:g.string().regex(/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/),framework:g.enum(["hono","nest"]).default("hono"),triggers:g.array(Hn).min(1),actions:g.array(Gn).default([])});v();import{existsSync as X,mkdirSync as Ma,readFileSync as qt,writeFileSync as we}from"fs";import{dirname as Jn,join as Z}from"path";import{deriveEventNames as ja}from"@crossdelta/cloudevents";var La=(e,t)=>{let r=`export * from './${t}'`;if(!X(e)){let s=Jn(e);X(s)||Ma(s,{recursive:!0});let i=`/**
|
|
271
271
|
* ${Jn(e).split("/").pop()} Domain Events
|
|
272
272
|
*/
|
|
273
273
|
|
|
@@ -286,7 +286,7 @@ ${r}
|
|
|
286
286
|
`),"utf-8"),!0},Wa=e=>{if(!X(e))return!1;let t=qt(e,"utf-8"),r="export * from './events'";if(t.split(`
|
|
287
287
|
`).some(s=>s.trim()===r||s.trim().startsWith(r)))return!1;let o=t;return o=o.replace(/\/\/\s*export \* from '\.\/events'/,r),o=o.replace(/\/\/\s*export \* from '\.\/stream-policies'/,"export * from './stream-policies'"),/export \* from '\.\/events\/\w+\/\w+'/.test(o)&&(o=o.replace(/export \* from '\.\/events\/\w+\/\w+'\n?/g,"")),o.includes(r)||(o=`${o.trimEnd()}
|
|
288
288
|
${r}
|
|
289
|
-
`),o!==t?(we(e,o,"utf-8"),!0):!1},zn=(e,t)=>{let{packagePath:r}=x(t),{domain:n,action:o}=
|
|
289
|
+
`),o!==t?(we(e,o,"utf-8"),!0):!1},zn=(e,t)=>{let{packagePath:r}=x(t),{domain:n,action:o}=ja(e),s=Z(r,"src","events");if(!X(s))return!1;let i=Z(s,n),a=Z(i,"index.ts"),c=Z(s,"index.ts"),p=Z(r,"src","index.ts"),l=e.split(".")[0],d=Z(s,l);l!==n&&X(d)&&(console.warn(`\u26A0\uFE0F Warning: Legacy folder '${l}/' found. Please migrate to '${n}/' to avoid conflicts.`),console.warn(` Run: mv ${d} ${i}`));let T=!1;return La(a,o)&&(T=!0),Fa(c,n)&&(T=!0),Wa(p)&&(T=!0),T};import{existsSync as Ze,readFileSync as Kn,writeFileSync as Ba}from"fs";import{join as Yt}from"path";import{getStreamName as Ha}from"@crossdelta/cloudevents";var Ga=(e,t)=>{let r=Yt(e,"src","index.ts");if(!Ze(r))return!1;let n=Kn(r,"utf-8"),o=t.toLowerCase();return new RegExp(`streams:\\s*\\[[^\\]]*['"]${t}['"]`).test(n)||n.includes(`stream: '${t}'`)?!0:new RegExp(`subjects:\\s*\\[.*['"]${o}\\.[*>]`).test(n)},Ua=e=>{if(e.includes("@crossdelta/cloudevents"))return e;let t=`import { consumeJetStreams } from '@crossdelta/cloudevents'
|
|
290
290
|
`,r=e.match(/import\s+['"]@crossdelta\/telemetry['"]\s*\n/);if(r){let o=(r.index??0)+r[0].length;return`${e.slice(0,o)}
|
|
291
291
|
${t}${e.slice(o)}`}let n=e.match(/import\s+.*\n/);if(n){let o=(n.index??0)+n[0].length;return e.slice(0,o)+t+e.slice(o)}return e},Va=(e,t)=>`
|
|
292
292
|
|
|
@@ -295,8 +295,8 @@ consumeJetStreams({
|
|
|
295
295
|
streams: ['${e}'],
|
|
296
296
|
consumer: '${t}-service',
|
|
297
297
|
discover: './src/events/**/*.handler.ts',
|
|
298
|
-
})`,qn=(e,t)=>{let r=
|
|
299
|
-
`;return
|
|
298
|
+
})`,qn=(e,t)=>{let r=Ha(t),n=Yt(e,"src","index.ts"),o=Yt(e,"src","main.ts");if(!Ze(n)&&Ze(o))return{added:!1,streamName:r};if(!Ze(n))return{added:!1,streamName:r,warning:"Entry point not found (index.ts or main.ts)"};if(Ga(e,r))return{added:!1,streamName:r};let s=Kn(n,"utf-8"),i=e.split("/").pop()||"unknown";s.includes("consumeJetStreams")||(s=Ua(s));let a=Va(r,i),c=`${s.trimEnd()+a}
|
|
299
|
+
`;return Ba(n,c,"utf-8"),{added:!0,streamName:r}};var Ja=(e,t,r)=>{let{stream:n,servicePath:o}=e,s=o.startsWith("/")?o:`${t.workspace.workspaceRoot}/${o}`;if(r?.dryRun)return{success:!0,message:`Would wire stream ${n} to ${o}`,changes:[{type:"update",path:s,description:`Wire ${n} stream to service`,preview:`consumeJetStreams({ streams: ['${n.toUpperCase()}'], ... })`}]};let i=qn(s,`${n.toLowerCase()}.event`);return i.warning?(t.logger.warn(i.warning),{success:!1,message:i.warning}):i.added?(t.logger.info(`Wired stream ${i.streamName} to service`),{success:!0,message:`Wired stream ${i.streamName}`}):(t.logger.debug(`Stream ${i.streamName} already wired`),{success:!0,message:`Stream ${i.streamName} already configured`})},za=(e,t,r)=>{let{path:n,eventType:o}=e;if(r?.dryRun){let i=`
|
|
300
300
|
import { createContract } from '@crossdelta/cloudevents'
|
|
301
301
|
import { z } from 'zod'
|
|
302
302
|
|
|
@@ -312,7 +312,7 @@ export default handleEvent(${Zt(o)}Contract, async (data) => {
|
|
|
312
312
|
console.log('Processing ${o}:', data)
|
|
313
313
|
// TODO: Implement handler logic
|
|
314
314
|
})
|
|
315
|
-
`.trim();return{success:!0,message:`Would create handler for ${o}`,changes:[{type:"create",path:n,description:`Create event handler for ${o}`,preview:i.slice(0,500)}]}}return t.logger.debug(`Handler created: ${o} at ${n} (service: ${s})`),{success:!0}},qa={"stream.wired":Ja,"contract.created":za,"handler.created":Ka},Xt=(e,t,r)=>e.map(n=>{let o=qa[n.kind];return o?o(n,t,r):(t.logger.warn(`Unknown effect kind: ${n.kind}`),{success:!1,message:`Unknown effect kind: ${n.kind}`})});import{join as rt}from"path";import{deriveEventNames as
|
|
315
|
+
`.trim();return{success:!0,message:`Would create handler for ${o}`,changes:[{type:"create",path:n,description:`Create event handler for ${o}`,preview:i.slice(0,500)}]}}return t.logger.debug(`Handler created: ${o} at ${n} (service: ${s})`),{success:!0}},qa={"stream.wired":Ja,"contract.created":za,"handler.created":Ka},Xt=(e,t,r)=>e.map(n=>{let o=qa[n.kind];return o?o(n,t,r):(t.logger.warn(`Unknown effect kind: ${n.kind}`),{success:!1,message:`Unknown effect kind: ${n.kind}`})});import{join as rt}from"path";import{deriveEventNames as Lc}from"@crossdelta/cloudevents";var Qt=(e,t,r={})=>({ok:!0,operation:e,summary:t,artifacts:r.artifacts??[],changes:r.changes??[],diagnostics:r.diagnostics??[],next:r.next,data:r.data});v();import{join as tr}from"path";import{readFileSync as Ya}from"fs";import{join as Za}from"path";import Xa from"handlebars";var Q=(e,t)=>Sn(e,t??`Templates directory not found. Searched in: ${e.join(", ")}`),er=(e,t={})=>{let r=Ya(e,"utf-8");return Xa.compile(r)(t)},Xe=e=>(t,r={})=>{let n=Za(e,t);return er(n,r)};var D=e=>e.toUpperCase().replace(/-/g,"_");var Yn=e=>e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ");var Qa=()=>typeof import.meta?.url=="string"?L(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),ec=()=>{let e=Qa(),t=H();return Q([tr(e,"templates","hono-microservice"),tr(e,"..","hono-microservice","templates"),tr(t,"bin","templates","hono-microservice")],"Hono templates directory not found.")},Qe=(e,t={})=>Xe(ec())(e,t),Zn=()=>Qe("tsconfig.json.hbs"),Xn=(e="1.2.23")=>Qe("Dockerfile.hbs",{bunVersion:e}),Qn=()=>Qe("biome.json.hbs");var eo=(e,t=[])=>Qe("src/config/env.ts.hbs",{envKey:D(e),envVars:t});var tc=e=>{let t=["import './config/env'","import '@crossdelta/telemetry'",""];return e&&t.push("import { consumeJetStreams, isConsumerConnected } from '@crossdelta/cloudevents'"),t.push("import { Hono } from 'hono'"),t},rc=(e,t)=>{let r=[`const port = Number(process.env.${e}_PORT) || 8080`,"const app = new Hono()","","app.get('/health', (c) => {"," return c.json({ status: 'ok' })","})"];return t&&r.push("","app.get('/health/ready', (c) => {"," const ready = isConsumerConnected()"," return c.json({ status: ready ? 'ok' : 'not-ready' }, ready ? 200 : 503)","})"),r},nc=(e,t)=>["","// Start NATS JetStream consumer","consumeJetStreams({",` streams: [${t.map(r=>`'${r}'`).join(", ")}],`,` consumer: '${e}',`," discover: './src/events/**/*.handler.ts',","})"],oc=()=>["","Bun.serve({"," port,"," fetch: app.fetch,","})","","console.log(`\u{1F680} Service ready at http://localhost:${port}`)"],sc=e=>{let t=D(e.serviceName);return`${[...tc(e.hasEvents),"",...rc(t,e.hasEvents),...e.hasEvents?nc(e.serviceName,e.streams):[],...oc()].join(`
|
|
316
316
|
`)}
|
|
317
317
|
`},ic=e=>{let t={hono:"^4.6.14","@crossdelta/telemetry":"workspace:*",zod:"^4.1.0",[`${e.workspaceScope}/contracts`]:"workspace:*"};e.hasEvents&&(t["@crossdelta/cloudevents"]="workspace:*");let r={name:e.packageName,version:"0.0.1",type:"module",scripts:{"start:dev":"bun --watch src/index.ts",start:"bun src/index.ts",test:"bun test"},dependencies:t,devDependencies:{"@types/bun":"^1.2.23"}};return JSON.stringify(r,null,2)},ac=e=>`# ${e.serviceName}
|
|
318
318
|
|
|
@@ -334,7 +334,7 @@ ${e.hasEvents?`
|
|
|
334
334
|
This service consumes from:
|
|
335
335
|
${e.streams.map(t=>`- ${t}`).join(`
|
|
336
336
|
`)}`:""}
|
|
337
|
-
`,cc=()=>"",to={name:"hono-bun",runtime:"bun",framework:"hono",files:[{path:"src/index.ts",content:sc},{path:"src/config/env.ts",content:e=>eo(e.serviceName,e.envVars)},{path:"package.json",content:ic},{path:"tsconfig.json",content:()=>Zn()},{path:"Dockerfile",content:()=>Xn()},{path:"biome.json",content:()=>Qn()},{path:"README.md",content:ac},{path:"src/events/.gitkeep",content:cc,skip:e=>!e.hasEvents}]};import{join as rr}from"path";var pc=()=>typeof import.meta?.url=="string"?
|
|
337
|
+
`,cc=()=>"",to={name:"hono-bun",runtime:"bun",framework:"hono",files:[{path:"src/index.ts",content:sc},{path:"src/config/env.ts",content:e=>eo(e.serviceName,e.envVars)},{path:"package.json",content:ic},{path:"tsconfig.json",content:()=>Zn()},{path:"Dockerfile",content:()=>Xn()},{path:"biome.json",content:()=>Qn()},{path:"README.md",content:ac},{path:"src/events/.gitkeep",content:cc,skip:e=>!e.hasEvents}]};import{join as rr}from"path";var pc=()=>typeof import.meta?.url=="string"?L(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),lc=()=>{let e=pc(),t=H();return Q([rr(e,"templates","nest-microservice"),rr(e,"..","nest-microservice","templates"),rr(t,"bin","templates","nest-microservice")],"NestJS templates directory not found.")},G=(e,t={})=>Xe(lc())(e,t),ro=(e,t=3e3)=>G("src/main.ts.hbs",{serviceName:e,envKey:D(e),displayName:Yn(e),defaultPort:t}),no=()=>G("src/app.context.ts.hbs",{}),oo=()=>G("src/events/events.module.ts.hbs",{}),so=e=>G("src/events/events.service.ts.hbs",{serviceName:e}),io=(e="24",t="1.2.23")=>G("Dockerfile.hbs",{nodeVersion:e,bunVersion:t}),ao=()=>G("biome.json.hbs",{}),co=(e,t=[])=>G("src/config/env.ts.hbs",{envKey:D(e),envVars:t});var mc=e=>{let t={"@nestjs/common":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/platform-express":"^11.0.0","@crossdelta/telemetry":"workspace:*","reflect-metadata":"^0.2.0",rxjs:"^7.8.0",zod:"^4.1.0",[`${e.workspaceScope}/contracts`]:"workspace:*"};e.hasEvents&&(t["@crossdelta/cloudevents"]="workspace:*");let r={name:e.packageName,version:"0.0.1",scripts:{"start:dev":"bun --watch src/main.ts",start:"node dist/main.js",build:"tsc",test:"bun test"},dependencies:t,devDependencies:{"@nestjs/cli":"^11.0.0","@types/node":"^24.0.0",typescript:"^5.7.0"}};return JSON.stringify(r,null,2)},dc=()=>JSON.stringify({extends:"../../../../tsconfig.json",compilerOptions:{outDir:"./dist",rootDir:"./src",experimentalDecorators:!0,emitDecoratorMetadata:!0},include:["src/**/*"],exclude:["node_modules","dist","**/*.test.ts"]},null,2),uc=e=>{let t=["Module","HttpModule"],r=["HttpModule"];return e.hasEvents&&(t.push("OnModuleInit"),r.push("EventsModule")),`import { ${t.join(", ")} } from '@nestjs/common'
|
|
338
338
|
${e.hasEvents?"import { EventsModule } from './events/events.module'":""}
|
|
339
339
|
|
|
340
340
|
@Module({
|
|
@@ -376,7 +376,7 @@ ${e.hasEvents?`
|
|
|
376
376
|
This service consumes from:
|
|
377
377
|
${e.streams.map(t=>`- ${t}`).join(`
|
|
378
378
|
`)}`:""}
|
|
379
|
-
`,hc=()=>"",po={name:"nest",runtime:"node",framework:"nest",files:[{path:"src/config/env.ts",content:e=>co(e.serviceName,e.envVars)},{path:"src/main.ts",content:e=>ro(e.serviceName,e.port)},{path:"src/app.module.ts",content:
|
|
379
|
+
`,hc=()=>"",po={name:"nest",runtime:"node",framework:"nest",files:[{path:"src/config/env.ts",content:e=>co(e.serviceName,e.envVars)},{path:"src/main.ts",content:e=>ro(e.serviceName,e.port)},{path:"src/app.module.ts",content:uc},{path:"src/app.controller.ts",content:()=>gc()},{path:"src/app.context.ts",content:()=>no()},{path:"package.json",content:mc},{path:"tsconfig.json",content:()=>dc()},{path:"Dockerfile",content:()=>io()},{path:"biome.json",content:()=>ao()},{path:"README.md",content:fc},{path:"src/events/events.module.ts",content:()=>oo(),skip:e=>!e.hasEvents},{path:"src/events/events.service.ts",content:e=>so(e.serviceName),skip:e=>!e.hasEvents},{path:"src/events/handlers/.gitkeep",content:hc,skip:e=>!e.hasEvents}]};var lo=[to,po],mo=e=>{let t=yc(e),r=lo.find(n=>n.name===t);if(!r)throw new Error(`Template '${e}' not found. Available: ${lo.map(n=>n.name).join(", ")}`);return r},yc=e=>({"hono-micro":"hono-bun","nest-micro":"nest"})[e]||e;import{join as or}from"path";import{deriveEventNames as sr}from"@crossdelta/cloudevents";var uo={appliesTo:["src/domain","src/use-cases"],forbiddenPatterns:[{pattern:"console\\.(log|error|warn|info|debug)\\s*\\(",description:"console.* is forbidden in business logic (use structured logging)",code:"CONSOLE_IN_DOMAIN"},{pattern:"process\\.env\\b",description:"process.env is forbidden in business logic (use dependency injection)",code:"PROCESS_ENV_IN_DOMAIN"},{pattern:"\\bfetch\\s*\\(",description:"fetch() is forbidden in business logic (use adapters/services)",code:"FETCH_IN_DOMAIN"}]},Pe={hono:{businessLogicDir:"use-cases",eventsDir:"events",filePattern:"{name}.use-case.ts",suffix:"use-case",handlerDelegatesToBusinessLogic:!0,pathGuards:{forbidDirs:["src/services"]},codingConstraints:uo},nestjs:{businessLogicDir:"",eventsDir:"events",filePattern:"{name}.service.ts",suffix:"service",handlerDelegatesToBusinessLogic:!1,pathGuards:{forbidDirs:[]},codingConstraints:{appliesTo:["src/domain"],forbiddenPatterns:uo.forbiddenPatterns}}},vc=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),kc=(e,t)=>`../${e}/${t}`,ee=(e,t)=>{let r=Pe[e],n=r.filePattern.replace("{name}",t),o=n.replace(/\.ts$/,""),s=r.businessLogicDir?`src/${r.businessLogicDir}`:"src";return{filePath:s?`${s}/${n}`:`src/${n}`,dirPath:s,fileName:n,functionName:vc(t),delegateFromHandler:r.handlerDelegatesToBusinessLogic,importFromEvents:r.businessLogicDir?kc(r.businessLogicDir,o):`./${o}`}},nr=(e,t)=>{let n=`src/${Pe[e].eventsDir}`,o=`${t}.handler.ts`;return{filePath:`${n}/${o}`,dirPath:n,fileName:o}},be=e=>`handle-${e.replace(/\./g,"-")}`,et=e=>{let t=e.replace(/\\/g,"/");t=t.replace(/^\.\//,"").replace(/^\//,"");let r=t.split("/"),n=[];for(let o of r)o===".."?n.pop():o!=="."&&o!==""&&n.push(o);return n.join("/")},Cc=(e,t)=>{let r=et(e);for(let n of t){let o=et(n);if(r.startsWith(`${o}/`)||r===o)return n}return null},xc=(e,t)=>{let r=et(e);return t.some(n=>{let o=et(n);return r.startsWith(`${o}/`)||r===o})},wc=(e,t,r)=>{let n=[],o=e.split(`
|
|
380
380
|
`);for(let{pattern:s,description:i,code:a}of t){let c=new RegExp(s,"g");for(let p=0;p<o.length;p++)c.test(o[p])&&n.push({code:a,message:i,path:r,line:p+1}),c.lastIndex=0}return n},Pc=(e,t)=>{let r=[],n=Cc(e.path,t.pathGuards.forbidDirs);if(n&&r.push({code:"FORBIDDEN_DIR",message:`Path '${e.path}' is in forbidden directory '${n}'`,path:e.path}),xc(e.path,t.codingConstraints.appliesTo)){let o=wc(e.content,t.codingConstraints.forbiddenPatterns,e.path);r.push(...o)}return r},tt=(e,t)=>{let r=Pe[e],n=[];for(let o of t)n.push(...Pc(o,r));return{valid:n.length===0,violations:n}};var Ec=(e,t)=>t.map(r=>({kind:"file:write",path:or(e,r.path),content:r.content})),Tc=(e,t,r)=>({kind:"infra:add",serviceName:e,port:t,framework:r.framework,runtime:r.runtime}),$c=(e,t)=>({kind:"env:add",key:`${e}_PORT`,value:t.toString()}),Rc=(e,t)=>{let{typeName:r}=sr(e),n=be(e),o=ee("hono",n);return`import type { ${r} } from '${t}/contracts'
|
|
381
381
|
|
|
382
382
|
/**
|
|
@@ -404,13 +404,13 @@ export default handleEvent(${n}, async (data: ${o}) => {
|
|
|
404
404
|
console.log('\u{1F4E6} [${e}] Event received:', data)
|
|
405
405
|
// TODO: Inject and call service
|
|
406
406
|
})
|
|
407
|
-
`},Nc=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:ee(r,"stub").delegateFromHandler?t.events.map(o=>{let s=be(o),i=ee(r,s);return{kind:"file:write",path:or(e,i.filePath),content:Rc(o,t.workspaceScope)}}):[],Oc=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:t.events.map(n=>{let{kebab:o}=sr(n),s=nr(r,o);return{kind:"file:write",path:or(e,s.filePath),content:Ic(n,t.workspaceScope,r)}}),Ac=e=>e==="hono"?"hono":e==="nest"?"nestjs":"hono",go=(e,t,r,n)=>{let o=Ac(n.framework),s=Ec(e,t),i=Nc(e,r,o),a=Oc(e,r,o),c=Tc(r.serviceName,r.port,n),p=$c(r.envVarName,r.port);return[...s,...i,...a,c,p]};import{existsSync as _c,readdirSync as Dc,readFileSync as
|
|
407
|
+
`},Nc=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:ee(r,"stub").delegateFromHandler?t.events.map(o=>{let s=be(o),i=ee(r,s);return{kind:"file:write",path:or(e,i.filePath),content:Rc(o,t.workspaceScope)}}):[],Oc=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:t.events.map(n=>{let{kebab:o}=sr(n),s=nr(r,o);return{kind:"file:write",path:or(e,s.filePath),content:Ic(n,t.workspaceScope,r)}}),Ac=e=>e==="hono"?"hono":e==="nest"?"nestjs":"hono",go=(e,t,r,n)=>{let o=Ac(n.framework),s=Ec(e,t),i=Nc(e,r,o),a=Oc(e,r,o),c=Tc(r.serviceName,r.port,n),p=$c(r.envVarName,r.port);return[...s,...i,...a,c,p]};import{existsSync as _c,readdirSync as Dc,readFileSync as Mc}from"fs";import{join as fo}from"path";var ho=4001,jc=e=>{let t=e.match(/ports\(\)\.(?:http|https|grpc|primary)\((\d+)\)/);if(t)return Number.parseInt(t[1],10);let r=e.match(/containerPort:\s*(\d+)/);return r?Number.parseInt(r[1],10):null},yo=e=>{try{let t=fo(e,"infra","services");return _c(t)?Dc(t).filter(n=>n.endsWith(".ts")).reduce((n,o)=>{let s=Mc(fo(t,o),"utf-8"),i=jc(s);return i!==null&&n.add(i),n},new Set):new Set}catch(t){return console.warn("Failed to scan ports:",t),new Set}},ir=(e,t)=>e.has(t)?ir(e,t+1):t;var Fc=e=>{if(!e||e.trim().length===0)throw new Error("Service name cannot be empty");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(e))throw new Error(`Service name '${e}' must be kebab-case (lowercase, alphanumeric, hyphens only)`)},Wc=(e,t,r)=>{if(t){if(t.startsWith("/"))return t;if(t.startsWith("."))return rt(r,t);if(t.includes("/"))return rt(r,t)}let n=I(r);return rt(r,n.services,e)},Bc=e=>[...new Set(e.map(t=>Lc(t).streamName))],Hc=(e,t,r,n)=>{let s=x(t).packageName.split("/")[0],i=e.events??[],a=i.length>0||e.hasEvents||!1,c=i.length>0?Bc(i):e.streams??[];return{serviceName:e.name,packageName:`${s}/${e.name}`,servicePath:r.replace(`${t}/`,""),port:n,envVarName:D(e.name),hasEvents:a,streams:c,events:i,workspaceScope:s,envVars:e.envVars}},Gc=(e,t)=>e.files.filter(r=>!r.skip?.(t)).map(r=>({path:r.path,content:r.content(t)})),Uc=(e,t,r)=>[...e.map(o=>({type:"file",path:rt(r,o.path),description:`Service file: ${o.path}`})),{type:"config",path:`infra/services/${t}.ts`,description:"Infrastructure configuration"},{type:"env",path:".env.local",description:"Environment variables"}],Vc=e=>[{command:`cd ${e} && bun dev`,description:"Start this service"},{command:"pf dev",description:"Start all services"}],vo=e=>{Fc(e.name);let t=e.workspaceRoot??u(),r=Wc(e.name,e.path,t),n=e.port??ir(yo(t),ho),o=Hc(e,t,r,n),s=mo(e.type),i=Gc(s,o),a=go(r,i,o,s),c=Uc(i,e.name,r),p=Vc(r);return Qt("service.generate",`Generated ${e.name} service (port ${n})`,{artifacts:c,changes:a,next:p,data:{serviceName:e.name,servicePath:r,port:n,vars:o}})},ko=e=>{let t=vo(e);if(!t.ok||!t.data)throw new Error(t.summary);return{serviceName:t.data.serviceName,servicePath:t.data.servicePath,port:t.data.port,effects:t.changes,vars:t.data.vars}};v();v();v();import b from"chalk";import{execa as zc}from"execa";import{createJiti as Kc}from"jiti";var cr=async e=>{let{stdout:t}=await zc("sh",["-c",e]);return t.trim()},Co="pf-local-nats",qc="2.10-alpine",Yc=4222,Zc=8222,Xc=64*1024*1024,Qc={storage:"memory",retention:"limits",maxAge:36e5,maxBytes:Xc},ep=e=>({clientPort:e.clientPort??Yc,monitoringPort:e.monitoringPort??Zc,containerName:e.containerName??Co,version:e.version??qc}),tp=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"],rp=e=>({containerName:e.containerName,clientUrl:`nats://localhost:${e.clientPort}`,monitoringUrl:`http://localhost:${e.monitoringPort}`}),np=async()=>{try{return await cr("docker info"),!0}catch{return!1}},op=async e=>{try{return(await cr(`docker ps -q -f name=${e}`)).length>0}catch{return!1}};var sp=async e=>{let t=tp(e);try{return await cr(`docker ${t.join(" ")}`),{success:!0,value:rp(e)}}catch{return{success:!1}}},ip=e=>{console.log(b.green("\u2713 NATS started")),console.log(b.dim(` Client: ${e.clientUrl}`)),console.log(b.dim(` Monitoring: ${e.monitoringUrl}`)),console.log(b.dim(" Streams: ephemeral, auto-created by services")),console.log("")},xo=async(e={})=>{let t=ep(e);if(!await np())return console.log(b.yellow("\u26A0\uFE0F Docker not available - skipping NATS (services may fail)")),!1;if(await op(t.containerName))return console.log(b.dim("\u2713 NATS already running")),!0;console.log(b.cyan("\u{1F680} Starting development infrastructure...")),console.log(b.dim(" NATS with JetStream (ephemeral)"));let r=await sp(t);return r.success?(ip(r.value),!0):(console.error(b.red("\u2717 Failed to start NATS")),!1)},ap=e=>e.map(({stream:t,subjects:r})=>({stream:t,subjects:r,config:Qc})),ar="@crossdelta/infrastructure",wo=e=>e.includes(ar)&&(e.includes("is not defined by")||e.includes("Cannot find module")||e.includes("Cannot find package")),Po=e=>{if(typeof e!="object"||e===null)return null;let{message:t}=e;return typeof t=="string"?t:null},cp=e=>{let t=Po(e);if(t===null)return!0;if(wo(t))return!1;let r=t.toLowerCase();return!r.includes("insufficient storage")&&!r.includes("connection refused")},pp=e=>{let t=Po(e);if(t===null)return"Unknown error";let r=t.toLowerCase();return r.includes("insufficient storage")?["NATS has insufficient storage to create streams."," JetStream fixes its storage limit when the server starts, at 75% of the free space it"," sees then, and never recomputes it. So a disk that was full when the container started"," keeps the old limit even after you free space. Restart the container first:","",` docker restart ${Co}`," pf dev",""," If it still fails, the disk is full now as well:",""," docker system prune -af"].join(`
|
|
408
408
|
`):r.includes("connection refused")?"Cannot connect to NATS \u2014 is the container running?":wo(t)?[`${ar} is missing or too old to provide its /streams entry point.`,""," It is a peer dependency of this CLI, so neither `bun add -g` nor `npm i -g` installs it"," alongside pf, and bun reports nothing when it is absent. Install it explicitly:","",` bun add -g ${ar}`,""," Not continuing without it: letting the services create the streams instead leaves them in"," whatever shape they already had, so a corrected contract subject never takes effect and"," its events are dropped without an error."].join(`
|
|
409
409
|
`):t},pr=async e=>{try{let{ensureJetStreams:t}=await import("@crossdelta/cloudevents"),{indexPath:r}=x(e),o=await Kc(e,{moduleCache:!1}).import(r,{default:!0}),{collectStreamDefinitions:s}=await import("@crossdelta/infrastructure/streams"),i=s(o);if(i.length===0){console.log(b.dim(" No streams found in contracts"));return}let a=ap(i);await t({streams:a});let c=i.map(p=>p.stream);console.log(b.dim(` Ensured ${i.length} ephemeral stream(s): ${c.join(", ")}`))}catch(t){if(!cp(t))throw console.error(b.red(`
|
|
410
410
|
\u2717 ${pp(t)}
|
|
411
411
|
`)),t;console.log(b.yellow(` \u26A0\uFE0F Stream creation failed: ${t instanceof Error?t.message:"Unknown error"}`)),console.log(b.dim(" Streams will be created when services connect"))}};var bo=`// env: string literals \u2192 written to .env.local by generate-env (use for values meaningful locally)
|
|
412
412
|
// containerEnv: \u2192 only applied in the K8s container, never in .env.local
|
|
413
|
-
// (use for deployment-specific values like ORIGIN or NODE_OPTIONS)
|
|
413
|
+
// (use for deployment-specific values like ORIGIN or NODE_OPTIONS)`,So=(e,t)=>`import type { K8sServiceConfig } from '@crossdelta/infrastructure'
|
|
414
414
|
import { ports } from '@crossdelta/infrastructure'
|
|
415
415
|
|
|
416
416
|
/**
|
|
@@ -432,7 +432,7 @@ const config: K8sServiceConfig = {
|
|
|
432
432
|
}
|
|
433
433
|
|
|
434
434
|
export default config
|
|
435
|
-
|
|
435
|
+
`,Eo=(e,t)=>`import type { K8sServiceConfig } from '@crossdelta/infrastructure'
|
|
436
436
|
import { ports } from '@crossdelta/infrastructure'
|
|
437
437
|
|
|
438
438
|
/**
|
|
@@ -454,41 +454,41 @@ const config: K8sServiceConfig = {
|
|
|
454
454
|
}
|
|
455
455
|
|
|
456
456
|
export default config
|
|
457
|
-
|
|
457
|
+
`;h();import U from"chalk";import mp from"terminal-link";var nt="integrations-run";import{z as P}from"zod";var lp=P.object({name:P.string(),description:P.string(),link:P.url().optional(),install:P.union([P.string(),P.array(P.string())]).transform(e=>Array.isArray(e)?e:[e]),installFlags:P.array(P.string()).optional(),run:P.array(P.string()).optional(),initial:P.boolean().optional(),interactive:P.boolean().optional()}),To=P.array(lp);var $o=e=>{try{return To.parse(e)}catch(t){throw new Error(t.issues.map(r=>` - Path ${r.path.join(". ")} : ${r.message}`).join(`
|
|
458
458
|
`))}};var N=()=>{try{let e=he("bin/integration.collection.json");return $o(e)}catch(e){throw new Error(`Failed to load integrations!
|
|
459
459
|
Check your integration.collection.json:
|
|
460
|
-
${e.message}`)}},te=()=>N().reduce((t,r)=>(r.initial&&t.push(r.name),t),[]),
|
|
461
|
-
`))}))},
|
|
462
|
-
`),fn:()=>vp(s,i,t,r,n)}))),vp=async(e,t,r,n,o)=>{let s=`${nt}:${e.name}`;try{if(e.interactive)return
|
|
463
|
-
`)),e.shouldInstallBun=await r.toggle({message:"Would you like to use Bun? (recommended)",initial:!0}),e.shouldInstallBun&&(e.packageManager="bun")}};import
|
|
460
|
+
${e.message}`)}},te=()=>N().reduce((t,r)=>(r.initial&&t.push(r.name),t),[]),dp=e=>!!e?.name&&!!e?.link&&!!e?.description,ot=e=>{let t=N();if(!t?.length||!e?.length)return;let r=e.map(n=>t.find(o=>o.name===n)).filter(dp);r.length&&(m.breakLine().log("\u{1F50C} Installed Integrations:"),r.forEach(({name:n,link:o,description:s})=>{let i=m.getStoredLogs(`${nt}:${n}`);o&&m.log(`${mp(U.cyan(n),o)} - ${s}`),i.length&&m.log(i.map(a=>` \u203A ${U.dim(a.message)}`).join(`
|
|
461
|
+
`))}))},up=e=>e.toUpperCase().replace(/-/g,"_"),Ro=(e,t)=>{let r=up(e);m.breakLine().log(U.bold("Environment variables:")).log(U.dim(" Local (.env.local):")).log(U.cyan(` ${r}_PORT=${t}`)).breakLine().log(U.dim(" Production (auto-injected by infra):")).log(U.cyan(` PORT=${t}`))};h();import Io from"chalk";var gp=e=>{let t=e.match(/^(@?[^@]+)@(.+)$/);return t?{name:t[1],version:t[2]}:{name:e,version:"latest"}},No=async e=>{let{selectedIntegrations:t,cwd:r,packageManager:n=w(),task:o}=e;if(!t?.length||!o)return;let s=fp(t,r,n,o);await je(o,s)},fp=(e,t,r,n)=>{let s=N()?.filter(a=>e.includes(a.name))?.flatMap(a=>a.install.map(c=>{let{name:p,version:l}=gp(c);return{title:Io.cyanBright(`Adding ${c} (${a.name})`),fn:async()=>{We(`dependencies.${p}`,l,t)}}})),i={title:Io.cyanBright("Installing packages..."),fn:async()=>{await j({cwd:t,packageManager:r,task:n})}};return[...s??[],i]};h();import hp from"chalk";var Oo=async e=>{let{selectedIntegrations:t,cwd:r,task:n}=e;if(!t?.length||!n)return;let o=yp(t,r,n,e.packageManager);await je(n,o)},yp=(e,t,r,n)=>N().filter(s=>e.includes(s.name)&&s.run?.length).flatMap(s=>(s.run||[]).map(i=>({title:hp.cyanBright(`Running "${i}" for ${s.name}
|
|
462
|
+
`),fn:()=>vp(s,i,t,r,n)}))),vp=async(e,t,r,n,o)=>{let s=`${nt}:${e.name}`;try{if(e.interactive)return fn(t,[],{cwd:r,context:s,task:n,manager:o});await Lt(t,[],{cwd:r,task:n,context:s})}catch(i){m.error(`Failed to run command "${t}" for ${e.name}: ${i.message}`)}};import{ListrEnquirerPromptAdapter as Se}from"@listr2/prompt-adapter-enquirer";var y=e=>({select:async t=>e.prompt(Se).run({type:"select",message:t.message,choices:t.choices}),confirm:async t=>e.prompt(Se).run({type:"confirm",message:t.message,initial:t.initial??!1}),toggle:async t=>e.prompt(Se).run({type:"toggle",message:t.message,enabled:t.enabled??"Yes",disabled:t.disabled??"No",initial:t.initial??!1}),input:async t=>e.prompt(Se).run({type:"input",message:t.message,initial:t.initial,validate:t.validate}),multiSelect:async t=>e.prompt(Se).run({type:"MultiSelect",message:t.message,hint:t.hint,initial:t.initial,choices:t.choices})});h();import{readFileSync as iy}from"fs";import{join as cy}from"path";import vy from"chalk";import Cy from"cli-table3";h();var st=e=>e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),Ao=async(e,t,r={},n=[],o=[])=>{if(!e){console.error("Subcommand is not defined.");return}let s=n.map(p=>t[p]).filter(p=>p!==void 0),i=o.map(p=>{let l=t[p];if(!(l===!1||l===void 0))return l===!0?`--${st(String(p))}`:`--${st(String(p))}=${String(l)}`}).filter(p=>p!==void 0),a=Object.entries(r).map(([p,l])=>{if(!(l===!1||l===void 0))return l===!0?`--${st(p)}`:`--${st(p)}=${String(l)}`}).filter(p=>p!==void 0),c=[...s,...i,...a].map(String);await e.parseAsync(c,{from:"user"})};import{basename as Gp}from"path";import Ho from"chalk";v();var re={title:"Confirm creation",enabled:e=>!e.userConfirmed,task:async(e,t)=>{let r=y(t);if(e.userConfirmed=await r.toggle({initial:!0,message:"\u{1F680} Ready to launch your project?"}),!e.userConfirmed)throw new Error("Project creation was canceled by the user.")}};import{existsSync as lr,readdirSync as Cp,readFileSync as xp,writeFileSync as wp}from"fs";import{basename as Pp,join as mr}from"path";var bp=4001,Sp=4e3,Ep=e=>{let t=[],r=e.matchAll(/ports\(\)\.(?:http|https|grpc|primary)\((\d+)\)/g);for(let c of r)t.push(Number(c[1]));let n=e.matchAll(/\.add(?:Http|Grpc)?\((\d+)/g);for(let c of n)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 i=e.match(/httpPort\s*:\s*(\d+)/);i&&t.push(Number(i[1]));let a=e.matchAll(/const\s+\w*[pP]ort\w*\s*=\s*(\d+)/g);for(let c of a)t.push(Number(c[1]));return t},Tp=(e,t)=>{let r=t?bp:Sp,n=new Set;if(!lr(e))return r;let o=Cp(e).filter(i=>i.endsWith(".ts"));for(let i of o){let a=mr(e,i);try{let c=xp(a,"utf-8"),p=Ep(c);for(let l of p)n.add(l)}catch{}}let s=r;for(;n.has(s);)s++;return s},$p=e=>Pp(e),it={title:"Creating infrastructure service config",task:async(e,t)=>{let r=$p(e.projectName),n=u(),o=mr(n,"infra","services");if(!lr(o)){t.title="Skipping infra config (no infra/services directory found)";return}let s=mr(o,`${r}.ts`);if(lr(s)){t.title=`Service config already exists: infra/services/${r}.ts`;return}let i=Tp(o,!0);e.assignedPort=i;let a=e.serviceType==="hono"?So(r,i):Eo(r,i);wp(s,a),t.title=`Created infra/services/${r}.ts (port: ${i})`}};import{execSync as at}from"child_process";import{existsSync as Rp}from"fs";import{join as Ip}from"path";var Np=()=>{try{return at("git --version",{stdio:"ignore"}),!0}catch{return!1}},Op=e=>Rp(Ip(e,".git")),_o={title:"Initializing git repository",enabled:()=>Np(),skip:e=>Op(e.cwd)?"Already a git repository":!1,task:async(e,t)=>{try{at("git init",{cwd:e.cwd,stdio:"ignore"}),at("git add -A",{cwd:e.cwd,stdio:"ignore"}),at('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)"}}};import Do from"chalk";h();var ne={title:"Installing Bun",enabled:e=>!!e.shouldInstallBun&&!Wt(),task:async(e,t)=>R(t,async r=>{await vn(t),e.elapsedTime+=r(),t.title=`Bun installed successfully. (${e.elapsedTime}s)`})},oe={enabled:e=>!Wt()&&!e.shouldInstallBun&&!e.packageManager,task:async(e,t)=>{let r=y(t);console.log(["",`${Do.magenta.bold("Bun")} is a fast JavaScript runtime, package manager, bundler, and test runner: ${Do.underline("https://bun.sh")}`,kn(),Cn()].join(`
|
|
463
|
+
`)),e.shouldInstallBun=await r.toggle({message:"Would you like to use Bun? (recommended)",initial:!0}),e.shouldInstallBun&&(e.packageManager="bun")}};import Mo from"chalk";h();var ct={title:"Install integrations",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>R(t,async r=>{let{selectedIntegrations:n,cwd:o,packageManager:s}=e;await No({selectedIntegrations:n,packageManager:s,cwd:o,task:t}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}},pt={title:"Select integrations",enabled:e=>e.selectedIntegrations.length===0,task:async(e,t)=>{let r=y(t);e.selectedIntegrations=await r.multiSelect({hint:"\\nPress <space> to select/deselect, <enter> to confirm, <i> to invert selection",message:"Which integrations would you like to include?",initial:te().map((n,o)=>o),choices:e.availableIntegrations.map(({name:n,description:o})=>({name:n,message:[Mo.bold(n),o].join(" - "),value:n}))}),!e.selectedIntegrations||e.selectedIntegrations.length===0?t.title="No integrations selected.":t.title=["Selected integrations:",...e.selectedIntegrations.map(n=>Mo.bold(`\u2022 ${n}`))].join("\\n")}};h();var jo={title:"Install Nest CLI",task:async(e,t)=>R(t,async r=>{await gn({packages:["@nestjs/cli"],task:t,cwd:e.cwd}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}};h();var lt={title:"Install dependencies",task:async(e,t)=>R(t,async r=>{await j({cwd:e.cwd,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()})};import Ap from"chalk";h();var se={enabled:e=>!e.removeDir&&!De(e.cwd),task:async(e,t)=>{let r=y(t);if(e.removeDir=await r.toggle({message:Ap.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}),!e.removeDir)throw new Error("Project creation was canceled by the user.")}},ie={enabled:e=>!!e.removeDir,task:async e=>Vr(e.cwd)};h();var mt={title:"Run integration commands",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>R(t,async r=>{let{selectedIntegrations:n,cwd:o}=e;await Oo({selectedIntegrations:n,cwd:o,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1}};h();var _p=["services/my-hono-service","services/my-nest-service","my-platform"],ae={enabled:e=>e.skipInputPrompts||e.userConfirmed?!1:e.projectName?_p.includes(e.projectName):!0,task:async(e,t)=>{let r=y(t);e.projectName=await r.input({initial:e.projectName,message:"Enter project name",validate:n=>n?!0:"Project name is required."}),e.cwd&&(e.cwd=_(e.projectName))}};import Lo from"chalk";var ce={title:"Select Package manager",task:async(e,t)=>{if(e.packageManager??=jt(),e.packageManager){t.title=`Using ${Lo.bold(e.packageManager)} as package manager.`;return}let r=y(t);e.packageManager=await r.select({message:"Which package manager would you like to use?",choices:mn().map(n=>({name:n,value:n}))}),t.title=`Using ${Lo.bold(e.packageManager)} as package manager.`}};import dt from"chalk";var Fo={title:"GitHub repository owner",task:async(e,t)=>{if(e.githubOwner){t.title=`GitHub owner: ${dt.bold(e.githubOwner)}`;return}let r=y(t);e.githubOwner=await r.input({message:"Enter GitHub organization or username",initial:"my-org",validate:n=>n?.trim()?!0:"GitHub owner is required."}),t.title=`GitHub owner: ${dt.bold(e.githubOwner)}`}},Wo={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}let r=y(t);e.includeGitHubCI=await r.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 Bo={title:"Pulumi stack name",task:async(e,t)=>{if(e.pulumiStackBase){t.title=`Pulumi stack: ${dt.bold(e.pulumiStackBase)}`;return}let r=e.githubOwner||"myorg",n=e.projectName?.replace(/[^a-zA-Z0-9-]/g,"-")||"myproject",o=`${r}/${n}`,s=y(t);e.pulumiStackBase=await s.input({message:"Enter Pulumi stack base name (org/project)",initial:o,validate:i=>i?.trim()?i.includes("/")?!0:"Format should be org/project (e.g., myorg/myproject)":"Pulumi stack name is required."}),t.title=`Pulumi stack: ${dt.bold(e.pulumiStackBase)}`}};h();import{mkdirSync as Dp,writeFileSync as Mp}from"fs";import{dirname as jp}from"path";h();var Lp={hono:"hono",nest:"nestjs"},Fp=e=>Lp[e],Wp=e=>{let t=jp(e.path);Dp(t,{recursive:!0}),Mp(e.path,e.content,"utf-8")},Bp=(e,t)=>{let r=e.map(o=>{let s=o.path.match(/services\/[^/]+\/(.+)$/);return{path:s?s[1]:o.path,content:o.content}}),n=tt(t,r);if(!n.valid){let o=n.violations.map(s=>` - ${s.code}: ${s.message} (${s.path})`).join(`
|
|
464
464
|
`);throw new Error(`Policy violation(s) detected:
|
|
465
|
-
${o}`)}e.forEach(
|
|
466
|
-
${
|
|
467
|
-
${Uo.bold(`cd ${e} && ${t} run start:dev`)}`).breakLine().log("Happy coding! \u{1F389}").breakLine()}});import O from"chalk";h();import{spawnSync as Vp}from"child_process";import{chmodSync as Jp,existsSync as gr,mkdirSync as zp,readFileSync as Kp,writeFileSync as fr}from"fs";import{dirname as qp,join as hr}from"path";import{existsSync as Gp}from"fs";import{join as gt}from"path";var Up=()=>typeof import.meta?.url=="string"?j(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),dr=()=>{let e=Up(),t=B();return Q([gt(e,"templates","workspace"),gt(e,"..","..","..","..","templates","workspace"),gt(t,"bin","templates","workspace")],"Workspace templates directory not found.")},Jo=()=>{let e=dr(),t=gt(e,"packages","contracts");if(!Gp(t))throw new Error(`Contracts templates directory not found at: ${t}`);return t},ft=(e,t)=>er(e,t);var zo=e=>{e.endsWith(".sh")&&Jp(e,493)},Yp=[{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/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:"CLAUDE.md",output:"CLAUDE.md",isStatic:!0},{template:".claude/rules/cloudevents.md",output:".claude/rules/cloudevents.md",isStatic:!0}],Ko={title:"Creating workspace structure",task:async(e,t)=>{if(gr(e.cwd)){t.title="Workspace directory already exists, skipping...";return}let r=dr(),n=e.includeGitHubCI??!0,o=e.packageManager||"bun",s=c=>{try{let u=Vp(c,["--version"],{encoding:"utf-8",timeout:5e3}).stdout?.trim();if(u&&/^\d+\.\d+/.test(u))return`${c}@${u}`}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`},i={projectName:e.projectName,scope:`@${e.projectName}`,githubOwner:e.githubOwner||"",pulumiStackBase:e.pulumiStackBase||e.projectName,packageManager:o,packageManagerVersion:s(o)},a=Yp.filter(c=>!(c.isGitHubCI&&!n||c.forPackageManager&&c.forPackageManager!==o));for(let c of a){let p=hr(e.cwd,c.output),l=qp(p);if(gr(l)||zp(l,{recursive:!0}),c.isStatic){let u=hr(r,c.template);gr(u)?fr(p,Kp(u)):fr(p,""),zo(p)}else{let u=hr(r,c.template),T=ft(u,i);fr(p,T),zo(p)}}t.title="Workspace structure created"}};v();import{existsSync as Yo,mkdirSync as qo,readFileSync as Zp,writeFileSync as Xp}from"fs";import{join as ht}from"path";import Qp from"chalk";var el=()=>{let e=ht(process.cwd(),"package.json");if(!Yo(e))throw new Error("Root package.json not found. Please run this command from the workspace root.");let r=JSON.parse(Zp(e,"utf-8")).name;if(!r)throw new Error('package.json must have a "name" field');return r.startsWith("@")?r:`@${r}`},tl=()=>{let e=el(),{relativePath:t,packagePath:r}=x();if(Yo(r))throw new Error(`${t} already exists. Remove it first if you want to regenerate.`);let n=Jo(),o={scope:e,workspaceName:e.replace("@","").replace("/","-")};qo(r,{recursive:!0}),qo(ht(r,"src","events"),{recursive:!0});let s=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"tsup.config.ts",output:"tsup.config.ts"},{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 i of s){let a=ht(n,i.template),c=ht(r,i.output),p=ft(a,o);Xp(c,p,"utf-8")}},Zo={title:"Initializing contracts package",task:(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),tl(),t.title="Contracts package initialized"}catch(n){throw t.title=Qp.red(`Contracts package failed: ${n.message}`),n}finally{process.chdir(r)}}};import{spawnSync as rl}from"child_process";import nl from"chalk";var ol=["bunx","jackherd","init"],sl=([e,...t],r)=>{let n=rl(e,t,{cwd:r,encoding:"utf-8"}),o=`${n.error?.message??""} ${n.stdout??""}${n.stderr??""}`.trim();return{exitCode:n.status??1,output:o}},il=(e,t=sl)=>{let{exitCode:r,output:n}=t(ol,e);if(r!==0)throw new Error(`jackherd init failed (exit ${r}): ${n}`)},Xo={title:"Installing agent skills and rules",task:(e,t)=>{try{il(e.cwd),t.title="Agent skills and rules installed"}catch(r){throw t.title=nl.red(r.message),r}}};import al from"chalk";var Qo={title:"Registering shell completion",task:async(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),await xe(),t.title="Shell completion registered"}catch{t.title=al.dim("Shell completion skipped")}finally{process.chdir(r)}}};var es=L({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 r=(e.name??"my-platform").trim(),n=_(r),o=!!t.yes,s=t.packageManager??(o?w():void 0),i=t.packageManager==="bun",a=t.githubOwner??(o?"my-org":void 0),c=t.pulumiStack??(o?`${a}/${r}`:void 0),p=t.github===!1?!1:o?!0:void 0,l=!!e.name,u=t.removeDir||o;return{cwd:n,projectName:r,shouldInstallBun:i,packageManager:s,elapsedTime:0,userConfirmed:o,skipInputPrompts:l&&!o,removeDir:u,githubOwner:a,pulumiStackBase:c,includeGitHubCI:p}},prompts:[{enabled:e=>!e.userConfirmed,task:async(e,t)=>{try{let r=d();if(!await y(t).toggle({message:`\u26A0\uFE0F You are inside an existing workspace (${r}). Create a nested workspace anyway?`,initial:!1}))throw new Error("Workspace creation cancelled - already inside a workspace");t.title=O.yellow("Warning: Creating nested workspace")}catch(r){if(Ie(r)&&r.message?.includes("cancelled"))throw r;t.title="No existing workspace detected"}}},ae,se,Fo,Wo,Ho,oe,ce,re],actions:[ie,ne,Ko,Zo,lt,Xo,_o,Qo],onComplete:({projectName:e,includeGitHubCI:t})=>{m.breakLine().log(O.bold.green("Workspace created successfully!")),m.breakLine().log(O.bold("Next steps:")).log(` 1. ${O.cyan(`cd ${e}`)}`).log(` 2. ${O.cyan("exec $SHELL")} ${O.dim("(enable tab completion)")}`),t&&m.breakLine().log(O.bold("GitHub Setup:")).log(" Configure these secrets in your GitHub repository:").log(` \u2022 ${O.yellow("PULUMI_ACCESS_TOKEN")} - Pulumi Cloud access token`).log(` \u2022 ${O.yellow("DIGITALOCEAN_TOKEN")} - DigitalOcean API token`).log(` \u2022 ${O.yellow("NPM_TOKEN")} - (optional) NPM token for private packages`),m.breakLine().log(O.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 yt=[{name:"Hono Microservice",value:"hono-micro",command:Go},{name:"Nest Microservice",value:"nest-micro",command:Vo},{name:"Workspace (Infrastructure)",value:"workspace",command:es}],ts=()=>{let e=L({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??"",elapsedTime:0,cwd:process.cwd()}),prompts:[{enabled:t=>!t.projectType,task:async(t,r)=>{let o=await y(r).select({message:"Select Project type",choices:yt});t.projectType=yt.find(s=>s.name===o)?.value||"",r.title=`Using ${pe.bold(o)}`}},{enabled:t=>t.projectType!=="workspace"&&t.projectType!=="",task:async(t,r)=>{try{d(),r.title="Workspace detected"}catch{let n=["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(`
|
|
468
|
-
`);throw new Error(n)}}},{enabled:t=>t.projectType==="workspace",task:async(t,r)=>{try{let n=
|
|
469
|
-
\u{1F4E6} Contracts changed, updating streams...`),await pr(e)},500),n=
|
|
470
|
-
`),
|
|
471
|
-
\u{1F6D1} Shutting down...`),await vt(n),await Promise.all([o?.(),s?.()]),process.exit(
|
|
465
|
+
${o}`)}e.forEach(Wp)},Hp=async(e,t,r)=>{let{projectName:n,serviceType:o,hasEvents:s,streams:i}=e,a=n.split("/").pop()||n,p=ko({type:o==="hono"?"hono-micro":"nest",name:a,path:n,hasEvents:s,streams:i}),l=p.effects.filter(T=>T.kind==="file:write"),d=Fp(o);Bp(l,d),e.assignedPort=p.port,e.elapsedTime+=r(),t.title=`Generated ${a} (port ${p.port}, ${e.elapsedTime}s)`},ut={title:"Generating service",task:async(e,t)=>R(t,async r=>{await Hp(e,t,r)})};var Go=M({name:"hono-micro",description:"Create a new Hono microservice with the Crossdelta setup.",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"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:"platform new hono-micro my-service",buildContext:async(e,t)=>{let r=(e.name??"my-hono-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${I().services}/${r}`);let n=_(r),o=t.packageManager??(t.yes&&w()),s=N(),i=t.yes?te():[],a=t.packageManager==="bun",c=!!t.yes||!!e.name&&e.name!=="my-hono-service";return{cwd:n,projectName:r,packageManager:o,shouldInstallBun:a,availableIntegrations:s,selectedIntegrations:i,serviceType:"hono",elapsedTime:0,userConfirmed:!!t.yes,skipInputPrompts:c,removeDir:!!t.removeDir||!!t.yes}},prompts:[ae,se,oe,ce,pt,re],actions:[ie,ne,ut,it,ct,mt],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r,assignedPort:n})=>{m.breakLine().log(Ho.bold.green("Hono Microservice created successfully!")),ot(r),Ro(Gp(e),n??8080);let o=t??w();m.breakLine().log(`To start the project, run:
|
|
466
|
+
${Ho.bold(`cd ${e} && ${o} run dev`)}`).breakLine().log("Happy shipping with Hono! \u26A1\uFE0F").breakLine()}});import Uo from"chalk";v();h();var Vo=M({name:"nest-micro",description:"Create a new NestJS microservice with the Crossdelta setup.",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"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:"platform new nest-micro my-service",buildContext:async(e,t)=>{let r=(e.name??"my-nest-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${I().services}/${r}`);let n=_(r),o=t.packageManager??(t.yes&&w()),s=t.packageManager==="bun",i=N(),a=t.yes?te():[],c=!!t.yes||!!e.name;return{cwd:n,projectName:r,shouldInstallBun:s,packageManager:o,availableIntegrations:i,selectedIntegrations:a,serviceType:"nest",elapsedTime:0,userConfirmed:!!t.yes,skipInputPrompts:c,removeDir:!!t.removeDir||!!t.yes}},prompts:[ae,se,oe,ce,pt,re],actions:[ie,ne,ut,it,lt,jo,ct,mt],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r})=>{m.breakLine().log(Uo.bold.green("NestJS Microservice created successfully!")),ot(r),m.breakLine().log(`To start the project, run:
|
|
467
|
+
${Uo.bold(`cd ${e} && ${t} run start:dev`)}`).breakLine().log("Happy coding! \u{1F389}").breakLine()}});import O from"chalk";h();import{spawnSync as Jp}from"child_process";import{chmodSync as zp,existsSync as gr,mkdirSync as Kp,readFileSync as qp,writeFileSync as fr}from"fs";import{dirname as Yp,join as hr}from"path";import{existsSync as Up}from"fs";import{join as gt}from"path";var Vp=()=>typeof import.meta?.url=="string"?L(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),ur=()=>{let e=Vp(),t=H();return Q([gt(e,"templates","workspace"),gt(e,"..","..","..","..","templates","workspace"),gt(t,"bin","templates","workspace")],"Workspace templates directory not found.")},Jo=()=>{let e=ur(),t=gt(e,"packages","contracts");if(!Up(t))throw new Error(`Contracts templates directory not found at: ${t}`);return t},ft=(e,t)=>er(e,t);var zo=e=>{e.endsWith(".sh")&&zp(e,493)},Zp=[{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/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:"CLAUDE.md",output:"CLAUDE.md",isStatic:!0},{template:".claude/rules/cloudevents.md",output:".claude/rules/cloudevents.md",isStatic:!0}],Ko={title:"Creating workspace structure",task:async(e,t)=>{if(gr(e.cwd)){t.title="Workspace directory already exists, skipping...";return}let r=ur(),n=e.includeGitHubCI??!0,o=e.packageManager||"bun",s=c=>{try{let d=Jp(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`},i={projectName:e.projectName,scope:`@${e.projectName}`,githubOwner:e.githubOwner||"",pulumiStackBase:e.pulumiStackBase||e.projectName,packageManager:o,packageManagerVersion:s(o)},a=Zp.filter(c=>!(c.isGitHubCI&&!n||c.forPackageManager&&c.forPackageManager!==o));for(let c of a){let p=hr(e.cwd,c.output),l=Yp(p);if(gr(l)||Kp(l,{recursive:!0}),c.isStatic){let d=hr(r,c.template);gr(d)?fr(p,qp(d)):fr(p,""),zo(p)}else{let d=hr(r,c.template),T=ft(d,i);fr(p,T),zo(p)}}t.title="Workspace structure created"}};v();import{existsSync as Yo,mkdirSync as qo,readFileSync as Xp,writeFileSync as Qp}from"fs";import{join as ht}from"path";import el from"chalk";var tl=()=>{let e=ht(process.cwd(),"package.json");if(!Yo(e))throw new Error("Root package.json not found. Please run this command from the workspace root.");let r=JSON.parse(Xp(e,"utf-8")).name;if(!r)throw new Error('package.json must have a "name" field');return r.startsWith("@")?r:`@${r}`},rl=()=>{let e=tl(),{relativePath:t,packagePath:r}=x();if(Yo(r))throw new Error(`${t} already exists. Remove it first if you want to regenerate.`);let n=Jo(),o={scope:e,workspaceName:e.replace("@","").replace("/","-")};qo(r,{recursive:!0}),qo(ht(r,"src","events"),{recursive:!0});let s=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"tsup.config.ts",output:"tsup.config.ts"},{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 i of s){let a=ht(n,i.template),c=ht(r,i.output),p=ft(a,o);Qp(c,p,"utf-8")}},Zo={title:"Initializing contracts package",task:(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),rl(),t.title="Contracts package initialized"}catch(n){throw t.title=el.red(`Contracts package failed: ${n.message}`),n}finally{process.chdir(r)}}};import{spawnSync as nl}from"child_process";import ol from"chalk";var sl=["bunx","jackherd","init"],il=([e,...t],r)=>{let n=nl(e,t,{cwd:r,encoding:"utf-8"}),o=`${n.error?.message??""} ${n.stdout??""}${n.stderr??""}`.trim();return{exitCode:n.status??1,output:o}},al=(e,t=il)=>{let{exitCode:r,output:n}=t(sl,e);if(r!==0)throw new Error(`jackherd init failed (exit ${r}): ${n}`)},Xo={title:"Installing agent skills and rules",task:(e,t)=>{try{al(e.cwd),t.title="Agent skills and rules installed"}catch(r){throw t.title=ol.red(r.message),r}}};import cl from"chalk";var Qo={title:"Registering shell completion",task:async(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),await xe(),t.title="Shell completion registered"}catch{t.title=cl.dim("Shell completion skipped")}finally{process.chdir(r)}}};var es=M({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 r=(e.name??"my-platform").trim(),n=_(r),o=!!t.yes,s=t.packageManager??(o?w():void 0),i=t.packageManager==="bun",a=t.githubOwner??(o?"my-org":void 0),c=t.pulumiStack??(o?`${a}/${r}`:void 0),p=t.github===!1?!1:o?!0:void 0,l=!!e.name,d=t.removeDir||o;return{cwd:n,projectName:r,shouldInstallBun:i,packageManager:s,elapsedTime:0,userConfirmed:o,skipInputPrompts:l&&!o,removeDir:d,githubOwner:a,pulumiStackBase:c,includeGitHubCI:p}},prompts:[{enabled:e=>!e.userConfirmed,task:async(e,t)=>{try{let r=u();if(!await y(t).toggle({message:`\u26A0\uFE0F You are inside an existing workspace (${r}). Create a nested workspace anyway?`,initial:!1}))throw new Error("Workspace creation cancelled - already inside a workspace");t.title=O.yellow("Warning: Creating nested workspace")}catch(r){if(Ie(r)&&r.message?.includes("cancelled"))throw r;t.title="No existing workspace detected"}}},ae,se,Fo,Wo,Bo,oe,ce,re],actions:[ie,ne,Ko,Zo,lt,Xo,_o,Qo],onComplete:({projectName:e,includeGitHubCI:t})=>{m.breakLine().log(O.bold.green("Workspace created successfully!")),m.breakLine().log(O.bold("Next steps:")).log(` 1. ${O.cyan(`cd ${e}`)}`).log(` 2. ${O.cyan("exec $SHELL")} ${O.dim("(enable tab completion)")}`),t&&m.breakLine().log(O.bold("GitHub Setup:")).log(" Configure these secrets in your GitHub repository:").log(` \u2022 ${O.yellow("PULUMI_ACCESS_TOKEN")} - Pulumi Cloud access token`).log(` \u2022 ${O.yellow("DIGITALOCEAN_TOKEN")} - DigitalOcean API token`).log(` \u2022 ${O.yellow("NPM_TOKEN")} - (optional) NPM token for private packages`),m.breakLine().log(O.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 yt=[{name:"Hono Microservice",value:"hono-micro",command:Go},{name:"Nest Microservice",value:"nest-micro",command:Vo},{name:"Workspace (Infrastructure)",value:"workspace",command:es}],ts=()=>{let e=M({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??"",elapsedTime:0,cwd:process.cwd()}),prompts:[{enabled:t=>!t.projectType,task:async(t,r)=>{let o=await y(r).select({message:"Select Project type",choices:yt});t.projectType=yt.find(s=>s.name===o)?.value||"",r.title=`Using ${pe.bold(o)}`}},{enabled:t=>t.projectType!=="workspace"&&t.projectType!=="",task:async(t,r)=>{try{u(),r.title="Workspace detected"}catch{let n=["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(`
|
|
468
|
+
`);throw new Error(n)}}},{enabled:t=>t.projectType==="workspace",task:async(t,r)=>{try{let n=u();if(!await y(r).toggle({message:`\u26A0\uFE0F You are inside an existing workspace (${n}). Create a nested workspace anyway?`,initial:!1}))throw new Error("Workspace creation cancelled - already inside a workspace");r.title=pe.yellow("Warning: Creating nested workspace")}catch(n){if(Ie(n)&&n.message?.includes("cancelled"))throw n;r.title="No existing workspace detected"}}},{enabled:t=>!!t.projectType,task:async(t,r)=>{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 y(r).input({message:s,initial:o});t.servicePath=a.trim(),r.title=`Path: ${pe.dim(a)}`}},{enabled:t=>{if(!t.servicePath)return!1;let r=_(t.servicePath);return!De(r)},task:async(t,r)=>{if(!await y(r).toggle({message:pe.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}))throw new Error("Project creation was canceled by the user.");t.shouldRemoveDir=!0,r.title=pe.yellow("Will overwrite existing directory")}},{title:"Confirm creation",enabled:t=>t.projectType!=="workspace",task:async(t,r)=>{if(!await y(r).toggle({message:"\u{1F680} Ready to launch your project?",initial:!0}))throw new Error("Project creation was canceled by the user.")}}],actions:[],onComplete:async t=>{yt.find(s=>s.value===t.projectType)||e.error(pe.red(`Project type ${t.projectType} is not supported.`));let r=e.commands.find(s=>s.name()===t.projectType),n={};t.projectType!=="workspace"&&(n.yes=!0);let o=[];t.servicePath&&o.push("servicePath"),t.shouldRemoveDir&&(n.removeDir=!0),await Ao(r,t,n,o)}});for(let t of yt)e.addCommand(t.command);return e};import{Command as Cl}from"commander";h();import{createHash as pl}from"crypto";import{existsSync as V,readdirSync as rs,readFileSync as ns,unlinkSync as ll,writeFileSync as ml}from"fs";import{join as F}from"path";import dl from"chokidar";v();h();var ul=e=>{let t=F(e,"infra","services");if(!V(t))return[];let r=rs(t).filter(a=>a.endsWith(".ts")&&a!=="index.ts").map(a=>a.replace(".ts","")),n=I(e),o=a=>{let c=F(e,a);return V(c)?rs(c).filter(p=>V(F(c,p,"package.json"))):[]},s=[...o(n.services),...o(n.apps)],i=r.filter(a=>!s.includes(a));for(let a of i)ll(F(t,`${a}.ts`));return i},os=".install-hash",ss=e=>{let t=ns(e);return pl("sha256").update(t).digest("hex")},gl=e=>{let t=F(e,"node_modules",os),r=F(e,"bun.lock");return!V(r)||!V(t)?!0:ns(t,"utf-8")!==ss(r)},fl=e=>{let t=F(e,"bun.lock"),r=F(e,"node_modules",os);V(t)&&ml(r,ss(t),"utf-8")},yr=async e=>{let t=ul(e);t.length>0&&console.log(`\u{1F9F9} Cleaned ${t.length} orphaned infra config(s): ${t.join(", ")}`),gl(e)&&(await j({cwd:e,quiet:!0}),fl(e)),await ye("generate-env",{cwd:e})},vr=async e=>{await xo()&&await pr(e)},is=e=>{let{eventsPath:t}=x(e);if(!V(t))return async()=>{};let r=z(async()=>{console.log(`
|
|
469
|
+
\u{1F4E6} Contracts changed, updating streams...`),await pr(e)},500),n=dl.watch(`${t}/**/*.ts`,{ignoreInitial:!0,ignored:["**/index.ts","**/*.test.ts","**/*.spec.ts"]});return n.on("add",r).on("change",r),async()=>{await n.close()}};Oe();import cs from"chalk";v();le();var hl=["SIGINT","SIGTERM"],yl=[k.SUCCESS,k.GENERAL_ERROR,k.CANCELLED],vl=({code:e,signal:t})=>t?hl.includes(t)?k.SUCCESS:k.GENERAL_ERROR:e===null||yl.includes(e)?k.SUCCESS:e,as=e=>!e.isCurrentProcess||e.isRestarting||e.isShuttingDown?{action:"continue"}:{action:"shutdown",exitCode:vl(e)};var kr=e=>new Promise(t=>setTimeout(t,e)),ps=e=>process.stdout.write(`${e}
|
|
470
|
+
`),kl=()=>{process.stdout.write("\x1B[2J\x1B[3J\x1B[H"),process.stdout.isTTY&&process.stdout.write("\x1Bc")},ls=()=>({turboProcess:null,isRestarting:!1,isShuttingDown:!1}),ms=async(e,t,r,n)=>{let{dev:o}=fe(t),s=r.length>0?[...r]:o.filter,i=on(nn(".env.local",t),s,process.env.PORT);i.length>0&&(await pn(i),await kr(50));let a=s.flatMap(p=>["--filter",p]);ps(cs.cyan("\u{1F525} Starting services...")),ps(cs.dim(` Command: turbo run ${Pt} --continue${a.length?` ${a.join(" ")}`:""}`)),e.isShuttingDown=!1,e.isRestarting=!1;let c=sn("turbo",["run",Pt,"--continue","--no-daemon",...a],{cwd:t,envFile:".env.local",onExit:(p,l)=>{let d=as({code:p,signal:l,isRestarting:e.isRestarting,isShuttingDown:e.isShuttingDown,isCurrentProcess:e.turboProcess===c});d.action==="shutdown"&&n(d.exitCode)}});e.turboProcess=c},vt=async e=>{let t=e.turboProcess?.pid;if(t){e.isShuttingDown=!0;try{try{process.kill(-t,"SIGTERM")}catch{e.turboProcess?.kill("SIGTERM")}await kr(200);try{process.kill(-t,"SIGKILL")}catch{}await kr(30)}catch{}e.turboProcess=null,kl()}};var ds=new Cl("dev").description("Start development mode with auto-reload").option("-f, --filter <packages...>","Only start these workspace packages (e.g. @orderboss/website). Overrides pf.dev.filter, and narrows the ports freed on start so a second worktree does not kill the first one.").action(async e=>{let t=e.filter??[],r;try{r=u()}catch(d){A(d);return}let n=ls(),o,s,i=async(d=k.SUCCESS)=>{n.isShuttingDown||(console.log(`
|
|
471
|
+
\u{1F6D1} Shutting down...`),await vt(n),await Promise.all([o?.(),s?.()]),process.exit(d))},a=()=>ms(n,r,t,i),c=async()=>{await yr(r),await vr(r),await a()},l=z(async()=>{if(!(n.isRestarting||n.isShuttingDown)){n.isRestarting=!0,console.log(`
|
|
472
472
|
\u{1F504} Change detected, restarting...
|
|
473
|
-
`);try{await vt(n),await yr(r),await vr(r),await a()}catch(
|
|
473
|
+
`);try{await vt(n),await yr(r),await vr(r),await a()}catch(d){A(d)}finally{n.isRestarting=!1}}},300);process.removeAllListeners("SIGINT"),process.removeAllListeners("SIGTERM"),process.on("SIGINT",()=>i()),process.on("SIGTERM",()=>i());try{await c(),o=Dr(r,l),s=is(r),console.log(`
|
|
474
474
|
\u{1F440} Watching for changes...`),console.log(` Press Ctrl+C to exit
|
|
475
|
-
`)}catch(
|
|
475
|
+
`)}catch(d){await Promise.all([o?.(),s?.()]),await vt(n),A(d)}});import hs from"chalk";import{Command as Al}from"commander";import{existsSync as xl,readFileSync as wl,writeFileSync as Pl}from"fs";import bl from"os";import us from"path";import Cr from"chalk";import{Command as Sl}from"commander";h();var{name:El,publishConfig:Tl}=E,$l=Tl?.registry,Rl=El?.split("/")[0],$C=new Sl("token:set").description(Cr.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)",Rl).option("--registry <registry>","Registry URL",$l).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)=>gs(e,t.scope||"",t.registry||"",t.local,t.force)).addHelpText("after",()=>`${Cr.cyan(`
|
|
476
476
|
Example:`)}
|
|
477
477
|
${Cr.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
|
|
478
|
-
`),
|
|
479
|
-
//${n}/:_authToken=${e}`:`//${n}/:_authToken=${e}`},
|
|
478
|
+
`),Il=e=>e?us.join(process.cwd(),".npmrc"):us.join(bl.homedir(),".npmrc"),Nl=(e,t,r)=>{let n=new URL(r).host;return t?`${t}:registry=https://${n}
|
|
479
|
+
//${n}/:_authToken=${e}`:`//${n}/:_authToken=${e}`},Ol=e=>xl(e)?wl(e,"utf8"):"",xr=(e,t)=>Pl(e,t),gs=(e,t,r,n=!1,o=!1)=>{let s=Il(n),i=Nl(e,t,r),a=new URL(r).host,c=Ol(s),p=new RegExp(`//${a}/:_authToken=\\S+`);if(!c){xr(s,`${i}
|
|
480
480
|
`),m.success(`Created new .npmrc and set token for ${a}`);return}if(p.test(c)){if(!o){m.warn(`Token for ${a} already exists in ${s}. Use --force to overwrite.`);return}c=c.replace(p,i),xr(s,c),m.success(`Overwrote existing token for ${a} in ${s}`);return}c+=`
|
|
481
481
|
${i}
|
|
482
|
-
`,xr(s,c),m.success(`Appended token for ${a} to ${s}`)},fs=(e,t)=>gs(e,t.scope||"",t.registry||"",t.local,t.force);var{name:
|
|
482
|
+
`,xr(s,c),m.success(`Appended token for ${a} to ${s}`)},fs=(e,t)=>gs(e,t.scope||"",t.registry||"",t.local,t.force);var{name:_l,publishConfig:Dl}=E,Ml=Dl?.registry,jl=_l?.split("/")[0],wr=new Al("token").description("Token management commands");wr.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)",jl).option("--registry <registry>","Registry URL",Ml).option("--local","Write token to a local .npmrc in the current directory",!1).option("--force","Force overwrite existing token if already present",!1).action(fs).addHelpText("after",()=>`${hs.cyan(`
|
|
483
483
|
Example:`)}
|
|
484
484
|
${hs.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
|
|
485
|
-
`);wr.action(()=>{let e=q({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 ys=wr;import br from"chalk";import{Command as
|
|
485
|
+
`);wr.action(()=>{let e=q({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 ys=wr;import br from"chalk";import{Command as Fl}from"commander";v();Oe();var jC={DEBUG:process.env.PF_DEBUG==="true"};import{existsSync as BC,readFileSync as HC}from"fs";import{homedir as UC}from"os";import{join as JC}from"path";var Pr=async(e,t=!1)=>{try{return zt(e,t),await xe({verbose:t}),!0}catch{return!1}};var kt=e=>{let t=new Fl("setup").description("Configure platform settings");return t.command("completion").description("Install shell autocompletion").option("--verbose","Enable verbose logging").addHelpText("after",`
|
|
486
486
|
Examples:
|
|
487
487
|
$ pf setup completion
|
|
488
488
|
$ pf setup completion --verbose
|
|
489
489
|
`).action(async r=>{await Pr(e,r.verbose),r.verbose||(console.log(br.green(`
|
|
490
490
|
\u2714 Shell autocompletion installed!`)),console.log(br.dim(` Restart your shell:
|
|
491
491
|
`)),console.log(br.cyan(` exec $SHELL
|
|
492
|
-
`)))}),t.action(()=>{let r=q({title:"\u2699\uFE0F Platform Setup",commands:[{name:"completion",description:"Install shell autocompletion"}],footer:'Run "pf setup <command> --help" for more information'});console.log(r)}),t},
|
|
492
|
+
`)))}),t.action(()=>{let r=q({title:"\u2699\uFE0F Platform Setup",commands:[{name:"completion",description:"Install shell autocompletion"}],footer:'Run "pf setup <command> --help" for more information'});console.log(r)}),t},Wl=kt("pf");J();v();import Hl from"chalk";import{Command as ks}from"commander";import vs from"chalk";var Bl=e=>({debug:()=>{},info:e?()=>{}:t=>console.log(` ${t}`),warn:e?()=>{}:t=>console.log(vs.yellow(` ${t}`)),error:e?()=>{}:t=>console.error(vs.red(` ${t}`))}),Sr=async e=>{let{command:t,args:r,options:n,context:o,silent:s=!1}=e,i=await t.run(r,n),a=i?.effects??[];if(a.length>0){let c={workspace:o.workspace,logger:Bl(s)};Xt(a,c)}if(!s&&i?.output){let c=Array.isArray(i.output)?i.output:[i.output];for(let p of c)console.log(p)}return{effects:a,output:i?.output}};var Gl=e=>e.required?`<${e.name}>`:`[${e.name}]`,Ul=(e,t)=>{e.argument(Gl(t),t.description)},Vl=(e,t)=>{t.default!==void 0?e.option(t.flags,t.description,t.default):e.option(t.flags,t.description)},Jl=(e,t)=>Object.fromEntries(e.args.map((r,n)=>[r.name,t[n]])),zl=e=>e[e.length-2],Kl=(e,t)=>async(...r)=>{try{await Sr({command:e,args:Jl(e,r),options:zl(r),context:t})}catch(n){console.error(Hl.red(`Error executing ${e.name}:`),n instanceof Error?n.message:n),process.exit(1)}},Cs=(e,t)=>{let r=new ks(e.name).description(e.description);return e.args.forEach(n=>{Ul(r,n)}),e.options.forEach(n=>{Vl(r,n)}),r.action(Kl(e,t)),r},Er=(e,t,r,n)=>{let o=new ks(e).description(t);return r.forEach(s=>{o.addCommand(Cs(s,n))}),o};ze();process.on("SIGINT",()=>{process.exit(k.CANCELLED)});process.on("unhandledRejection",e=>{throw Ne(e)&&process.exit(k.CANCELLED),e});process.on("uncaughtException",e=>{A(e)});var Ee=new Yl,xs=Object.keys(E.bin||{}),[$r="pf",Tr]=xs.length>0?xs:["pf"],{description:ws,version:Xl,repository:Ps,homepage:Ql}=E,bs=ws?.split(/ —|,|\./)[0]||ws||"Platform CLI",Es=Ps?.url?`https://${Ps.url.replace(/^(git\+|git@)/,"").replace(/\.git$/,"").replace(":","/")}`:null,Ss=Es||Ql,em=Es?"GitHub":"README",tm=Ss?[Te.bold(bs),`
|
|
493
493
|
|
|
494
|
-
`,Te.cyan("See more at: "),Te.bold(
|
|
494
|
+
`,Te.cyan("See more at: "),Te.bold(Zl(em,String(Ss)))].join(""):Te.bold(bs),rm=[kt($r),ts(),ds,ys,hn],nm=async()=>{try{let e=u(),t=fe(e);if(!t.plugins?.length)return[];let r=x(e),n=Ke({workspaceRoot:e,availableServices:Be(e),contracts:{path:`${r.relativePath}/src`,packageName:r.packageName}}),o=[];for(let s of t.plugins)try{let{plugin:i}=await qe(s,n),a=Er(i.name,i.description??`Commands from ${i.name}`,i.commands,n);o.push(a)}catch(i){console.warn(`\u26A0\uFE0F Failed to load plugin '${s}':`,i.message)}return o}catch{return[]}},om=async()=>{let e=await nm(),t=[...rm,...e];Ee.name($r).description(tm).version(Xl||"0.0.1").helpCommand(!1).configureHelp({subcommandTerm:r=>Te.cyan(r.name())}).addHelpText("after",wn),Tr&&Tr!==$r&&Ee.alias(Tr);for(let r of t)Ee.addCommand(r);Ee.command("__workspace-hash",{hidden:!0}).action(()=>{let r=process.cwd(),n=Math.abs(r.split("").reduce((o,s)=>(o<<5)-o+s.charCodeAt(0)|0,0));console.log(n)}),Pn(Ee,ql,t)};om();
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"pulumi": "pulumi"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@crossdelta/cloudevents": "^0.10.
|
|
12
|
-
"@crossdelta/infrastructure": "^0.
|
|
11
|
+
"@crossdelta/cloudevents": "^0.10.1",
|
|
12
|
+
"@crossdelta/infrastructure": "^0.19.0",
|
|
13
13
|
"{{scope}}/contracts": "workspace:*",
|
|
14
14
|
"@pulumi/digitalocean": "^4.55.0",
|
|
15
15
|
"@pulumi/kubernetes": "^4.21.0",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"clean": "rm -rf dist"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@crossdelta/cloudevents": "^0.10.
|
|
23
|
-
"@crossdelta/infrastructure": "^0.
|
|
22
|
+
"@crossdelta/cloudevents": "^0.10.1",
|
|
23
|
+
"@crossdelta/infrastructure": "^0.19.0",
|
|
24
24
|
"zod": "^4.0.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
package/dist/facade.js
CHANGED
|
@@ -150,14 +150,7 @@ var init_environment = __esm({
|
|
|
150
150
|
});
|
|
151
151
|
|
|
152
152
|
// cli/src/utils/fs.ts
|
|
153
|
-
|
|
154
|
-
const packageJsonPath = (0, import_package_up.packageUpSync)({ cwd: (0, import_node_path2.dirname)(getModuleFilename()) });
|
|
155
|
-
if (!packageJsonPath) {
|
|
156
|
-
throw new Error("Could not find package.json");
|
|
157
|
-
}
|
|
158
|
-
return (0, import_node_path2.dirname)(packageJsonPath);
|
|
159
|
-
}
|
|
160
|
-
var import_node_fs2, import_node_path2, import_node_url, import_package_up, import_rimraf, import_meta, getModuleFilename;
|
|
153
|
+
var import_node_fs2, import_node_path2, import_node_url, import_package_up, import_rimraf, import_meta, getModuleFilename, getCliRoot;
|
|
161
154
|
var init_fs = __esm({
|
|
162
155
|
"cli/src/utils/fs.ts"() {
|
|
163
156
|
"use strict";
|
|
@@ -175,6 +168,13 @@ var init_fs = __esm({
|
|
|
175
168
|
}
|
|
176
169
|
return process.cwd();
|
|
177
170
|
};
|
|
171
|
+
getCliRoot = () => {
|
|
172
|
+
const packageJsonPath = (0, import_package_up.packageUpSync)({ cwd: (0, import_node_path2.dirname)(getModuleFilename()) });
|
|
173
|
+
if (!packageJsonPath) {
|
|
174
|
+
throw new Error("Could not find package.json");
|
|
175
|
+
}
|
|
176
|
+
return (0, import_node_path2.dirname)(packageJsonPath);
|
|
177
|
+
};
|
|
178
178
|
}
|
|
179
179
|
});
|
|
180
180
|
|
|
@@ -1328,21 +1328,21 @@ var getTemplatesDir = () => {
|
|
|
1328
1328
|
);
|
|
1329
1329
|
};
|
|
1330
1330
|
var renderTemplate2 = (templateName, data = {}) => createTemplateRenderer(getTemplatesDir())(templateName, data);
|
|
1331
|
-
|
|
1331
|
+
var generateHonoTsConfig = () => {
|
|
1332
1332
|
return renderTemplate2("tsconfig.json.hbs");
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1333
|
+
};
|
|
1334
|
+
var generateHonoDockerfile = (bunVersion = "1.2.23") => {
|
|
1335
1335
|
return renderTemplate2("Dockerfile.hbs", { bunVersion });
|
|
1336
|
-
}
|
|
1337
|
-
|
|
1336
|
+
};
|
|
1337
|
+
var generateHonoBiomeJson = () => {
|
|
1338
1338
|
return renderTemplate2("biome.json.hbs");
|
|
1339
|
-
}
|
|
1340
|
-
|
|
1339
|
+
};
|
|
1340
|
+
var generateHonoEnvTs = (serviceName, envVars = []) => {
|
|
1341
1341
|
return renderTemplate2("src/config/env.ts.hbs", {
|
|
1342
1342
|
envKey: toEnvKey(serviceName),
|
|
1343
1343
|
envVars
|
|
1344
1344
|
});
|
|
1345
|
-
}
|
|
1345
|
+
};
|
|
1346
1346
|
|
|
1347
1347
|
// cli/src/core/templates/hono-bun.template.ts
|
|
1348
1348
|
var generateImports = (hasEvents) => {
|
|
@@ -1522,35 +1522,35 @@ var getTemplatesDir2 = () => {
|
|
|
1522
1522
|
);
|
|
1523
1523
|
};
|
|
1524
1524
|
var renderTemplate3 = (templateName, data = {}) => createTemplateRenderer(getTemplatesDir2())(templateName, data);
|
|
1525
|
-
|
|
1525
|
+
var generateNestMainTs = (serviceName, defaultPort = 3e3) => {
|
|
1526
1526
|
return renderTemplate3("src/main.ts.hbs", {
|
|
1527
1527
|
serviceName,
|
|
1528
1528
|
envKey: toEnvKey(serviceName),
|
|
1529
1529
|
displayName: toDisplayName(serviceName),
|
|
1530
1530
|
defaultPort
|
|
1531
1531
|
});
|
|
1532
|
-
}
|
|
1533
|
-
|
|
1532
|
+
};
|
|
1533
|
+
var generateAppContext = () => {
|
|
1534
1534
|
return renderTemplate3("src/app.context.ts.hbs", {});
|
|
1535
|
-
}
|
|
1536
|
-
|
|
1535
|
+
};
|
|
1536
|
+
var generateEventsModule = () => {
|
|
1537
1537
|
return renderTemplate3("src/events/events.module.ts.hbs", {});
|
|
1538
|
-
}
|
|
1539
|
-
|
|
1538
|
+
};
|
|
1539
|
+
var generateEventsService = (serviceName) => {
|
|
1540
1540
|
return renderTemplate3("src/events/events.service.ts.hbs", { serviceName });
|
|
1541
|
-
}
|
|
1542
|
-
|
|
1541
|
+
};
|
|
1542
|
+
var generateNestDockerfile = (nodeVersion = "24", bunVersion = "1.2.23") => {
|
|
1543
1543
|
return renderTemplate3("Dockerfile.hbs", { nodeVersion, bunVersion });
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1544
|
+
};
|
|
1545
|
+
var generateNestBiomeJson = () => {
|
|
1546
1546
|
return renderTemplate3("biome.json.hbs", {});
|
|
1547
|
-
}
|
|
1548
|
-
|
|
1547
|
+
};
|
|
1548
|
+
var generateNestEnvTs = (serviceName, envVars = []) => {
|
|
1549
1549
|
return renderTemplate3("src/config/env.ts.hbs", {
|
|
1550
1550
|
envKey: toEnvKey(serviceName),
|
|
1551
1551
|
envVars
|
|
1552
1552
|
});
|
|
1553
|
-
}
|
|
1553
|
+
};
|
|
1554
1554
|
|
|
1555
1555
|
// cli/src/core/templates/nest.template.ts
|
|
1556
1556
|
var generatePackageJson2 = (vars) => {
|
|
@@ -1884,11 +1884,7 @@ var validateFile = (file, layout) => {
|
|
|
1884
1884
|
});
|
|
1885
1885
|
}
|
|
1886
1886
|
if (isInConstrainedDir(file.path, layout.codingConstraints.appliesTo)) {
|
|
1887
|
-
const patternViolations = findPatternViolations(
|
|
1888
|
-
file.content,
|
|
1889
|
-
layout.codingConstraints.forbiddenPatterns,
|
|
1890
|
-
file.path
|
|
1891
|
-
);
|
|
1887
|
+
const patternViolations = findPatternViolations(file.content, layout.codingConstraints.forbiddenPatterns, file.path);
|
|
1892
1888
|
violations.push(...patternViolations);
|
|
1893
1889
|
}
|
|
1894
1890
|
return violations;
|
package/dist/facade.mjs
CHANGED
|
@@ -123,14 +123,7 @@ import { dirname, isAbsolute, join as join2, normalize, resolve, sep } from "pat
|
|
|
123
123
|
import { fileURLToPath } from "url";
|
|
124
124
|
import { packageUpSync } from "package-up";
|
|
125
125
|
import { rimraf } from "rimraf";
|
|
126
|
-
|
|
127
|
-
const packageJsonPath = packageUpSync({ cwd: dirname(getModuleFilename()) });
|
|
128
|
-
if (!packageJsonPath) {
|
|
129
|
-
throw new Error("Could not find package.json");
|
|
130
|
-
}
|
|
131
|
-
return dirname(packageJsonPath);
|
|
132
|
-
}
|
|
133
|
-
var getModuleFilename;
|
|
126
|
+
var getModuleFilename, getCliRoot;
|
|
134
127
|
var init_fs = __esm({
|
|
135
128
|
"cli/src/utils/fs.ts"() {
|
|
136
129
|
"use strict";
|
|
@@ -142,6 +135,13 @@ var init_fs = __esm({
|
|
|
142
135
|
}
|
|
143
136
|
return process.cwd();
|
|
144
137
|
};
|
|
138
|
+
getCliRoot = () => {
|
|
139
|
+
const packageJsonPath = packageUpSync({ cwd: dirname(getModuleFilename()) });
|
|
140
|
+
if (!packageJsonPath) {
|
|
141
|
+
throw new Error("Could not find package.json");
|
|
142
|
+
}
|
|
143
|
+
return dirname(packageJsonPath);
|
|
144
|
+
};
|
|
145
145
|
}
|
|
146
146
|
});
|
|
147
147
|
|
|
@@ -1258,21 +1258,21 @@ var getTemplatesDir = () => {
|
|
|
1258
1258
|
);
|
|
1259
1259
|
};
|
|
1260
1260
|
var renderTemplate2 = (templateName, data = {}) => createTemplateRenderer(getTemplatesDir())(templateName, data);
|
|
1261
|
-
|
|
1261
|
+
var generateHonoTsConfig = () => {
|
|
1262
1262
|
return renderTemplate2("tsconfig.json.hbs");
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1263
|
+
};
|
|
1264
|
+
var generateHonoDockerfile = (bunVersion = "1.2.23") => {
|
|
1265
1265
|
return renderTemplate2("Dockerfile.hbs", { bunVersion });
|
|
1266
|
-
}
|
|
1267
|
-
|
|
1266
|
+
};
|
|
1267
|
+
var generateHonoBiomeJson = () => {
|
|
1268
1268
|
return renderTemplate2("biome.json.hbs");
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1269
|
+
};
|
|
1270
|
+
var generateHonoEnvTs = (serviceName, envVars = []) => {
|
|
1271
1271
|
return renderTemplate2("src/config/env.ts.hbs", {
|
|
1272
1272
|
envKey: toEnvKey(serviceName),
|
|
1273
1273
|
envVars
|
|
1274
1274
|
});
|
|
1275
|
-
}
|
|
1275
|
+
};
|
|
1276
1276
|
|
|
1277
1277
|
// cli/src/core/templates/hono-bun.template.ts
|
|
1278
1278
|
var generateImports = (hasEvents) => {
|
|
@@ -1451,35 +1451,35 @@ var getTemplatesDir2 = () => {
|
|
|
1451
1451
|
);
|
|
1452
1452
|
};
|
|
1453
1453
|
var renderTemplate3 = (templateName, data = {}) => createTemplateRenderer(getTemplatesDir2())(templateName, data);
|
|
1454
|
-
|
|
1454
|
+
var generateNestMainTs = (serviceName, defaultPort = 3e3) => {
|
|
1455
1455
|
return renderTemplate3("src/main.ts.hbs", {
|
|
1456
1456
|
serviceName,
|
|
1457
1457
|
envKey: toEnvKey(serviceName),
|
|
1458
1458
|
displayName: toDisplayName(serviceName),
|
|
1459
1459
|
defaultPort
|
|
1460
1460
|
});
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1461
|
+
};
|
|
1462
|
+
var generateAppContext = () => {
|
|
1463
1463
|
return renderTemplate3("src/app.context.ts.hbs", {});
|
|
1464
|
-
}
|
|
1465
|
-
|
|
1464
|
+
};
|
|
1465
|
+
var generateEventsModule = () => {
|
|
1466
1466
|
return renderTemplate3("src/events/events.module.ts.hbs", {});
|
|
1467
|
-
}
|
|
1468
|
-
|
|
1467
|
+
};
|
|
1468
|
+
var generateEventsService = (serviceName) => {
|
|
1469
1469
|
return renderTemplate3("src/events/events.service.ts.hbs", { serviceName });
|
|
1470
|
-
}
|
|
1471
|
-
|
|
1470
|
+
};
|
|
1471
|
+
var generateNestDockerfile = (nodeVersion = "24", bunVersion = "1.2.23") => {
|
|
1472
1472
|
return renderTemplate3("Dockerfile.hbs", { nodeVersion, bunVersion });
|
|
1473
|
-
}
|
|
1474
|
-
|
|
1473
|
+
};
|
|
1474
|
+
var generateNestBiomeJson = () => {
|
|
1475
1475
|
return renderTemplate3("biome.json.hbs", {});
|
|
1476
|
-
}
|
|
1477
|
-
|
|
1476
|
+
};
|
|
1477
|
+
var generateNestEnvTs = (serviceName, envVars = []) => {
|
|
1478
1478
|
return renderTemplate3("src/config/env.ts.hbs", {
|
|
1479
1479
|
envKey: toEnvKey(serviceName),
|
|
1480
1480
|
envVars
|
|
1481
1481
|
});
|
|
1482
|
-
}
|
|
1482
|
+
};
|
|
1483
1483
|
|
|
1484
1484
|
// cli/src/core/templates/nest.template.ts
|
|
1485
1485
|
var generatePackageJson2 = (vars) => {
|
|
@@ -1813,11 +1813,7 @@ var validateFile = (file, layout) => {
|
|
|
1813
1813
|
});
|
|
1814
1814
|
}
|
|
1815
1815
|
if (isInConstrainedDir(file.path, layout.codingConstraints.appliesTo)) {
|
|
1816
|
-
const patternViolations = findPatternViolations(
|
|
1817
|
-
file.content,
|
|
1818
|
-
layout.codingConstraints.forbiddenPatterns,
|
|
1819
|
-
file.path
|
|
1820
|
-
);
|
|
1816
|
+
const patternViolations = findPatternViolations(file.content, layout.codingConstraints.forbiddenPatterns, file.path);
|
|
1821
1817
|
violations.push(...patternViolations);
|
|
1822
1818
|
}
|
|
1823
1819
|
return violations;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crossdelta/platform-sdk",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.8",
|
|
4
4
|
"description": "Platform toolkit for event-driven microservices — keeping code and infrastructure in lockstep.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -81,8 +81,8 @@
|
|
|
81
81
|
"schematics": "./dist/schematics/collection.json",
|
|
82
82
|
"dependencies": {
|
|
83
83
|
"@angular-devkit/core": "^21.0.0",
|
|
84
|
-
"@crossdelta/cloudevents": "^0.10.
|
|
85
|
-
"@crossdelta/flowcore": "^0.1.
|
|
84
|
+
"@crossdelta/cloudevents": "^0.10.1",
|
|
85
|
+
"@crossdelta/flowcore": "^0.1.3",
|
|
86
86
|
"@faker-js/faker": "^9.8.0",
|
|
87
87
|
"@listr2/prompt-adapter-enquirer": "^2.0.15",
|
|
88
88
|
"chalk": "^5.4.1",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"rimraf": "^6.1.2",
|
|
101
101
|
"terminal-link": "^4.0.0",
|
|
102
102
|
"zod": "^4.0.0",
|
|
103
|
-
"@crossdelta/infrastructure": "^0.
|
|
103
|
+
"@crossdelta/infrastructure": "^0.19.0"
|
|
104
104
|
},
|
|
105
105
|
"peerDependencies": {
|
|
106
106
|
"@nestjs/schematics": "^11.0.5",
|