@crossdelta/platform-sdk 0.19.8 → 0.19.10
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/README.md +3 -3
- package/bin/chunk-634PL24Z.mjs +0 -0
- package/bin/cli.mjs +44 -41
- package/bin/config-CKQHYOF4.mjs +0 -0
- package/bin/templates/workspace/.github/workflows/build-and-deploy.yml.hbs +3 -0
- package/bin/templates/workspace/.github/workflows/publish-packages.yml +15 -11
- package/bin/templates/workspace/infra/package.json.hbs +2 -2
- package/bin/templates/workspace/packages/contracts/package.json.hbs +2 -2
- package/package.json +4 -4
package/README.md
CHANGED
package/bin/chunk-634PL24Z.mjs
CHANGED
|
File without changes
|
package/bin/cli.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{A as Ur,C as Tt,D as Et,F as
|
|
2
|
+
import{A as Ur,C as Tt,D as Et,F as A,G as ue,H as $t,a as Or,b as T,c as Y,d as _r,e as Lr,f as E,g as St,h as bt,i as Wr,j as Hr,k as L,l as Re,m as Ne,n as $,o as Gr,p as Fe,q as Br,r as d,s as I,t as Me,v as h,w as G,x as w,y as De,z as C}from"./chunk-634PL24Z.mjs";import{argv as $d}from"process";import Ae from"chalk";import{Command as Id}from"commander";import Ad from"terminal-link";import mi from"chalk";import{Command as di}from"commander";import{existsSync as si}from"fs";import{join as ii}from"path";import{cwd as qr}from"process";import{execaSync as ai}from"execa";import{spawn as Vr}from"child_process";import{resolve as Xs}from"path";import{execa as Qs}from"execa";import{existsSync as qs}from"fs";import{resolve as Ys}from"path";import{config as Zs}from"dotenv";var It=(e,t)=>{let r=Ys(t,e);return qs(r)?Zs({path:r,processEnv:{}}).parsed||{}:{}},zr=(e,t)=>{let r=It(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(i)}return n};var At={...process.env,NODE_NO_WARNINGS:"1"},ei=(e,t,r)=>e?"pipe":t||r?["ignore","pipe","pipe"]:"inherit",ti=(e,t,r)=>e?{...At,...e}:t||r?{...At,CI:"true"}:{...At},ri=e=>e.includes("EEXIST")||e.includes("failed to link package");async function W(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 l=Qs(e,t,{cwd:r,stdio:ei(i,n,a),all:n||a?!0:void 0,shell:o??!0,env:ti(c,n,a)});l.all&&l.all.on("data",p=>{let m=p.toString().trim();n?(n.output=m,m.length&&d.storeLog(m,s)):a&&m.length&&console.log(m)}),await l}catch(l){let p=l instanceof Error?l.message:String(l);if(ri(p))return;throw new Error(ni(p))}}var ni=e=>{let t=e.match(/error: (.+)/);return t?t[1].trim():e};function Kr(e,t,r={}){let{cwd:n=process.cwd(),envFile:o,detached:s=!0,pipeStdout:i=!1,onStdout:a,onStderr:c,onExit:l}=r,p=o?It(o,n):{},m=Xs(n,"node_modules",".bin"),f=process.env.PATH||"",F=`${m}:${f}`,ge={...process.env,...p,PATH:F,FORCE_COLOR:"1"},b=Vr(e,t,{cwd:n,env:ge,stdio:["inherit",i?"pipe":"inherit","pipe"],detached:s});return a&&i&&b.stdout?.on("data",a),c&&b.stderr?.on("data",c),l&&b.on("exit",l),b}function je(e,t,r={}){let{cwd:n=process.cwd()}=r;Vr(e,t,{cwd:n,stdio:"inherit",shell:!0}).on("exit",s=>process.exit(s||0))}async function Jr(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(`
|
|
3
3
|
`).filter(Boolean);for(let s of o)try{process.kill(Number.parseInt(s,10),"SIGKILL")}catch{}}catch{}}var Oe=e=>Ne(e);function Rt(e=process.cwd()){let t=r=>si(ii(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"}function x(e){return Rt(e)??ci()}function ci(){return Oe("bun")?"bun":Oe("pnpm")?"pnpm":Oe("yarn")?"yarn":"npm"}function Yr(){return["bun","pnpm","yarn","npm"].filter(Oe)}async function M(e,t){let r=li(e,t),{mergedOptions:n,packages:o}=r,{cwd:s=process.cwd(),flags:i=[],task:a,quiet:c}=n,l=n.packageManager??x(),p=[],m=Array.isArray(o)?o:[o];l==="bun"&&(m=m.map(F=>F.replace("git+ssh://",""))),l==="pnpm"&&(p.push("--config.engine-strict=false"),p.push("--no-frozen-lockfile")),["yarn","npm"].includes(l)&&p.push("--ignore-engines");let f=m.length?l==="npm"?["install",...i,...p,...m]:["add",...i,...p,...m]:["install",...i,...p];await W(l,f,{cwd:s,task:a,quiet:c})}async function Zr(e){let t=["-g"],r=[...e.flags??[],...t];await M({...e,flags:r,packageManager:e.packageManager??x()})}function Xr(e,t,r){let{args:n,mergedOptions:o}=en(t??[],r),s=o.manager??x(),{command:i,args:a}=Qr(s);console.log(`
|
|
4
4
|
Running command: ${i} ${[...a,e,...n].join(" ")}
|
|
5
|
-
`),ai(i,[...a,e,...n],{cwd:o.cwd??qr(),stdio:"inherit",preferLocal:!0})}async function fe(e,t,r){let{args:n,mergedOptions:o}=en(t??[],r),s=o.manager??x(),{command:i,args:a}=Qr(s);await W(i,[...a,e,...n],o)}async function he(e,t){let{script:r,mergedOptions:n}=pi(e,t),o=n.packageManager??x();await W(o,["run",r,...n.args??[]],{cwd:n.cwd??qr(),task:n.task})}function Qr(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}}function li(e,t){return Array.isArray(e)?{packages:e,mergedOptions:{...t,packages:e}}:{packages:e.packages??[],mergedOptions:e}}function en(e,t){return Array.isArray(e)?{args:e,mergedOptions:t??{}}:{args:[],mergedOptions:e}}function pi(e,t){return typeof e=="string"?{script:e,mergedOptions:t??{}}:{script:e.script,mergedOptions:e}}var gi=e=>e==="yarn"?["npm","audit"]:["audit"],tn=new di("audit").description("Run security audit on dependencies").allowUnknownOption(!0).action((e,t)=>{try{let r=h(),n=x(),o=gi(n),s=t.args||[];console.log(mi.dim(`Running ${n} ${[...o,...s].join(" ")}`)),je(n,[...o,...s],{cwd:r})}catch(r){
|
|
5
|
+
`),ai(i,[...a,e,...n],{cwd:o.cwd??qr(),stdio:"inherit",preferLocal:!0})}async function fe(e,t,r){let{args:n,mergedOptions:o}=en(t??[],r),s=o.manager??x(),{command:i,args:a}=Qr(s);await W(i,[...a,e,...n],o)}async function he(e,t){let{script:r,mergedOptions:n}=pi(e,t),o=n.packageManager??x();await W(o,["run",r,...n.args??[]],{cwd:n.cwd??qr(),task:n.task})}function Qr(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}}function li(e,t){return Array.isArray(e)?{packages:e,mergedOptions:{...t,packages:e}}:{packages:e.packages??[],mergedOptions:e}}function en(e,t){return Array.isArray(e)?{args:e,mergedOptions:t??{}}:{args:[],mergedOptions:e}}function pi(e,t){return typeof e=="string"?{script:e,mergedOptions:t??{}}:{script:e.script,mergedOptions:e}}var gi=e=>e==="yarn"?["npm","audit"]:["audit"],tn=new di("audit").description("Run security audit on dependencies").allowUnknownOption(!0).action((e,t)=>{try{let r=h(),n=x(),o=gi(n),s=t.args||[];console.log(mi.dim(`Running ${n} ${[...o,...s].join(" ")}`)),je(n,[...o,...s],{cwd:r})}catch(r){E(r)}});import H from"chalk";import{existsSync as Ei,readFileSync as $i,writeFileSync as Ii}from"fs";import{homedir as Ai}from"os";import{join as Ri}from"path";import{createCipheriv as ui,createDecipheriv as fi,createHash as hi,randomBytes as yi}from"crypto";import{existsSync as vi,readFileSync as Ci,writeFileSync as ki}from"fs";import{homedir as rn,hostname as xi,userInfo as Pi}from"os";import{join as wi}from"path";var Nt=wi(rn(),".platform-sdk-keys"),nn="aes-256-gcm",on=()=>{let e=`${xi()}:${Pi().username}:${rn()}`;return hi("sha256").update(e).digest()},sn=()=>{if(!vi(Nt))return{};try{return JSON.parse(Ci(Nt,"utf-8"))}catch{return{}}},Si=e=>{ki(Nt,JSON.stringify(e,null,2),{mode:384})},bi=e=>{let t=on(),r=yi(16),n=ui(nn,t,r),o=n.update(e,"utf8","hex");return o+=n.final("hex"),{iv:r.toString("hex"),tag:n.getAuthTag().toString("hex"),data:o}},Ti=e=>{let t=on(),r=Buffer.from(e.iv,"hex"),n=Buffer.from(e.tag,"hex"),o=fi(nn,t,r);o.setAuthTag(n);let s=o.update(e.data,"hex","utf8");return s+=o.final("utf8"),s};async function an(e,t){let r=sn();r[e]=bi(t),Si(r)}async function _e(e){let r=sn()[e];if(!r)return null;try{return Ti(r)}catch{return null}}var ye={openai:{id:"openai",name:"OpenAI",defaultApiKeyEnvVar:"OPENAI_API_KEY",defaultModel:"gpt-4o-mini",modelsApiUrl:"https://api.openai.com/v1/models",apiKeyUrl:"https://platform.openai.com/api-keys",buildHeaders:e=>({Authorization:`Bearer ${e}`}),parseModelsResponse:e=>e.data??[],modelFilters:[/^gpt-4/,/^gpt-3\.5/,/^o1/,/^o3/]},anthropic:{id:"anthropic",name:"Anthropic (Claude)",defaultApiKeyEnvVar:"ANTHROPIC_API_KEY",defaultModel:"claude-sonnet-4-20250514",modelsApiUrl:"https://api.anthropic.com/v1/models",apiKeyUrl:"https://console.anthropic.com/settings/keys",buildHeaders:e=>({"x-api-key":e,"anthropic-version":"2023-06-01"}),parseModelsResponse:e=>(e.data??[]).map(r=>({id:r.id,created:new Date(r.created_at).getTime()})),modelFilters:[/^claude-/]}};function cn(){return Object.entries(ye).map(([e,t])=>({name:t.name,value:e}))}function ve(e){let t=ye[e];if(!t)throw new Error(`Unknown AI provider: ${e}`);return t}var B=Ri(Ai(),".platform-sdk-ai.json"),Ni=()=>{let e="anthropic",t=ye[e];return{provider:e,model:t.defaultModel}},Ft=Ni();function Ce(){return Ei(B)}function Le(){if(!Ce())throw new Error("AI configuration not found. Please run 'pf ai:setup' to configure your AI provider.");try{let e=$i(B,"utf-8"),t=JSON.parse(e);return{...Ft,...t}}catch{throw new Error(`Failed to load AI configuration from ${B}. Please run 'pf setup --ai' again.`)}}function ln(e){let t=JSON.stringify(e,null,2);Ii(B,t,"utf-8")}async function pn(e,t){await an(e,t)}async function mn(e){let t=await _e(e.provider);if(t)return t;let r=ye[e.provider],n=process.env[r.defaultApiKeyEnvVar];if(n)return n;throw new Error("API key not found. Please run 'pf setup --ai' to configure your API key.")}var Fi=async(e,t,r,n)=>{let{createOpenAI:o}=await import("@ai-sdk/openai"),s=o({apiKey:r});if(n.onToken){let{streamText:c}=await import("ai"),l=c({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature}),p="";for await(let m of(await l).textStream)p+=m,n.onToken(m);return p}let{generateText:i}=await import("ai"),{text:a}=await i({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature});return a},Mi=async(e,t,r,n)=>{let{createAnthropic:o}=await import("@ai-sdk/anthropic"),s=o({apiKey:r});if(n.onToken){let{streamText:c}=await import("ai"),l=c({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature}),p="";for await(let m of(await l).textStream)p+=m,n.onToken(m);return p}let{generateText:i}=await import("ai"),{text:a}=await i({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature});return a};async function dn(e,t,r={}){let{system:n,maxTokens:o=4096,temperature:s=.7,onToken:i}=r,a=await mn(e);switch(e.provider){case"openai":return Fi(t,e.model,a,{system:n,maxTokens:o,temperature:s,onToken:i});case"anthropic":return Mi(t,e.model,a,{system:n,maxTokens:o,temperature:s,onToken:i});default:throw new Error(`Unsupported AI provider: ${e.provider}`)}}import{existsSync as Jn,readFileSync as cc,unlinkSync as lc,writeFileSync as pc}from"fs";import{join as qn,resolve as Vn}from"path";import{input as mc}from"@inquirer/prompts";import u from"chalk";import dc from"ora";import{existsSync as Mt,readdirSync as Oi}from"fs";import{dirname as _i,join as gn}from"path";import{dirname as Di}from"path";import{fileURLToPath as ji}from"url";var D=e=>Di(ji(e));var Li=()=>typeof import.meta?.url=="string"?D(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),U=e=>{let t=e??Li(),r=o=>Mt(gn(o,"package.json")),n=_i(t);if(r(t))return t;if(t==="/")throw new Error("Could not find package.json (package root)");return U(n)},un=(e,t)=>{let r=e.find(Mt);if(!r)throw new Error(t??`Directory not found. Searched in: ${e.join(", ")}`);return r},fn=async e=>{let{getWorkspacePathsConfig:t}=await import("./config-CKQHYOF4.mjs"),r=t(e);return[r.services,r.apps].flatMap(o=>{let s=gn(e,o);if(!Mt(s))return[];try{return Oi(s,{withFileTypes:!0}).filter(i=>i.isDirectory()&&i.name!==".gitkeep").map(i=>`${o}/${i.name}`)}catch{return[]}})};import{existsSync as pa,readFileSync as ma}from"fs";import{join as da}from"path";import{Project as ga}from"ts-morph";import{deriveEventNames as Eu,getContractPaths as $u,getStreamName as Iu}from"@crossdelta/cloudevents";import{existsSync as We,readFileSync as hn,writeFileSync as Wi}from"fs";import{join as Dt}from"path";import{getStreamName as Hi}from"@crossdelta/cloudevents";var yn=(e,t)=>{let r=Dt(e,"src","index.ts");if(!We(r))return!1;let n=hn(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)},Gi=e=>{if(e.includes("@crossdelta/cloudevents"))return e;let t=`import { consumeJetStreams } from '@crossdelta/cloudevents'
|
|
6
6
|
`,r=e.match(/import\s+['"]@crossdelta\/telemetry['"]\s*\n/);if(r){let o=(r.index??0)+r[0].length;return`${e.slice(0,o)}
|
|
7
7
|
${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},Bi=(e,t)=>`
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@ consumeJetStreams({
|
|
|
12
12
|
consumer: '${t}-service',
|
|
13
13
|
discover: './src/events/**/*.handler.ts',
|
|
14
14
|
})`,jt=(e,t)=>{let r=Hi(t),n=Dt(e,"src","index.ts"),o=Dt(e,"src","main.ts");if(!We(n)&&We(o))return{added:!1,streamName:r};if(!We(n))return{added:!1,streamName:r,warning:"Entry point not found (index.ts or main.ts)"};if(yn(e,r))return{added:!1,streamName:r};let s=hn(n,"utf-8"),i=e.split("/").pop()||"unknown";s.includes("consumeJetStreams")||(s=Gi(s));let a=Bi(r,i),c=`${s.trimEnd()+a}
|
|
15
|
-
`;return Wi(n,c,"utf-8"),{added:!0,streamName:r}};import{existsSync as
|
|
15
|
+
`;return Wi(n,c,"utf-8"),{added:!0,streamName:r}};import{existsSync as Gg,readFileSync as Bg}from"fs";import{join as zg}from"path";import{contractCreated as Kg,deriveEventNames as Jg,generateContract as qg,getContractFilePath as Yg}from"@crossdelta/cloudevents";import{readdirSync as Ui,readFileSync as zi}from"fs";import{join as vn}from"path";import{getStreamName as Vi,pluralize as Ki,singularize as Ji}from"@crossdelta/cloudevents";var Cn=e=>{try{return Ui(e,{withFileTypes:!0}).flatMap(r=>{let n=vn(e,r.name);return r.isDirectory()?Cn(n):r.name.endsWith(".handler.ts")?[n]:[]})}catch{return[]}},Ot=e=>{let t=vn(e,"src","events");return Cn(t).flatMap(n=>{let o=zi(n,"utf-8");return qi(n,o)})},qi=(e,t)=>{let r=Zi(t);if(!r)return[];let n=Yi(r);return n?[{filePath:e,eventType:n,contractName:r}]:[]},Yi=e=>{let r=e.replace(/Contract$/,"").match(/[A-Z][a-z]*/g);if(!r||r.length<2)return null;let n=r[0].toLowerCase(),o=Ji(n),i=r.slice(1).map(a=>a.toLowerCase()).join("-");return`${o}.${i}`},Zi=e=>{let r=/import\s+{([^}]+)}\s+from\s+['"]@[\w-]+\/contracts['"]/.exec(e);return r?r[1].split(",").map(s=>s.trim()).filter(s=>s.endsWith("Contract")).map(s=>s.replace(/\s+as\s+.+$/,"").trim()).at(0)??null:null},_t=e=>{let t=e.reduce((r,n)=>{let o=n.eventType.split(".")[0],s=r.get(o)??[];return r.set(o,[...s,n]),r},new Map);return Array.from(t.entries()).map(([r,n])=>Xi(r,n)).sort((r,n)=>r.stream.localeCompare(n.stream))},Xi=(e,t)=>{let r=Vi(t[0]?.eventType??`${e}.event`),o=`${Ki(e)}.>`;return{stream:r,subjects:[o],handlers:t}},Lt=(e,t)=>e.length===0?"":` // Development: pf dev auto-creates ephemeral streams from contracts
|
|
16
16
|
// Production: Pulumi materializes persistent streams
|
|
17
17
|
|
|
18
18
|
consumeJetStreams({
|
|
@@ -40,10 +40,10 @@ ${r}
|
|
|
40
40
|
${r}
|
|
41
41
|
`),o!==t?(X(e,o,"utf-8"),!0):!1},Wt=(e,t)=>{let{packagePath:r}=C(t),{domain:n,action:o}=ea(e),s=Z(r,"src","events");if(!z(s))return!1;let i=Z(s,n),a=Z(i,"index.ts"),c=Z(s,"index.ts"),l=Z(r,"src","index.ts"),p=e.split(".")[0],m=Z(s,p);p!==n&&z(m)&&(console.warn(`\u26A0\uFE0F Warning: Legacy folder '${p}/' found. Please migrate to '${n}/' to avoid conflicts.`),console.warn(` Run: mv ${m} ${i}`));let f=!1;return ta(a,o)&&(f=!0),ra(c,n)&&(f=!0),na(l)&&(f=!0),f},Ht=(e,t)=>{if(!z(e))return!1;let r=`export * from './events/${t}'`,n=He(e,"utf-8");if(n.includes(`'./events/${t}'`))return!1;let o=n.split(`
|
|
42
42
|
`),s=o.findLastIndex(i=>i.startsWith("export"));return s>=0?o.splice(s+1,0,r):o.push("",r),X(e,o.join(`
|
|
43
|
-
`),"utf-8"),!0};import{existsSync as xn,readdirSync as sa,readFileSync as ia}from"fs";import{join as Pn}from"path";import{generateJsonMockFromContract as aa,getJsonMockPath as ca,initFaker as la}from"@crossdelta/cloudevents";var
|
|
43
|
+
`),"utf-8"),!0};import{existsSync as xn,readdirSync as sa,readFileSync as ia}from"fs";import{join as Pn}from"path";import{generateJsonMockFromContract as aa,getJsonMockPath as ca,initFaker as la}from"@crossdelta/cloudevents";var wn=e=>{let t=e.match(/handleEvent\s*\(\s*(\w+Contract)/m);if(t){let n=e.match(/type:\s*['"]([^'"]+)['"]/m);if(n)return n[1]}let r=e.match(/handleEvent\s*\(\s*\{[^}]*type:\s*['"]([^'"]+)['"]/m);if(r)return r[1];if(t){let s=t[1].replace(/Contract$/,"").split(/(?=[A-Z])/).filter(Boolean);if(s.length>=2){let i=s[0].toLowerCase(),a=s.slice(1).join("").toLowerCase();return`${i}.${a}`}}return null};var Gt=async(e,t={})=>{let r=Pn(e,"src","events");if(!xn(r))return{mockPaths:[],skippedHandlers:[]};await la();let n=sa(r).filter(i=>i.endsWith(".handler.ts")||i.endsWith(".event.ts")),o=[],s=[];for(let i of n){let a=Pn(r,i),c=ia(a,"utf-8"),l=wn(c);if(!l){s.push(`${i} (Could not extract event type)`);continue}let p=t.outputDir??C().packagePath,m=ca(l,p);if(xn(m)&&!t.overwrite){s.push(`${i} (Mock already exists)`);continue}let f=aa(l,p,{useFaker:!0});f&&f.status!=="skipped"&&"ref"in f?o.push(f.ref):s.push(`${i} (Contract not found or generation failed)`)}return{mockPaths:o,skippedHandlers:s}};var Sn=e=>{let t=e.split("/").pop()||"service",r=da(e,"src","events","events.service.ts");if(!pa(r))return!1;let n=Ot(e);if(n.length===0||ma(r,"utf-8").replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"").includes("consumeJetStreams"))return!1;let a=_t(n),c=Lt(a,t);if(!c)return!1;let l=new ga({skipAddingFilesFromTsConfig:!0,skipFileDependencyResolution:!0}),p=l.addSourceFileAtPath(r),m=!1;for(let f of p.getClasses()){let F=f.getMethod("startConsumers");if(!F)continue;let b=[...c.split(`
|
|
44
44
|
`),""," this.logger.log('Event consumers started successfully')"].join(`
|
|
45
|
-
`);F.setBodyText(b),m=!0;break}return m&&l.saveSync(),m};var ua=e=>{let t=e.split(/\s+/),r=t[0],n=t.slice(1);return r==="pf"&&(r=process.argv[1]),{executable:r,args:n}},fa=async(e,t)=>{try{let{executable:r,args:n}=ua(e.command);return await W(r,n,{cwd:t,shell:!1}),{command:e.command,success:!0}}catch(r){return{command:e.command,success:!1,error:r instanceof Error?r.message:String(r)}}},Bt=async(e,t)=>{let r=[];for(let n of e){let o=await fa(n,t);if(r.push(o),!o.success)break}return r},Ut=e=>{let t=[/^pf\s+/,/^bun\s+pf\s+/,/^npx\s+pf\s+/,/^bunx\s+pf\s+/];return e.filter(r=>t.some(n=>n.test(r.command)))},bn=e=>{for(let t of e){let r=t.command.match(/(?:bun\s+)?pf\s+new\s+\S+\s+(\S+)/);if(r)return r[1]}return null};import{existsSync as $n,readFileSync as ka}from"fs";import{join as zt}from"path";import O from"chalk";import{existsSync as Tn,mkdirSync as ha,writeFileSync as ya}from"fs";import{dirname as va}from"path";var Ca=(e,t)=>{let n=e.path.startsWith("packages/")&&t.workspaceRoot?t.workspaceRoot:t.baseDir,o;try{o=Gr(e.path,n)}catch(s){return{status:"failed",path:e.path,error:s.message}}try{if(Tn(o)&&!t.overwrite)return{status:"skipped",path:e.path};if(t.dryRun)return{status:"written",path:e.path};let s=va(o);return Tn(s)||ha(s,{recursive:!0}),ya(o,e.content,"utf-8"),{status:"written",path:e.path}}catch(s){return{status:"failed",path:e.path,error:s.message}}},En=(e,t)=>{let r=e.map(n=>Ca(n,t));return{written:r.filter(n=>n.status==="written").map(n=>n.path),skipped:r.filter(n=>n.status==="skipped").map(n=>n.path),failed:r.filter(n=>n.status==="failed").map(n=>({path:n.path,error:n.error}))}};var xa=(e,t)=>{let r=
|
|
46
|
-
`));for(let r of e)console.log(O.dim(` ${t}/contracts \u2192 ${r}`));console.log()}},Ta=(e,t)=>{let r=/^packages\/contracts\/src\/events\/([^/]+)\.ts$/,n=zt(t,"packages/contracts/src/index.ts");for(let o of e){let s=o.match(r);s&&s[1]!=="index"&&Ht(n,s[1])}},In=async(e,t)=>{t.start("Applying code formatting...");try{await fe("biome",["check","--fix","--unsafe","."],{cwd:e,quiet:!0}),t.succeed("Code formatted!")}catch{t.warn("Code formatting completed with warnings")}},Ea=async(e,t)=>{t.start("Scanning for event handlers...");let{mockPaths:r,skippedHandlers:n}=await Gt(e);if(r.length+n.length===0){t.info("No event handlers found");return}if(r.length>0){t.succeed(`Generated ${r.length} event ${r.length===1?"mock":"mocks"}`),console.log();for(let s of r){let i=s.replace(`${e}/`,"");console.log(O.dim(` ${i}`))}console.log()}else t.succeed("Event handlers found");if(n.length>0){for(let s of n)console.log(O.dim(` \u2139 Skipped: ${s}`));console.log()}},An=async(e,t,r,n)=>{n.start("Writing generated files...");let o=En(e,{baseDir:t,workspaceRoot:r.workspaceRoot,overwrite:!0});if(o.written.length>0){n.succeed(`Created ${o.written.length} files`),console.log();for(let l of o.written)console.log(O.dim(` ${l}`));console.log()}else n.succeed("No files to write");let s=xa(e,r),{existing:i,missing:a,suggestedCommands:c}=
|
|
45
|
+
`);F.setBodyText(b),m=!0;break}return m&&l.saveSync(),m};var ua=e=>{let t=e.split(/\s+/),r=t[0],n=t.slice(1);return r==="pf"&&(r=process.argv[1]),{executable:r,args:n}},fa=async(e,t)=>{try{let{executable:r,args:n}=ua(e.command);return await W(r,n,{cwd:t,shell:!1}),{command:e.command,success:!0}}catch(r){return{command:e.command,success:!1,error:r instanceof Error?r.message:String(r)}}},Bt=async(e,t)=>{let r=[];for(let n of e){let o=await fa(n,t);if(r.push(o),!o.success)break}return r},Ut=e=>{let t=[/^pf\s+/,/^bun\s+pf\s+/,/^npx\s+pf\s+/,/^bunx\s+pf\s+/];return e.filter(r=>t.some(n=>n.test(r.command)))},bn=e=>{for(let t of e){let r=t.command.match(/(?:bun\s+)?pf\s+new\s+\S+\s+(\S+)/);if(r)return r[1]}return null};import{existsSync as $n,readFileSync as ka}from"fs";import{join as zt}from"path";import O from"chalk";import{existsSync as Tn,mkdirSync as ha,writeFileSync as ya}from"fs";import{dirname as va}from"path";var Ca=(e,t)=>{let n=e.path.startsWith("packages/")&&t.workspaceRoot?t.workspaceRoot:t.baseDir,o;try{o=Gr(e.path,n)}catch(s){return{status:"failed",path:e.path,error:s.message}}try{if(Tn(o)&&!t.overwrite)return{status:"skipped",path:e.path};if(t.dryRun)return{status:"written",path:e.path};let s=va(o);return Tn(s)||ha(s,{recursive:!0}),ya(o,e.content,"utf-8"),{status:"written",path:e.path}}catch(s){return{status:"failed",path:e.path,error:s.message}}},En=(e,t)=>{let r=e.map(n=>Ca(n,t));return{written:r.filter(n=>n.status==="written").map(n=>n.path),skipped:r.filter(n=>n.status==="skipped").map(n=>n.path),failed:r.filter(n=>n.status==="failed").map(n=>({path:n.path,error:n.error}))}};var xa=(e,t)=>{let r=w(t.workspaceRoot),n=zt(t.workspaceRoot,r.contracts);if(!$n(n))return[];let o=/import\s+(?:type\s+)?{([^}]+)}\s+from\s+['"]@\w+\/contracts['"]/g,s=new Set;for(let i of e){let a=i.content.matchAll(o);for(let c of a){let p=c[1].split(",").map(m=>m.trim()).map(m=>m.replace(/^type\s+/,"").replace(/\s+as\s+.+$/,"").trim()).filter(m=>m.endsWith("Contract"));for(let m of p)s.add(m)}}return Array.from(s).sort()},Pa=e=>{let t=zt(e,"packages/contracts/src/index.ts");if(!$n(t))return new Set;try{let r=ka(t,"utf-8"),n=new Set,o=/export\s+(?:\*|{[^}]*Contract[^}]*})\s+from\s+['"]\.\/events\/([^'"]+)['"]/g,s=r.matchAll(o);for(let i of s){let a=i[0],c=/(\w+Contract)/g,l=a.matchAll(c);for(let p of l)n.add(p[1])}return n}catch{return new Set}},wa=e=>{let t=e.replace(/Contract$/,""),r=t.split(/(?=[A-Z])/).filter(Boolean);if(r.length<2)return t.toLowerCase();let n=r[0].toLowerCase(),o=r.slice(1).join("").toLowerCase();return`${n}.${o}`},Sa=(e,t,r)=>{let n=Pa(t),o=[],s=[],i=[];for(let a of e)if(n.has(a))o.push(a);else{s.push(a);let c=wa(a),l=r.replace(`${t}/`,"");i.push(`pf cloudevents add ${c} --service ${l}`)}return{existing:o,missing:s,suggestedCommands:i}},ba=(e,t)=>{if(e.length!==0){console.log(O.cyan(`\u{1F4E6} Using existing contracts:
|
|
46
|
+
`));for(let r of e)console.log(O.dim(` ${t}/contracts \u2192 ${r}`));console.log()}},Ta=(e,t)=>{let r=/^packages\/contracts\/src\/events\/([^/]+)\.ts$/,n=zt(t,"packages/contracts/src/index.ts");for(let o of e){let s=o.match(r);s&&s[1]!=="index"&&Ht(n,s[1])}},In=async(e,t)=>{t.start("Applying code formatting...");try{await fe("biome",["check","--fix","--unsafe","."],{cwd:e,quiet:!0}),t.succeed("Code formatted!")}catch{t.warn("Code formatting completed with warnings")}},Ea=async(e,t)=>{t.start("Scanning for event handlers...");let{mockPaths:r,skippedHandlers:n}=await Gt(e);if(r.length+n.length===0){t.info("No event handlers found");return}if(r.length>0){t.succeed(`Generated ${r.length} event ${r.length===1?"mock":"mocks"}`),console.log();for(let s of r){let i=s.replace(`${e}/`,"");console.log(O.dim(` ${i}`))}console.log()}else t.succeed("Event handlers found");if(n.length>0){for(let s of n)console.log(O.dim(` \u2139 Skipped: ${s}`));console.log()}},An=async(e,t,r,n)=>{n.start("Writing generated files...");let o=En(e,{baseDir:t,workspaceRoot:r.workspaceRoot,overwrite:!0});if(o.written.length>0){n.succeed(`Created ${o.written.length} files`),console.log();for(let l of o.written)console.log(O.dim(` ${l}`));console.log()}else n.succeed("No files to write");let s=xa(e,r),{existing:i,missing:a,suggestedCommands:c}=Sa(s,r.workspaceRoot,t);if(i.length>0&&ba(i,r.scope),a.length>0){console.log(O.yellow(`\u26A0\uFE0F Missing contracts (not exported from @${r.scope}/contracts):
|
|
47
47
|
`));for(let l of a)console.log(O.yellow(` ${l}`));console.log(),console.log(O.cyan(`\u{1F4A1} Run these commands to create the missing contracts:
|
|
48
48
|
`));for(let l of c)console.log(O.dim(` ${l}`));console.log()}return Ta(o.written,r.workspaceRoot),o.written.length>0&&await Ea(t,n),{missingContractCommands:c}};import{existsSync as Da,readFileSync as ja}from"fs";import{join as ke}from"path";import{existsSync as $a,readdirSync as Ia,readFileSync as Aa}from"fs";import{join as Ra}from"path";var Rn=e=>{let{eventsPath:t}=C(e);if(!$a(t))return[];let r=[];try{let n=Ia(t).filter(o=>o.endsWith(".ts")&&!o.endsWith(".mock.json")&&o!=="index.ts");for(let o of n){let s=Ra(t,o),i=Aa(s,"utf-8"),a=Na(i,s);a&&r.push(a)}}catch(n){return console.warn("Warning: Could not scan contracts package:",n),[]}return r},Na=(e,t)=>{try{let r=e.match(/export const (\w+Contract) = createContract/);if(!r)return null;let n=r[1],o=e.match(/export type (\w+(?:Data|Event)) = z\.infer/);if(!o)return null;let s=o[1],i=e.match(/type:\s*['"]([^'"]+)['"]/);if(!i)return null;let a=i[1],c=Ma(e);return{name:n,typeName:s,eventType:a,fields:c,filePath:t}}catch{return null}},Fa={string:"string",number:"number",boolean:"boolean",array:"array",object:"object",date:"date"},Ma=e=>{let t=e.match(/z\.object\({([^}]+)\}/);if(!t)return[];let r=t[1],n=/(\w+):\s*z\.(\w+)\([^)]*\)/g,o=[...r.matchAll(n)].map(([,a,c])=>{let l=Fa[c]||c;return`${a}: ${l}`});if(!e.includes("z.array("))return o;let s=/(\w+):\s*z\.array\(/g,i=[...e.matchAll(s)].map(([,a])=>a).filter(a=>!o.some(c=>c.startsWith(a))).map(a=>`${a}: array`);return[...o,...i]},Nn=(e,t)=>{if(e.length===0)return`
|
|
49
49
|
**Available Contracts:**
|
|
@@ -137,7 +137,7 @@ Validation errors:`),...e.map(r=>u.yellow(` \u26A0 ${r}`)),u.dim(`
|
|
|
137
137
|
Response preview:`),u.dim(t)].join(`
|
|
138
138
|
`)}
|
|
139
139
|
`,Q=e=>{e&&process.stdout.write(e)},Cc=(e,t)=>{let r=Wn(e,t),n=Ut(r.commands),o=Ut(r.postCommands),s=Hn(r.files);return s.valid?{files:r.files,commands:n,dependencies:r.dependencies,postCommands:o}:(console.log(`${u.yellow("\u26A0")} Could not extract structured files from AI response`),Q(vc(s.errors,e.slice(0,500))),null)},kc=e=>{console.log(`${u.green("\u2714")} Extracted ${e.files.length} files`),Q(hc(e.files)),Q(Kn(e.commands,"Commands to run","\u{1F527}")),Q(Kn(e.postCommands,"Post-generation commands","\u{1F4DD}")),Q(yc(e.dependencies)),Q(`
|
|
140
|
-
`)},xc=(e,t,r)=>{let n=bn(e);return n&&!n.includes("/")&&!n.startsWith(".")&&(n=`${
|
|
140
|
+
`)},xc=(e,t,r)=>{let n=bn(e);return n&&!n.includes("/")&&!n.startsWith(".")&&(n=`${w().services}/${n}`),n?Vn(r,n):Vn(r,t)},Pc=(e,t)=>{let{serviceTypes:r}=ue(),n=r[t]?.skipFiles||["package.json","tsconfig.json","Dockerfile"];return e.filter(o=>!n.includes(o.path))},ee=()=>{if(!Ce())return{valid:!1,error:u.red.bold(`\u274C AI configuration not found.
|
|
141
141
|
`)+u.yellow("Please run ")+u.cyan.bold("pf setup --ai")+u.yellow(` first to configure your AI provider.
|
|
142
142
|
`)};try{return{valid:!0,config:Le()}}catch(e){return{valid:!1,error:u.red.bold(`\u274C ${e.message}
|
|
143
143
|
`)}}},Ue=async e=>e||mc({message:"\u{1F4DD} Describe what this service should do:",validate:t=>t.trim().length>0||"Please provide a description for the AI to generate code"}),ze=(e,t,r)=>{console.log(u.cyan.bold(`
|
|
@@ -146,19 +146,19 @@ Response preview:`),u.dim(t)].join(`
|
|
|
146
146
|
`))},Ve=async(e,t)=>{let{servicePath:r,description:n="",serviceType:o,packageManager:s}=e,i=r.split("/").pop()||r,a=gc(),c=qn(a.workspaceRoot,Wr);pc(c,`generating:${r}`);let l=()=>{Jn(c)&&lc(c)},p=()=>{l(),process.exit(T.CANCELLED)};process.on("SIGINT",p),process.on("SIGTERM",p);try{console.log(u.cyan.bold(`
|
|
147
147
|
\u{1F916} AI Generation
|
|
148
148
|
`));let m=await uc(t,a,r,n,o,s),f=Cc(m,i);if(!f)return!1;kc(f);let F=dc({text:"Processing files...",color:"cyan"}).start(),ge=fc(f.commands,o),b=xc(ge,r,a.cwd),Vs=Pc(f.files,o);await Gn(ge,b,a.workspaceRoot);let{missingContractCommands:jr}=await An(Vs,b,a,F);if(f.postCommands.length>0)await Jt(f.postCommands,a.workspaceRoot);else if(jr.length>0){console.log(u.cyan(`\u{1F527} Auto-creating missing contracts...
|
|
149
|
-
`));let Ks=jr.map(Js=>({command:Js,isPfCommand:!0}));await Jt(Ks,a.workspaceRoot)}return
|
|
149
|
+
`));let Ks=jr.map(Js=>({command:Js,isPfCommand:!0}));await Jt(Ks,a.workspaceRoot)}return Sn(b),await Bn(f.dependencies,b,F),await In(b,F),!0}finally{process.off("SIGINT",p),process.off("SIGTERM",p),l()}};import{existsSync as Vf}from"fs";import{Project as wc,SyntaxKind as Jf}from"ts-morph";var qf=new wc({skipAddingFilesFromTsConfig:!0,skipFileDependencyResolution:!0});import{promises as qt}from"fs";import Ke from"path";import Yn from"chalk";var Zn=async e=>{await W("bash",["-c",`
|
|
150
150
|
curl -fsSL https://bun.sh/install | bash && if [ -f "$HOME/.bun/bin/bun" ]; then export PATH="$HOME/.bun/bin:$PATH"; fi
|
|
151
151
|
`],{task:e,shell:!0}),await $c()},Yt=()=>Ne("bun"),Xn=()=>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"}),Qn=()=>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"}),$c=async()=>{let e='export PATH="$HOME/.bun/bin:$PATH"',t=process.env.HOME;if(!t){d.error("Could not detect $HOME environment variable. Cannot update shell config.");return}let r=[Ke.join(t,".zshrc"),Ke.join(t,".bashrc"),Ke.join(t,".bash_profile")];for(let n of r)try{if(await qt.stat(n).then(()=>!0).catch(()=>!1)){(await qt.readFile(n,"utf8")).includes(e)||(await qt.appendFile(n,`
|
|
152
152
|
# Added by platform installer
|
|
153
153
|
${e}
|
|
154
|
-
`),d.log(`Added Bun path to ${Ke.basename(n)}`));return}}catch(o){d.error(`Failed to update ${n}: ${o.message}`)}d.warn("No shell config file (.zshrc, .bashrc, .bash_profile) found. Please add the following manually:"),d.log(Yn.cyan(e))};import{existsSync as Ye,mkdirSync as Bc,readFileSync as Uc,renameSync as zc,statSync as so,unlinkSync as Vc,writeFileSync as Kc}from"fs";import{join as
|
|
154
|
+
`),d.log(`Added Bun path to ${Ke.basename(n)}`));return}}catch(o){d.error(`Failed to update ${n}: ${o.message}`)}d.warn("No shell config file (.zshrc, .bashrc, .bash_profile) found. Please add the following manually:"),d.log(Yn.cyan(e))};import{existsSync as Ye,mkdirSync as Bc,readFileSync as Uc,renameSync as zc,statSync as so,unlinkSync as Vc,writeFileSync as Kc}from"fs";import{join as we}from"path";import{existsSync as Ic}from"fs";import{join as Ac}from"path";import Je from"chalk";import Zt from"chalk";var te=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` ${Zt.cyan(o.name)}${s}${o.description}`}),n=e.footer||'Run "<command> --help" for more information';return[Zt.cyan.bold(`
|
|
155
155
|
${e.title}
|
|
156
156
|
`),`Available commands:
|
|
157
157
|
`,...r,"",Zt.dim(`${n}
|
|
158
158
|
`)].join(`
|
|
159
159
|
`)};var Rc=(e,t)=>t.some(r=>r.name()===e),Nc=(e,t)=>t.pf?.commands?.[e]??null,Fc=(e,t)=>!!t.scripts?.[e],Mc=(e,t)=>t.cwd?Ac(e,t.cwd):e,Dc=(e,t)=>t.command||e,jc=(e,t,r,n)=>{let o=Mc(n,r),s=Dc(e,r);if(r.cwd&&!Ic(o))return console.error(Je.red(`
|
|
160
160
|
\u2716 Directory not found: ${o}
|
|
161
|
-
`)),!0;let i=r.cwd?Je.dim(` in ${r.cwd}/`):"";return console.log(Je.dim(`Running ${s}${i}`)),je(s,t,{cwd:o}),!0},Oc=(e,t,r)=>(console.log(Je.dim(`Running workspace script: ${e}`)),he(e,{args:t,cwd:r}),!0);async function _c(e,t,r){if(Rc(e,r))return!1;let n;try{n=h()}catch{return!1}let o=G(n);if(!o)return!1;let s=Nc(e,o);return s?jc(e,t,s,n):Fc(e,o)?Oc(e,t,n):!1}function eo(){let e;try{e=G()}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}}function Xt(){let{configured:e,scripts:t}=eo();return[...e,...t]}function to(){let{configured:e,scripts:t}=eo(),r=[...e,...t];if(r.length===0)return"";let o=G()?.pf?.commands||{},s=r.map(i=>({name:i,description:o[i]?.description||qe[i]||""}));return te({title:"Workspace Commands",commands:s,footer:""})}function ro(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=Xt();for(let a of i)console.log(a);return}_c(o,s,r).then(i=>{i||e.parse(t)})}else e.parse(t)}var no={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"},qe={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"},oo=(e,t)=>t?`${e}:${t}`:e,Lc=()=>Object.entries(no).map(([e,t])=>oo(e,t)),Wc=()=>{try{let e=Xt(),r=G()?.pf?.commands||{},n=Object.keys(no);return e.filter(o=>!n.includes(o)).map(o=>{let s=r[o]?.description||qe[o]||"";return oo(o,s)})}catch{return[]}},Hc=()=>{try{let e=h(),t=C(e),r=`${e}/${t.relativePath}/src`,{discoverEventTypes:n}=Or("@crossdelta/cloudevents");return n(r)}catch{return[]}},Gc=async()=>{try{let e=h();return await fn(e)}catch{return[]}},Qt=async()=>({commands:[...Lc(),...Wc()],events:Hc(),services:await Gc()});var xe="node_modules/.cache/pf",Pe="completion-cache";var Jc=e=>{let t=
|
|
161
|
+
`)),!0;let i=r.cwd?Je.dim(` in ${r.cwd}/`):"";return console.log(Je.dim(`Running ${s}${i}`)),je(s,t,{cwd:o}),!0},Oc=(e,t,r)=>(console.log(Je.dim(`Running workspace script: ${e}`)),he(e,{args:t,cwd:r}),!0);async function _c(e,t,r){if(Rc(e,r))return!1;let n;try{n=h()}catch{return!1}let o=G(n);if(!o)return!1;let s=Nc(e,o);return s?jc(e,t,s,n):Fc(e,o)?Oc(e,t,n):!1}function eo(){let e;try{e=G()}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}}function Xt(){let{configured:e,scripts:t}=eo();return[...e,...t]}function to(){let{configured:e,scripts:t}=eo(),r=[...e,...t];if(r.length===0)return"";let o=G()?.pf?.commands||{},s=r.map(i=>({name:i,description:o[i]?.description||qe[i]||""}));return te({title:"Workspace Commands",commands:s,footer:""})}function ro(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=Xt();for(let a of i)console.log(a);return}_c(o,s,r).then(i=>{i||e.parse(t)})}else e.parse(t)}var no={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"},qe={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"},oo=(e,t)=>t?`${e}:${t}`:e,Lc=()=>Object.entries(no).map(([e,t])=>oo(e,t)),Wc=()=>{try{let e=Xt(),r=G()?.pf?.commands||{},n=Object.keys(no);return e.filter(o=>!n.includes(o)).map(o=>{let s=r[o]?.description||qe[o]||"";return oo(o,s)})}catch{return[]}},Hc=()=>{try{let e=h(),t=C(e),r=`${e}/${t.relativePath}/src`,{discoverEventTypes:n}=Or("@crossdelta/cloudevents");return n(r)}catch{return[]}},Gc=async()=>{try{let e=h();return await fn(e)}catch{return[]}},Qt=async()=>({commands:[...Lc(),...Wc()],events:Hc(),services:await Gc()});var xe="node_modules/.cache/pf",Pe="completion-cache";var Jc=e=>{let t=A.version||"0.0.0",r=e.commands.join("|"),n=e.events.join("|"),o=e.services.join("|");return`${t} ${r} ${n} ${o}`},qc=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:[]}},Yc=e=>{let t=we(e,xe);return we(t,Pe)},Zc=(e,t=!1)=>{if(t)return!0;let r=Yc(e);if(!Ye(r))return!0;let n=Uc(r,"utf-8").trim(),o=qc(n),s=A.version||"0.0.0";if(o.version!==s)return!0;let i=we(e,"package.json");if(!Ye(i))return!1;let a=so(r).mtimeMs;return so(i).mtimeMs>a};var Xc=(e,t)=>{let r=we(e,xe),n=we(r,Pe),o=`${n}.tmp.${process.pid}`;Ye(r)||Bc(r,{recursive:!0});let s=Jc(t);try{Kc(o,s,"utf-8"),zc(o,n)}catch(i){try{Ye(o)&&Vc(o)}catch{}throw i}},Ze=async(e={})=>{let t;try{t=h()}catch{return!1}if(!t)return!1;if(!Zc(t,e.force))return e.verbose&&console.log("[completion] Cache is up to date"),!1;let r=await Qt();return Xc(t,r),e.verbose&&console.log(`[completion] Cache regenerated: ${r.commands.length} commands, ${r.events.length} events`),!0},Se=async(e={})=>{await Ze({...e,force:!0})};import{existsSync as tr,readFileSync as po,writeFileSync as mo}from"fs";import{homedir as go}from"os";import{join as er}from"path";import re from"chalk";var io=`${xe}/${Pe}`,ao=e=>`# ${e} completion (workspace-local cache)
|
|
162
162
|
# Generated: ${new Date().toISOString()}
|
|
163
163
|
|
|
164
164
|
# Cache file path (relative to workspace root)
|
|
@@ -391,9 +391,9 @@ complete -F _${e}_completions ${e}`;var Qc=(e,t)=>er(go(),`.${t}-completion.${e}
|
|
|
391
391
|
`)?`${r}${t}
|
|
392
392
|
`:`${r}
|
|
393
393
|
${t}
|
|
394
|
-
`;mo(e,n,"utf-8")},nl=(e,t)=>{let r=Qc(e,t),n=e==="zsh"?ao(t):co(t);return mo(r,n,"utf-8"),r},lo=(e,t,r)=>{let n=nl(e,t),o=uo(e),s=el(n);return tl(o,s)?(r&&console.log(re.dim(`[${e}] Already configured in ${o}`)),!1):(rl(o,s),r&&console.log(re.green(`[${e}] Added source line to ${o}`)),!0)},ol=()=>(process.env.SHELL||"").includes("zsh")?"zsh":"bash",rr=(e,t=!1)=>{let r=ol();t&&console.log(re.cyan(`Installing ${r} completion...`)),lo(r,e,t);let n=r==="zsh"?"bash":"zsh",o=uo(n);tr(o)&&lo(n,e,t),t&&(console.log(re.green("\u2713 Shell completion installed")),console.log(re.dim(` Run: ${re.cyan("exec $SHELL")} to reload`)))};import{readdir as
|
|
394
|
+
`;mo(e,n,"utf-8")},nl=(e,t)=>{let r=Qc(e,t),n=e==="zsh"?ao(t):co(t);return mo(r,n,"utf-8"),r},lo=(e,t,r)=>{let n=nl(e,t),o=uo(e),s=el(n);return tl(o,s)?(r&&console.log(re.dim(`[${e}] Already configured in ${o}`)),!1):(rl(o,s),r&&console.log(re.green(`[${e}] Added source line to ${o}`)),!0)},ol=()=>(process.env.SHELL||"").includes("zsh")?"zsh":"bash",rr=(e,t=!1)=>{let r=ol();t&&console.log(re.cyan(`Installing ${r} completion...`)),lo(r,e,t);let n=r==="zsh"?"bash":"zsh",o=uo(n);tr(o)&&lo(n,e,t),t&&(console.log(re.green("\u2713 Shell completion installed")),console.log(re.dim(` Run: ${re.cyan("exec $SHELL")} to reload`)))};import{readdir as Dv}from"fs/promises";import{dirname as Ov,join as _v}from"path";import{fileURLToPath as Wv}from"url";import{runFlow as Gv}from"@crossdelta/flowcore";var sl={debug:()=>{},info:console.log,warn:console.warn,error:console.error},fo=e=>e!==null&&typeof e=="object",ho=e=>typeof e=="string"&&e.length>0,yo=e=>typeof e=="string",nr=e=>typeof e=="function",il=(e,t)=>fo(e)?[!ho(e.name)&&`commands[${t}]: missing or invalid 'name'`,!yo(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`,!nr(e.run)&&`commands[${t}]: missing 'run' function`].filter(r=>r!==!1):[`commands[${t}]: must be an object`];var vo=e=>{if(!fo(e))return["Plugin must be an object"];let t=[!ho(e.name)&&"Missing or invalid 'name'",!yo(e.version)&&"Missing or invalid 'version'",!Array.isArray(e.commands)&&"Missing 'commands' array",!Array.isArray(e.flows)&&"Missing 'flows' array",!nr(e.setup)&&"Missing 'setup' function"].filter(n=>n!==!1),r=Array.isArray(e.commands)?e.commands.flatMap((n,o)=>il(n,o)):[];return[...t,...r]},Xe=(e,t=sl)=>({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(!nr(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=vo(s);if(i.length>0)throw new Error(`Plugin from ${e} does not conform to PfPlugin interface:
|
|
395
395
|
- ${i.join(`
|
|
396
|
-
- `)}`);let a=s;return r.debug(`Loaded plugin: ${a.name} v${a.version}`),await a.setup(t),{plugin:a,source:e}};import{deriveEventNames as
|
|
396
|
+
- `)}`);let a=s;return r.debug(`Loaded plugin: ${a.name} v${a.version}`),await a.setup(t),{plugin:a,source:e}};import{deriveEventNames as Vv}from"@crossdelta/cloudevents";import{z as y}from"zod";var et=y.object({dependencies:y.record(y.string(),y.string()).default({}),envVars:y.array(y.object({key:y.string(),description:y.string(),required:y.boolean().default(!0)})).default([]),adapterFile:y.string().optional()}),al=y.object({push:y.string().optional(),email:y.string().optional(),slack:y.string().optional(),sms:y.string().optional()}).optional(),cl=y.object({defaults:al,providers:y.object({push:y.record(y.string(),et).optional(),email:y.record(y.string(),et).optional(),slack:y.record(y.string(),et).optional(),sms:y.record(y.string(),et).optional()}).optional()}),Jh=y.object({notifier:cl.optional()});import{z as g}from"zod";var ll=g.object({type:g.literal("event"),eventType:g.string(),stream:g.string().optional()}),pl=g.object({type:g.literal("http"),method:g.enum(["GET","POST","PUT","DELETE","PATCH"]).optional(),path:g.string().optional()}),Co=g.discriminatedUnion("type",[ll,pl]),ml=g.object({type:g.literal("emit.event"),eventType:g.string()}),dl=g.object({type:g.literal("notify"),channel:g.enum(["push","email","slack","sms"]),provider:g.string().optional()}),gl=g.object({type:g.literal("call.http"),name:g.string().optional(),baseUrl:g.string().optional()}),ul=g.object({type:g.literal("persist"),store:g.enum(["db","kv","cache"]),entity:g.string().optional()}),ko=g.discriminatedUnion("type",[ml,dl,gl,ul]),xo=g.object({serviceName:g.string().regex(/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/),framework:g.enum(["hono","nest"]).default("hono"),triggers:g.array(Co).min(1),actions:g.array(ko).default([])});var Sl=(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=jt(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`})},bl=(e,t,r)=>{let{path:n,eventType:o}=e;if(r?.dryRun){let i=`
|
|
397
397
|
import { createContract } from '@crossdelta/cloudevents'
|
|
398
398
|
import { z } from 'zod'
|
|
399
399
|
|
|
@@ -409,7 +409,7 @@ export default handleEvent(${or(o)}Contract, async (data) => {
|
|
|
409
409
|
console.log('Processing ${o}:', data)
|
|
410
410
|
// TODO: Implement handler logic
|
|
411
411
|
})
|
|
412
|
-
`.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}},El={"stream.wired":
|
|
412
|
+
`.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}},El={"stream.wired":Sl,"contract.created":bl,"handler.created":Tl},sr=(e,t,r)=>e.map(n=>{let o=El[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 st}from"path";import{deriveEventNames as hp}from"@crossdelta/cloudevents";var ir=(e,t,r={})=>({ok:!0,operation:e,summary:t,artifacts:r.artifacts??[],changes:r.changes??[],diagnostics:r.diagnostics??[],next:r.next,data:r.data});import{join as cr}from"path";import{readFileSync as $l}from"fs";import{join as Il}from"path";import Al from"handlebars";var ne=(e,t)=>un(e,t??`Templates directory not found. Searched in: ${e.join(", ")}`),ar=(e,t={})=>{let r=$l(e,"utf-8");return Al.compile(r)(t)},tt=e=>(t,r={})=>{let n=Il(e,t);return ar(n,r)};var _=e=>e.toUpperCase().replace(/-/g,"_");var wo=e=>e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ");var Rl=()=>typeof import.meta?.url=="string"?D(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Nl=()=>{let e=Rl(),t=U();return ne([cr(e,"templates","hono-microservice"),cr(e,"..","hono-microservice","templates"),cr(t,"bin","templates","hono-microservice")],"Hono templates directory not found.")},rt=(e,t={})=>tt(Nl())(e,t);function So(){return rt("tsconfig.json.hbs")}function bo(e="1.2.23"){return rt("Dockerfile.hbs",{bunVersion:e})}function To(){return rt("biome.json.hbs")}function Eo(e,t=[]){return rt("src/config/env.ts.hbs",{envKey:_(e),envVars:t})}var Fl=e=>{let t=["import './config/env'","import '@crossdelta/telemetry'",""];return e&&t.push("import { consumeJetStreams } from '@crossdelta/cloudevents'"),t.push("import { Hono } from 'hono'"),t},Ml=e=>[`const port = Number(process.env.${e}_PORT) || 8080`,"const app = new Hono()","","app.get('/health', (c) => {"," return c.json({ status: 'ok' })","})"],Dl=(e,t)=>["","// Start NATS JetStream consumer","consumeJetStreams({",` streams: [${t.map(r=>`'${r}'`).join(", ")}],`,` consumer: '${e}',`," discover: './src/events/**/*.handler.ts',","})"],jl=()=>["","Bun.serve({"," port,"," fetch: app.fetch,","})","","console.log(`\u{1F680} Service ready at http://localhost:${port}`)"],Ol=e=>{let t=_(e.serviceName);return`${[...Fl(e.hasEvents),"",...Ml(t),...e.hasEvents?Dl(e.serviceName,e.streams):[],...jl()].join(`
|
|
413
413
|
`)}
|
|
414
414
|
`},_l=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)},Ll=e=>`# ${e.serviceName}
|
|
415
415
|
|
|
@@ -431,7 +431,7 @@ ${e.hasEvents?`
|
|
|
431
431
|
This service consumes from:
|
|
432
432
|
${e.streams.map(t=>`- ${t}`).join(`
|
|
433
433
|
`)}`:""}
|
|
434
|
-
`,Wl=()=>"",$o={name:"hono-bun",runtime:"bun",framework:"hono",files:[{path:"src/index.ts",content:Ol},{path:"src/config/env.ts",content:e=>Eo(e.serviceName,e.envVars)},{path:"package.json",content:_l},{path:"tsconfig.json",content:()=>
|
|
434
|
+
`,Wl=()=>"",$o={name:"hono-bun",runtime:"bun",framework:"hono",files:[{path:"src/index.ts",content:Ol},{path:"src/config/env.ts",content:e=>Eo(e.serviceName,e.envVars)},{path:"package.json",content:_l},{path:"tsconfig.json",content:()=>So()},{path:"Dockerfile",content:()=>bo()},{path:"biome.json",content:()=>To()},{path:"README.md",content:Ll},{path:"src/events/.gitkeep",content:Wl,skip:e=>!e.hasEvents}]};import{join as lr}from"path";var Hl=()=>typeof import.meta?.url=="string"?D(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Gl=()=>{let e=Hl(),t=U();return ne([lr(e,"templates","nest-microservice"),lr(e,"..","nest-microservice","templates"),lr(t,"bin","templates","nest-microservice")],"NestJS templates directory not found.")},V=(e,t={})=>tt(Gl())(e,t);function Io(e,t=3e3){return V("src/main.ts.hbs",{serviceName:e,envKey:_(e),displayName:wo(e),defaultPort:t})}function Ao(){return V("src/app.context.ts.hbs",{})}function Ro(){return V("src/events/events.module.ts.hbs",{})}function No(e){return V("src/events/events.service.ts.hbs",{serviceName:e})}function Fo(e="24",t="1.2.23"){return V("Dockerfile.hbs",{nodeVersion:e,bunVersion:t})}function Mo(){return V("biome.json.hbs",{})}function Do(e,t=[]){return V("src/config/env.ts.hbs",{envKey:_(e),envVars:t})}var Bl=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)},Ul=()=>JSON.stringify({extends:"../../../../tsconfig.json",compilerOptions:{outDir:"./dist",rootDir:"./src",experimentalDecorators:!0,emitDecoratorMetadata:!0},include:["src/**/*"],exclude:["node_modules","dist","**/*.test.ts"]},null,2),zl=e=>{let t=["Module","HttpModule"],r=["HttpModule"];return e.hasEvents&&(t.push("OnModuleInit"),r.push("EventsModule")),`import { ${t.join(", ")} } from '@nestjs/common'
|
|
435
435
|
${e.hasEvents?"import { EventsModule } from './events/events.module'":""}
|
|
436
436
|
|
|
437
437
|
@Module({
|
|
@@ -501,7 +501,10 @@ export default handleEvent(${n}, async (data: ${o}) => {
|
|
|
501
501
|
console.log('\u{1F4E6} [${e}] Event received:', data)
|
|
502
502
|
// TODO: Inject and call service
|
|
503
503
|
})
|
|
504
|
-
`},lp=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:oe(r,"stub").delegateFromHandler?t.events.map(o=>{let s=Te(o),i=oe(r,s);return{kind:"file:write",path:mr(e,i.filePath),content:ap(o,t.workspaceScope)}}):[],pp=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:t.events.map(n=>{let{kebab:o}=dr(n),s=pr(r,o);return{kind:"file:write",path:mr(e,s.filePath),content:cp(n,t.workspaceScope,r)}}),mp=e=>e==="hono"?"hono":e==="nest"?"nestjs":"hono",Wo=(e,t,r,n)=>{let o=mp(n.framework),s=op(e,t),i=lp(e,r,o),a=pp(e,r,o),c=sp(r.serviceName,r.port,n),l=ip(r.envVarName,r.port);return[...s,...i,...a,c,l]};import{existsSync as dp,readdirSync as gp,readFileSync as up}from"fs";import{join as Ho}from"path";var Go=4001,fp=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},Bo=e=>{try{let t=Ho(e,"infra","services");return dp(t)?gp(t).filter(n=>n.endsWith(".ts")).reduce((n,o)=>{let s=up(Ho(t,o),"utf-8"),i=fp(s);return i!==null&&n.add(i),n},new Set):new Set}catch(t){return console.warn("Failed to scan ports:",t),new Set}},gr=(e,t)=>e.has(t)?gr(e,t+1):t;var yp=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)`)},vp=(e,t,r)=>{if(t){if(t.startsWith("/"))return t;if(t.startsWith("."))return st(r,t);if(t.includes("/"))return st(r,t)}let n=
|
|
504
|
+
`},lp=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:oe(r,"stub").delegateFromHandler?t.events.map(o=>{let s=Te(o),i=oe(r,s);return{kind:"file:write",path:mr(e,i.filePath),content:ap(o,t.workspaceScope)}}):[],pp=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:t.events.map(n=>{let{kebab:o}=dr(n),s=pr(r,o);return{kind:"file:write",path:mr(e,s.filePath),content:cp(n,t.workspaceScope,r)}}),mp=e=>e==="hono"?"hono":e==="nest"?"nestjs":"hono",Wo=(e,t,r,n)=>{let o=mp(n.framework),s=op(e,t),i=lp(e,r,o),a=pp(e,r,o),c=sp(r.serviceName,r.port,n),l=ip(r.envVarName,r.port);return[...s,...i,...a,c,l]};import{existsSync as dp,readdirSync as gp,readFileSync as up}from"fs";import{join as Ho}from"path";var Go=4001,fp=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},Bo=e=>{try{let t=Ho(e,"infra","services");return dp(t)?gp(t).filter(n=>n.endsWith(".ts")).reduce((n,o)=>{let s=up(Ho(t,o),"utf-8"),i=fp(s);return i!==null&&n.add(i),n},new Set):new Set}catch(t){return console.warn("Failed to scan ports:",t),new Set}},gr=(e,t)=>e.has(t)?gr(e,t+1):t;var yp=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)`)},vp=(e,t,r)=>{if(t){if(t.startsWith("/"))return t;if(t.startsWith("."))return st(r,t);if(t.includes("/"))return st(r,t)}let n=w(r);return st(r,n.services,e)},Cp=e=>[...new Set(e.map(t=>hp(t).streamName))],kp=(e,t,r,n)=>{let s=C(t).packageName.split("/")[0],i=e.events??[],a=i.length>0||e.hasEvents||!1,c=i.length>0?Cp(i):e.streams??[];return{serviceName:e.name,packageName:`${s}/${e.name}`,servicePath:r.replace(`${t}/`,""),port:n,envVarName:_(e.name),hasEvents:a,streams:c,events:i,workspaceScope:s,envVars:e.envVars}},xp=(e,t)=>e.files.filter(r=>!r.skip||!r.skip(t)).map(r=>({path:r.path,content:r.content(t)})),Pp=(e,t,r)=>[...e.map(o=>({type:"file",path:st(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"}],wp=e=>[{command:`cd ${e} && bun dev`,description:"Start this service"},{command:"pf dev",description:"Start all services"}],Uo=e=>{yp(e.name);let t=e.workspaceRoot??h(),r=vp(e.name,e.path,t),n=e.port??gr(Bo(t),Go),o=kp(e,t,r,n),s=_o(e.type),i=xp(s,o),a=Wo(r,i,o,s),c=Pp(i,e.name,r),l=wp(r);return ir("service.generate",`Generated ${e.name} service (port ${n})`,{artifacts:c,changes:a,next:l,data:{serviceName:e.name,servicePath:r,port:n,vars:o}})},zo=e=>{let t=Uo(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}};import S from"chalk";import{execa as Sp}from"execa";import{createJiti as bp}from"jiti";var ur=async e=>{let{stdout:t}=await Sp("sh",["-c",e]);return t.trim()},Tp="pf-local-nats",Ep="2.10-alpine",$p=4222,Ip=8222,Ap=e=>({clientPort:e.clientPort??$p,monitoringPort:e.monitoringPort??Ip,containerName:e.containerName??Tp,version:e.version??Ep}),Rp=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"],Np=e=>({containerName:e.containerName,clientUrl:`nats://localhost:${e.clientPort}`,monitoringUrl:`http://localhost:${e.monitoringPort}`}),Fp=async()=>{try{return await ur("docker info"),!0}catch{return!1}},Mp=async e=>{try{return(await ur(`docker ps -q -f name=${e}`)).length>0}catch{return!1}};var Dp=async e=>{let t=Rp(e);try{return await ur(`docker ${t.join(" ")}`),{success:!0,value:Np(e)}}catch{return{success:!1}}},jp=e=>{console.log(S.green("\u2713 NATS started")),console.log(S.dim(` Client: ${e.clientUrl}`)),console.log(S.dim(` Monitoring: ${e.monitoringUrl}`)),console.log(S.dim(" Streams: ephemeral, auto-created by services")),console.log("")},Vo=async(e={})=>{let t=Ap(e);if(!await Fp())return console.log(S.yellow("\u26A0\uFE0F Docker not available - skipping NATS (services may fail)")),!1;if(await Mp(t.containerName))return console.log(S.dim("\u2713 NATS already running")),!0;console.log(S.cyan("\u{1F680} Starting development infrastructure...")),console.log(S.dim(" NATS with JetStream (ephemeral)"));let r=await Dp(t);return r.success?(jp(r.value),!0):(console.error(S.red("\u2717 Failed to start NATS")),!1)},Op=e=>e.map(t=>({stream:t,subjects:[`${t.toLowerCase()}.*`],config:{storage:"memory",retention:"limits",maxAge:36e5}})),_p=e=>Array.from(new Set(Object.values(e).filter(t=>t!==null&&typeof t=="object"&&"channel"in t).map(t=>t.channel?.stream).filter(t=>!!t))),Lp=e=>{if(!(e instanceof Error))return!0;let t=e.message.toLowerCase();return!t.includes("insufficient storage")&&!t.includes("connection refused")},Wp=e=>{if(!(e instanceof Error))return"Unknown error";let t=e.message.toLowerCase();return t.includes("insufficient storage")?["NATS has insufficient storage to create streams."," Your disk is likely full. Free space and restart:",""," docker system prune -af"," pf dev"].join(`
|
|
505
|
+
`):t.includes("connection refused")?"Cannot connect to NATS \u2014 is the container running?":e.message},fr=async e=>{try{let{ensureJetStreams:t}=await import("@crossdelta/cloudevents"),{indexPath:r}=C(e),o=await bp(e,{moduleCache:!1}).import(r,{default:!0}),s=_p(o);if(s.length===0){console.log(S.dim(" No streams found in contracts"));return}let i=Op(s);await t({streams:i}),console.log(S.dim(` Created ${s.length} ephemeral stream(s): ${s.join(", ")}`))}catch(t){if(!Lp(t))throw console.error(S.red(`
|
|
506
|
+
\u2717 ${Wp(t)}
|
|
507
|
+
`)),t;console.log(S.yellow(` \u26A0\uFE0F Stream creation failed: ${t instanceof Error?t.message:"Unknown error"}`)),console.log(S.dim(" Streams will be created when services connect"))}};function Ko(e,t){return`import type { K8sServiceConfig } from '@crossdelta/infrastructure'
|
|
505
508
|
import { ports } from '@crossdelta/infrastructure'
|
|
506
509
|
|
|
507
510
|
/**
|
|
@@ -543,53 +546,53 @@ const config: K8sServiceConfig = {
|
|
|
543
546
|
}
|
|
544
547
|
|
|
545
548
|
export default config
|
|
546
|
-
`}import K from"chalk";import
|
|
549
|
+
`}import K from"chalk";import Gp from"terminal-link";var it="integrations-run";import{z as P}from"zod";var Hp=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()}),qo=P.array(Hp);var Yo=e=>{try{return qo.parse(e)}catch(t){throw new Error(t.issues.map(r=>` - Path ${r.path.join(". ")} : ${r.message}`).join(`
|
|
547
550
|
`))}};var R=()=>{try{let e=Et("bin/integration.collection.json");return Yo(e)}catch(e){throw new Error(`Failed to load integrations!
|
|
548
551
|
Check your integration.collection.json:
|
|
549
|
-
${e.message}`)}},se=()=>R().reduce((t,r)=>(r.initial&&t.push(r.name),t),[]),
|
|
550
|
-
`))}))},
|
|
551
|
-
`),fn:()=>
|
|
552
|
-
`)),e.shouldInstallBun=await r.toggle({message:"Would you like to use Bun? (recommended)",initial:!0}),e.shouldInstallBun&&(e.packageManager="bun")}};import os from"chalk";var mt={title:"Install integrations",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)
|
|
552
|
+
${e.message}`)}},se=()=>R().reduce((t,r)=>(r.initial&&t.push(r.name),t),[]),Bp=e=>!!e?.name&&!!e?.link&&!!e?.description,at=e=>{let t=R();if(!t?.length||!e?.length)return;let r=e.map(n=>t.find(o=>o.name===n)).filter(Bp);r.length&&(d.breakLine().log("\u{1F50C} Installed Integrations:"),r.forEach(({name:n,link:o,description:s})=>{let i=d.getStoredLogs(`${it}:${n}`);o&&d.log(`${Gp(K.cyan(n),o)} - ${s}`),i.length&&d.log(i.map(a=>` \u203A ${K.dim(a.message)}`).join(`
|
|
553
|
+
`))}))},Up=e=>e.toUpperCase().replace(/-/g,"_"),Zo=(e,t)=>{let r=Up(e);d.breakLine().log(K.bold("Environment variables:")).log(K.dim(" Local (.env.local):")).log(K.cyan(` ${r}_PORT=${t}`)).breakLine().log(K.dim(" Production (auto-injected by infra):")).log(K.cyan(` PORT=${t}`))};import Xo from"chalk";var zp=e=>{let t=e.match(/^(@?[^@]+)@(.+)$/);return t?{name:t[1],version:t[2]}:{name:e,version:"latest"}},Qo=async e=>{let{selectedIntegrations:t,cwd:r,packageManager:n=x(),task:o}=e;if(!t?.length||!o)return;let s=Vp(t,r,n,o);await Me(o,s)},Vp=(e,t,r,n)=>{let s=R()?.filter(a=>e.includes(a.name))?.flatMap(a=>a.install.map(c=>{let{name:l,version:p}=zp(c);return{title:Xo.cyanBright(`Adding ${c} (${a.name})`),fn:async()=>{Tt(`dependencies.${l}`,p,t)}}})),i={title:Xo.cyanBright("Installing packages..."),fn:async()=>{await M({cwd:t,packageManager:r,task:n})}};return[...s??[],i]};import Kp from"chalk";var es=async e=>{let{selectedIntegrations:t,cwd:r,task:n}=e;if(!t?.length||!n)return;let o=Jp(t,r,n,e.packageManager);await Me(n,o)},Jp=(e,t,r,n)=>R().filter(s=>e.includes(s.name)&&s.run?.length).flatMap(s=>(s.run||[]).map(i=>({title:Kp.cyanBright(`Running "${i}" for ${s.name}
|
|
554
|
+
`),fn:()=>qp(s,i,t,r,n)}))),qp=async(e,t,r,n,o)=>{let s=`${it}:${e.name}`;try{if(e.interactive)return Xr(t,[],{cwd:r,context:s,task:n,manager:o});await fe(t,[],{cwd:r,task:n,context:s})}catch(i){d.error(`Failed to run command "${t}" for ${e.name}: ${i.message}`)}};import{readFileSync as HC,writeFileSync as GC}from"fs";import{join as UC}from"path";import{join as JC}from"path";import{ListrEnquirerPromptAdapter as Ee}from"@listr2/prompt-adapter-enquirer";var v=e=>({select:async t=>e.prompt(Ee).run({type:"select",message:t.message,choices:t.choices}),confirm:async t=>e.prompt(Ee).run({type:"confirm",message:t.message,initial:t.initial??!1}),toggle:async t=>e.prompt(Ee).run({type:"toggle",message:t.message,enabled:t.enabled??"Yes",disabled:t.disabled??"No",initial:t.initial??!1}),input:async t=>e.prompt(Ee).run({type:"input",message:t.message,initial:t.initial,validate:t.validate}),multiSelect:async t=>e.prompt(Ee).run({type:"MultiSelect",message:t.message,hint:t.hint,initial:t.initial,choices:t.choices})});import{readFileSync as ck}from"fs";import{join as pk}from"path";import kk from"chalk";import Pk from"cli-table3";function ct(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}async function ts(e,t,r={},n=[],o=[]){if(!e){console.error("Subcommand is not defined.");return}let s=n.map(l=>t[l]).filter(l=>l!==void 0),i=o.map(l=>{let p=t[l];if(!(p===!1||p===void 0))return p===!0?`--${ct(String(l))}`:`--${ct(String(l))}=${String(p)}`}).filter(l=>l!==void 0),a=Object.entries(r).map(([l,p])=>{if(!(p===!1||p===void 0))return p===!0?`--${ct(l)}`:`--${ct(l)}=${String(p)}`}).filter(l=>l!==void 0),c=[...s,...i,...a].map(String);await e.parseAsync(c,{from:"user"})}import{basename as Cm}from"path";import J from"chalk";var ie={title:"Confirm creation",enabled:e=>!e.userConfirmed,task:async(e,t)=>{let r=v(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 hr,readdirSync as Zp,readFileSync as Xp,writeFileSync as Qp}from"fs";import{basename as em,join as yr}from"path";var tm=4001,rm=4e3;function nm(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}function om(e,t){let r=t?tm:rm,n=new Set;if(!hr(e))return r;let o=Zp(e).filter(i=>i.endsWith(".ts"));for(let i of o){let a=yr(e,i);try{let c=Xp(a,"utf-8"),l=nm(c);for(let p of l)n.add(p)}catch{}}let s=r;for(;n.has(s);)s++;return s}function sm(e){return em(e)}var lt={title:"Creating infrastructure service config",task:async(e,t)=>{let r=sm(e.projectName),n=h(),o=yr(n,"infra","services");if(!hr(o)){t.title="Skipping infra config (no infra/services directory found)";return}let s=yr(o,`${r}.ts`);if(hr(s)){t.title=`Service config already exists: infra/services/${r}.ts`;return}let i=om(o,!0);e.assignedPort=i;let a=e.serviceType==="hono"?Ko(r,i):Jo(r,i);Qp(s,a),t.title=`Created infra/services/${r}.ts (port: ${i})`}};import{execSync as pt}from"child_process";import{existsSync as im}from"fs";import{join as am}from"path";var cm=()=>{try{return pt("git --version",{stdio:"ignore"}),!0}catch{return!1}},lm=e=>im(am(e,".git")),rs={title:"Initializing git repository",enabled:()=>cm(),skip:e=>lm(e.cwd)?"Already a git repository":!1,task:async(e,t)=>{try{pt("git init",{cwd:e.cwd,stdio:"ignore"}),pt("git add -A",{cwd:e.cwd,stdio:"ignore"}),pt('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 ns from"chalk";var ae={title:"Installing Bun",enabled:e=>!!e.shouldInstallBun&&!Yt(),task:async(e,t)=>I(t,async r=>{await Zn(t),e.elapsedTime+=r(),t.title=`Bun installed successfully. (${e.elapsedTime}s)`})},ce={enabled:e=>!Yt()&&!e.shouldInstallBun&&!e.packageManager,task:async(e,t)=>{let r=v(t);console.log(["",`${ns.magenta.bold("Bun")} is a fast JavaScript runtime, package manager, bundler, and test runner: ${ns.underline("https://bun.sh")}`,Xn(),Qn()].join(`
|
|
555
|
+
`)),e.shouldInstallBun=await r.toggle({message:"Would you like to use Bun? (recommended)",initial:!0}),e.shouldInstallBun&&(e.packageManager="bun")}};import os from"chalk";var mt={title:"Install integrations",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>I(t,async r=>{let{selectedIntegrations:n,cwd:o,packageManager:s}=e;await Qo({selectedIntegrations:n,packageManager:s,cwd:o,task:t}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}},dt={title:"Select integrations",enabled:e=>e.selectedIntegrations.length===0,task:async(e,t)=>{let r=v(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:se().map((n,o)=>o),choices:e.availableIntegrations.map(({name:n,description:o})=>({name:n,message:[os.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=>os.bold(`\u2022 ${n}`))].join("\\n")}};var ss={title:"Install Nest CLI",task:async(e,t)=>I(t,async r=>{await Zr({packages:["@nestjs/cli"],task:t,cwd:e.cwd}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}};var gt={title:"Install dependencies",task:async(e,t)=>I(t,async r=>{await M({cwd:e.cwd,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()})};import pm from"chalk";var le={enabled:e=>!e.removeDir&&!Fe(e.cwd),task:async(e,t)=>{let r=v(t);if(e.removeDir=await r.toggle({message:pm.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}),!e.removeDir)throw new Error("Project creation was canceled by the user.")}},pe={enabled:e=>!!e.removeDir,task:async e=>Br(e.cwd)};var ut={title:"Run integration commands",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>I(t,async r=>{let{selectedIntegrations:n,cwd:o}=e;await es({selectedIntegrations:n,cwd:o,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1}};var mm=["services/my-hono-service","services/my-nest-service","my-platform"],me={enabled:e=>e.skipInputPrompts||e.userConfirmed?!1:e.projectName?mm.includes(e.projectName):!0,task:async(e,t)=>{let r=v(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 is from"chalk";var de={title:"Select Package manager",task:async(e,t)=>{if(e.packageManager??=Rt(),e.packageManager){t.title=`Using ${is.bold(e.packageManager)} as package manager.`;return}let r=v(t);e.packageManager=await r.select({message:"Which package manager would you like to use?",choices:Yr().map(n=>({name:n,value:n}))}),t.title=`Using ${is.bold(e.packageManager)} as package manager.`}};import ft from"chalk";var as={title:"GitHub repository owner",task:async(e,t)=>{if(e.githubOwner){t.title=`GitHub owner: ${ft.bold(e.githubOwner)}`;return}let r=v(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: ${ft.bold(e.githubOwner)}`}},cs={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=v(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 ls={title:"Pulumi stack name",task:async(e,t)=>{if(e.pulumiStackBase){t.title=`Pulumi stack: ${ft.bold(e.pulumiStackBase)}`;return}let r=e.githubOwner||"myorg",n=e.projectName?.replace(/[^a-zA-Z0-9-]/g,"-")||"myproject",o=`${r}/${n}`,s=v(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: ${ft.bold(e.pulumiStackBase)}`}};import{mkdirSync as dm,writeFileSync as gm}from"fs";import{dirname as um}from"path";var fm=e=>e==="hono"?"hono":"nestjs",hm=e=>{let t=um(e.path);dm(t,{recursive:!0}),gm(e.path,e.content,"utf-8")},ym=(e,t)=>{let r=e.map(o=>{let s=o.path.match(/services\/[^/]+\/(.+)$/);return{path:s?s[1]:o.path,content:o.content}}),n=ot(t,r);if(!n.valid){let o=n.violations.map(s=>` - ${s.code}: ${s.message} (${s.path})`).join(`
|
|
553
556
|
`);throw new Error(`Policy violation(s) detected:
|
|
554
|
-
${o}`)}e.forEach(
|
|
555
|
-
${J.bold(`cd ${e} && ${o} run dev`)}`).breakLine().log("Happy shipping with Hono! \u26A1\uFE0F").breakLine()}});import q from"chalk";var
|
|
556
|
-
${q.bold(`cd ${e} && ${t} run start:dev`)}`).breakLine().log("Happy coding! \u{1F389}").breakLine()}});import N from"chalk";import{spawnSync as wm}from"child_process";import{chmodSync as bm,existsSync as kr,mkdirSync as Tm,readFileSync as Em,writeFileSync as xr}from"fs";import{dirname as $m,join as Pr}from"path";import{existsSync as Pm}from"fs";import{join as yt}from"path";var Sm=()=>typeof import.meta?.url=="string"?D(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Cr=()=>{let e=Sm(),t=U();return ne([yt(e,"templates","workspace"),yt(e,"..","..","..","..","templates","workspace"),yt(t,"bin","templates","workspace")],"Workspace templates directory not found.")},ds=()=>{let e=Cr(),t=yt(e,"packages","contracts");if(!Pm(t))throw new Error(`Contracts templates directory not found at: ${t}`);return t},vt=(e,t)=>ar(e,t);var gs=e=>{e.endsWith(".sh")&&bm(e,493)},Im=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"pnpm-workspace.yaml.hbs",output:"pnpm-workspace.yaml",forPackageManager:"pnpm"},{template:"biome.json.hbs",output:"biome.json"},{template:"turbo.json.hbs",output:"turbo.json"},{template:"bunfig.toml.hbs",output:"bunfig.toml"},{template:"gitignore.hbs",output:".gitignore"},{template:"editorconfig.hbs",output:".editorconfig"},{template:"npmrc.hbs",output:".npmrc"},{template:".vscode/settings.json",output:".vscode/settings.json",isStatic:!0},{template:".vscode/extensions.json",output:".vscode/extensions.json",isStatic:!0},{template:"infra/package.json.hbs",output:"infra/package.json"},{template:"infra/index.ts.hbs",output:"infra/index.ts"},{template:"infra/tsconfig.json.hbs",output:"infra/tsconfig.json"},{template:"infra/Pulumi.yaml.hbs",output:"infra/Pulumi.yaml"},{template:"infra/Pulumi.dev.yaml.hbs",output:"infra/Pulumi.dev.yaml"},{template:"apps/.gitkeep",output:"apps/.gitkeep",isStatic:!0},{template:"services/.gitkeep",output:"services/.gitkeep",isStatic:!0},{template:"packages/.gitkeep",output:"packages/.gitkeep",isStatic:!0},{template:"docs/.gitkeep",output:"docs/.gitkeep",isStatic:!0},{template:"infra/services/.gitkeep",output:"infra/services/.gitkeep",isStatic:!0},{template:".github/README.md",output:".github/README.md",isStatic:!0,isGitHubCI:!0},{template:".github/dependabot.yml",output:".github/dependabot.yml",isStatic:!0,isGitHubCI:!0},{template:".github/workflows/lint-and-tests.yml.hbs",output:".github/workflows/lint-and-tests.yml",isGitHubCI:!0},{template:".github/workflows/build-and-deploy.yml.hbs",output:".github/workflows/build-and-deploy.yml",isGitHubCI:!0},{template:".github/workflows/publish-packages.yml",output:".github/workflows/publish-packages.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/setup-bun-install/action.yml.hbs",output:".github/actions/setup-bun-install/action.yml",isGitHubCI:!0},{template:".github/actions/check-image-tag-exists/action.yml",output:".github/actions/check-image-tag-exists/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-image-tag-exists/index.js",output:".github/actions/check-image-tag-exists/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-path-changes/action.yml",output:".github/actions/check-path-changes/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-path-changes/index.js",output:".github/actions/check-path-changes/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/detect-skipped-services/action.yml",output:".github/actions/detect-skipped-services/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/action.yml",output:".github/actions/generate-scope-matrix/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/index.js",output:".github/actions/generate-scope-matrix/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/prepare-build-context/action.yml",output:".github/actions/prepare-build-context/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/resolve-scope-tags/action.yml",output:".github/actions/resolve-scope-tags/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/resolve-scope-tags/index.js",output:".github/actions/resolve-scope-tags/index.js",isStatic:!0,isGitHubCI:!0}],us={title:"Creating workspace structure",task:async(e,t)=>{if(kr(e.cwd)){t.title="Workspace directory already exists, skipping...";return}let r=Cr(),n=e.includeGitHubCI??!0,o=e.packageManager||"bun",s=c=>{try{let m=wm(c,["--version"],{encoding:"utf-8",timeout:5e3}).stdout?.trim();if(m&&/^\d+\.\d+/.test(m))return`${c}@${m}`}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=Im.filter(c=>!(c.isGitHubCI&&!n||c.forPackageManager&&c.forPackageManager!==o));for(let c of a){let l=Pr(e.cwd,c.output),p=$m(l);if(kr(p)||Tm(p,{recursive:!0}),c.isStatic){let m=Pr(r,c.template);kr(m)?xr(l,Em(m)):xr(l,""),gs(l)}else{let m=Pr(r,c.template),f=vt(m,i);xr(l,f),gs(l)}}t.title="Workspace structure created"}};import{existsSync as hs,mkdirSync as fs,readFileSync as Am,writeFileSync as Rm}from"fs";import{join as Ct}from"path";import Nm from"chalk";var Fm=()=>{let e=Ct(process.cwd(),"package.json");if(!hs(e))throw new Error("Root package.json not found. Please run this command from the workspace root.");let r=JSON.parse(Am(e,"utf-8")).name;if(!r)throw new Error('package.json must have a "name" field');return r.startsWith("@")?r:`@${r}`},Mm=()=>{let e=Fm(),{relativePath:t,packagePath:r}=C();if(hs(r))throw new Error(`${t} already exists. Remove it first if you want to regenerate.`);let n=ds(),o={scope:e,workspaceName:e.replace("@","").replace("/","-")};fs(r,{recursive:!0}),fs(Ct(r,"src","events"),{recursive:!0});let s=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"README.md.hbs",output:"README.md"},{template:"src/index.ts",output:"src/index.ts"},{template:"src/stream-policies.ts.hbs",output:"src/stream-policies.ts"},{template:"src/events/index.ts",output:"src/events/index.ts"}];for(let i of s){let a=Ct(n,i.template),c=Ct(r,i.output),l=vt(a,o);Rm(c,l,"utf-8")}},ys={title:"Initializing contracts package",task:(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),Mm(),t.title="Contracts package initialized"}catch(n){throw t.title=Nm.red(`Contracts package failed: ${n.message}`),n}finally{process.chdir(r)}}};import Dm from"chalk";var vs={title:"Registering shell completion",task:async(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),await we(),t.title="Shell completion registered"}catch{t.title=Dm.dim("Shell completion skipped")}finally{process.chdir(r)}}};var Cs=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=E(r),o=!!t.yes,s=t.packageManager??(o?x():void 0),i=t.packageManager==="bun",a=t.githubOwner??(o?"my-org":void 0),c=t.pulumiStack??(o?`${a}/${r}`:void 0),l=t.github===!1?!1:o?!0:void 0,p=!!e.name,m=t.removeDir||o;return{cwd:n,projectName:r,shouldInstallBun:i,packageManager:s,elapsedTime:0,userConfirmed:o,skipInputPrompts:p&&!o,removeDir:m,githubOwner:a,pulumiStackBase:c,includeGitHubCI:l}},prompts:[{enabled:e=>!e.userConfirmed,task:async(e,t)=>{try{let r=h();if(!await v(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=N.yellow("Warning: Creating nested workspace")}catch(r){if(Y(r)&&r.message?.includes("cancelled"))throw r;t.title="No existing workspace detected"}}},me,le,as,cs,ls,ce,de,ie],actions:[pe,ae,us,ys,gt,rs,vs],onComplete:({projectName:e,includeGitHubCI:t})=>{d.breakLine().log(N.bold.green("Workspace created successfully!")),d.breakLine().log(N.bold("Next steps:")).log(` 1. ${N.cyan(`cd ${e}`)}`).log(` 2. ${N.cyan("exec $SHELL")} ${N.dim("(enable tab completion)")}`),t&&d.breakLine().log(N.bold("GitHub Setup:")).log(" Configure these secrets in your GitHub repository:").log(` \u2022 ${N.yellow("PULUMI_ACCESS_TOKEN")} - Pulumi Cloud access token`).log(` \u2022 ${N.yellow("DIGITALOCEAN_TOKEN")} - DigitalOcean API token`).log(` \u2022 ${N.yellow("NPM_TOKEN")} - (optional) NPM token for private packages`),d.breakLine().log(N.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&&d.log(" .github/").log(" \u251C\u2500\u2500 workflows/ # CI/CD workflows").log(" \u2514\u2500\u2500 actions/ # Custom actions"),d.breakLine().log("Happy coding! \u{1F389}").breakLine()}});var $e=[{name:"Hono Microservice",value:"hono-micro",command:ps,supportsAi:!0},{name:"Nest Microservice",value:"nest-micro",command:ms,supportsAi:!0},{name:"Workspace (Infrastructure)",value:"workspace",command:Cs,supportsAi:!1}],ks=()=>{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??"",useAi:!1,aiDescription:"",elapsedTime:0,cwd:process.cwd()}),prompts:[{enabled:t=>!t.projectType,task:async(t,r)=>{let o=await v(r).select({message:"Select Project type",choices:$e});t.projectType=$e.find(s=>s.name===o)?.value||"",r.title=`Using ${H.bold(o)}`}},{enabled:t=>t.projectType!=="workspace"&&t.projectType!=="",task:async(t,r)=>{try{h(),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(`
|
|
557
|
-
`);throw new Error(n)}}},{enabled:t=>t.projectType==="workspace",task:async(t,r)=>{try{let n=h();if(!await v(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=H.yellow("Warning: Creating nested workspace")}catch(n){if(Y(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 v(r).input({message:s,initial:o});t.servicePath=a.trim(),r.title=`Path: ${H.dim(a)}`}},{enabled:t=>!!$e.find(n=>n.value===t.projectType)?.supportsAi&&ee().valid,task:async(t,r)=>{let o=await v(r).toggle({message:"Use AI to generate service code?",initial:!1});t.useAi=o,r.title=o?H.cyan("\u{1F916} AI-powered generation"):"Standard scaffolding"}},{enabled:t=>t.useAi,task:async(t,r)=>{let o=await v(r).input({message:"Describe what this service should do:"});t.aiDescription=o,r.title=`Description: ${H.dim(o.slice(0,50))}${o.length>50?"...":""}`}},{enabled:t=>{if(!t.servicePath)return!1;let r
|
|
558
|
-
\u{1F4E6} Contracts changed, updating streams...`),await fr(e)},500),n=
|
|
559
|
-
`),
|
|
557
|
+
${o}`)}e.forEach(hm)},vm=async(e,t,r)=>{let{projectName:n,serviceType:o,hasEvents:s,streams:i}=e,a=n.split("/").pop()||n,l=zo({type:o==="hono"?"hono-micro":"nest",name:a,path:n,hasEvents:s,streams:i}),p=l.effects.filter(f=>f.kind==="file:write"),m=fm(o);ym(p,m),e.assignedPort=l.port,e.elapsedTime+=r(),t.title=`Generated ${a} (port ${l.port}, ${e.elapsedTime}s)`},ht={title:"Generating service",task:async(e,t)=>I(t,async r=>{await vm(e,t,r)})};var km=e=>{let t=(e||"my-hono-service").trim();return t.includes("/")||t.startsWith(".")?t:`${w().services}/${t}`},xm=async(e,t)=>{let{valid:r,config:n,error:o}=ee();if(!r||!n){E(new Error(o||"AI configuration is invalid"),{exit:!1});return}let s=km(e.name),i=t.packageManager||x(),a=await Ue(t.description);if(ze(s,n,a),await Ve({servicePath:s,description:a,serviceType:"hono",packageManager:i},n))d.breakLine().success("Service generated successfully!").breakLine().log(J.dim("Next steps:")).log(J.dim(` ${J.cyan("pf dev")} - Start all services`)).log(J.dim(` ${J.cyan(`cd ${s} && bun dev`)} - Start this service only`)).breakLine();else throw new Error("Service generation failed")},ps=L({name:"hono-micro",description:"Create a new Hono microservice with the Crossdelta setup. Use --ai for AI-powered generation.",arguments:[["[name]","Name or path of the service"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["--ai","Use AI to generate service code based on a description"],["-d, --description <description>","Service description for AI generation (requires --ai)"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:'platform new hono-micro my-service --ai -d "Payment processing service"',shouldSkipWorkflow:(e,t)=>!!t.ai,onSkipWorkflow:xm,buildContext:async(e,t)=>{let r=(e.name??"my-hono-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${w().services}/${r}`);let n=$(r),o=t.packageManager??(t.yes&&x()),s=R(),i=t.yes?se():[],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:[me,le,ce,de,dt,ie],actions:[pe,ae,ht,lt,mt,ut],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r,assignedPort:n})=>{d.breakLine().log(J.bold.green("Hono Microservice created successfully!")),at(r),Zo(Cm(e),n??8080);let o=t??x();d.breakLine().log(`To start the project, run:
|
|
558
|
+
${J.bold(`cd ${e} && ${o} run dev`)}`).breakLine().log("Happy shipping with Hono! \u26A1\uFE0F").breakLine()}});import q from"chalk";var Pm=e=>{let t=(e||"my-nest-service").trim();return t.includes("/")||t.startsWith(".")?t:`${w().services}/${t}`},wm=async(e,t)=>{let{valid:r,config:n,error:o}=ee();if(!r||!n){E(new Error(o||"AI configuration is invalid"),{exit:!1});return}let s=Pm(e.name),i=t.packageManager||x(),a=await Ue(t.description);if(ze(s,n,a),await Ve({servicePath:s,description:a,serviceType:"nest",packageManager:i},n))d.breakLine().success("Service generated successfully!").breakLine().log(q.dim("Next steps:")).log(q.dim(` ${q.cyan("pf dev")} - Start all services`)).log(q.dim(` ${q.cyan(`cd ${s} && bun run start:dev`)} - Start this service only`)).breakLine();else throw new Error("Service generation failed")},ms=L({name:"nest-micro",description:"Create a new NestJS microservice with the Crossdelta setup. Use --ai for AI-powered generation.",arguments:[["[name]","Name or path of the service"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["--ai","Use AI to generate service code based on a description"],["-d, --description <description>","Service description for AI generation (requires --ai)"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:'platform new nest-micro my-service --ai -d "User authentication service"',shouldSkipWorkflow:(e,t)=>!!t.ai,onSkipWorkflow:wm,buildContext:async(e,t)=>{let r=(e.name??"my-nest-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${w().services}/${r}`);let n=$(r),o=t.packageManager??(t.yes&&x()),s=t.packageManager==="bun",i=R(),a=t.yes?se():[],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:[me,le,ce,de,dt,ie],actions:[pe,ae,ht,lt,gt,ss,mt,ut],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r})=>{d.breakLine().log(q.bold.green("NestJS Microservice created successfully!")),at(r),d.breakLine().log(`To start the project, run:
|
|
559
|
+
${q.bold(`cd ${e} && ${t} run start:dev`)}`).breakLine().log("Happy coding! \u{1F389}").breakLine()}});import N from"chalk";import{spawnSync as Tm}from"child_process";import{chmodSync as Em,existsSync as kr,mkdirSync as $m,readFileSync as Im,writeFileSync as xr}from"fs";import{dirname as Am,join as Pr}from"path";import{existsSync as Sm}from"fs";import{join as yt}from"path";var bm=()=>typeof import.meta?.url=="string"?D(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Cr=()=>{let e=bm(),t=U();return ne([yt(e,"templates","workspace"),yt(e,"..","..","..","..","templates","workspace"),yt(t,"bin","templates","workspace")],"Workspace templates directory not found.")},ds=()=>{let e=Cr(),t=yt(e,"packages","contracts");if(!Sm(t))throw new Error(`Contracts templates directory not found at: ${t}`);return t},vt=(e,t)=>ar(e,t);var gs=e=>{e.endsWith(".sh")&&Em(e,493)},Rm=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"pnpm-workspace.yaml.hbs",output:"pnpm-workspace.yaml",forPackageManager:"pnpm"},{template:"biome.json.hbs",output:"biome.json"},{template:"turbo.json.hbs",output:"turbo.json"},{template:"bunfig.toml.hbs",output:"bunfig.toml"},{template:"gitignore.hbs",output:".gitignore"},{template:"editorconfig.hbs",output:".editorconfig"},{template:"npmrc.hbs",output:".npmrc"},{template:".vscode/settings.json",output:".vscode/settings.json",isStatic:!0},{template:".vscode/extensions.json",output:".vscode/extensions.json",isStatic:!0},{template:"infra/package.json.hbs",output:"infra/package.json"},{template:"infra/index.ts.hbs",output:"infra/index.ts"},{template:"infra/tsconfig.json.hbs",output:"infra/tsconfig.json"},{template:"infra/Pulumi.yaml.hbs",output:"infra/Pulumi.yaml"},{template:"infra/Pulumi.dev.yaml.hbs",output:"infra/Pulumi.dev.yaml"},{template:"apps/.gitkeep",output:"apps/.gitkeep",isStatic:!0},{template:"services/.gitkeep",output:"services/.gitkeep",isStatic:!0},{template:"packages/.gitkeep",output:"packages/.gitkeep",isStatic:!0},{template:"docs/.gitkeep",output:"docs/.gitkeep",isStatic:!0},{template:"infra/services/.gitkeep",output:"infra/services/.gitkeep",isStatic:!0},{template:".github/README.md",output:".github/README.md",isStatic:!0,isGitHubCI:!0},{template:".github/dependabot.yml",output:".github/dependabot.yml",isStatic:!0,isGitHubCI:!0},{template:".github/workflows/lint-and-tests.yml.hbs",output:".github/workflows/lint-and-tests.yml",isGitHubCI:!0},{template:".github/workflows/build-and-deploy.yml.hbs",output:".github/workflows/build-and-deploy.yml",isGitHubCI:!0},{template:".github/workflows/publish-packages.yml",output:".github/workflows/publish-packages.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/setup-bun-install/action.yml.hbs",output:".github/actions/setup-bun-install/action.yml",isGitHubCI:!0},{template:".github/actions/check-image-tag-exists/action.yml",output:".github/actions/check-image-tag-exists/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-image-tag-exists/index.js",output:".github/actions/check-image-tag-exists/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-path-changes/action.yml",output:".github/actions/check-path-changes/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-path-changes/index.js",output:".github/actions/check-path-changes/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/detect-skipped-services/action.yml",output:".github/actions/detect-skipped-services/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/action.yml",output:".github/actions/generate-scope-matrix/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/index.js",output:".github/actions/generate-scope-matrix/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/prepare-build-context/action.yml",output:".github/actions/prepare-build-context/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/resolve-scope-tags/action.yml",output:".github/actions/resolve-scope-tags/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/resolve-scope-tags/index.js",output:".github/actions/resolve-scope-tags/index.js",isStatic:!0,isGitHubCI:!0}],us={title:"Creating workspace structure",task:async(e,t)=>{if(kr(e.cwd)){t.title="Workspace directory already exists, skipping...";return}let r=Cr(),n=e.includeGitHubCI??!0,o=e.packageManager||"bun",s=c=>{try{let m=Tm(c,["--version"],{encoding:"utf-8",timeout:5e3}).stdout?.trim();if(m&&/^\d+\.\d+/.test(m))return`${c}@${m}`}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=Rm.filter(c=>!(c.isGitHubCI&&!n||c.forPackageManager&&c.forPackageManager!==o));for(let c of a){let l=Pr(e.cwd,c.output),p=Am(l);if(kr(p)||$m(p,{recursive:!0}),c.isStatic){let m=Pr(r,c.template);kr(m)?xr(l,Im(m)):xr(l,""),gs(l)}else{let m=Pr(r,c.template),f=vt(m,i);xr(l,f),gs(l)}}t.title="Workspace structure created"}};import{existsSync as hs,mkdirSync as fs,readFileSync as Nm,writeFileSync as Fm}from"fs";import{join as Ct}from"path";import Mm from"chalk";var Dm=()=>{let e=Ct(process.cwd(),"package.json");if(!hs(e))throw new Error("Root package.json not found. Please run this command from the workspace root.");let r=JSON.parse(Nm(e,"utf-8")).name;if(!r)throw new Error('package.json must have a "name" field');return r.startsWith("@")?r:`@${r}`},jm=()=>{let e=Dm(),{relativePath:t,packagePath:r}=C();if(hs(r))throw new Error(`${t} already exists. Remove it first if you want to regenerate.`);let n=ds(),o={scope:e,workspaceName:e.replace("@","").replace("/","-")};fs(r,{recursive:!0}),fs(Ct(r,"src","events"),{recursive:!0});let s=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"README.md.hbs",output:"README.md"},{template:"src/index.ts",output:"src/index.ts"},{template:"src/stream-policies.ts.hbs",output:"src/stream-policies.ts"},{template:"src/events/index.ts",output:"src/events/index.ts"}];for(let i of s){let a=Ct(n,i.template),c=Ct(r,i.output),l=vt(a,o);Fm(c,l,"utf-8")}},ys={title:"Initializing contracts package",task:(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),jm(),t.title="Contracts package initialized"}catch(n){throw t.title=Mm.red(`Contracts package failed: ${n.message}`),n}finally{process.chdir(r)}}};import Om from"chalk";var vs={title:"Registering shell completion",task:async(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),await Se(),t.title="Shell completion registered"}catch{t.title=Om.dim("Shell completion skipped")}finally{process.chdir(r)}}};var Cs=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?x():void 0),i=t.packageManager==="bun",a=t.githubOwner??(o?"my-org":void 0),c=t.pulumiStack??(o?`${a}/${r}`:void 0),l=t.github===!1?!1:o?!0:void 0,p=!!e.name,m=t.removeDir||o;return{cwd:n,projectName:r,shouldInstallBun:i,packageManager:s,elapsedTime:0,userConfirmed:o,skipInputPrompts:p&&!o,removeDir:m,githubOwner:a,pulumiStackBase:c,includeGitHubCI:l}},prompts:[{enabled:e=>!e.userConfirmed,task:async(e,t)=>{try{let r=h();if(!await v(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=N.yellow("Warning: Creating nested workspace")}catch(r){if(Y(r)&&r.message?.includes("cancelled"))throw r;t.title="No existing workspace detected"}}},me,le,as,cs,ls,ce,de,ie],actions:[pe,ae,us,ys,gt,rs,vs],onComplete:({projectName:e,includeGitHubCI:t})=>{d.breakLine().log(N.bold.green("Workspace created successfully!")),d.breakLine().log(N.bold("Next steps:")).log(` 1. ${N.cyan(`cd ${e}`)}`).log(` 2. ${N.cyan("exec $SHELL")} ${N.dim("(enable tab completion)")}`),t&&d.breakLine().log(N.bold("GitHub Setup:")).log(" Configure these secrets in your GitHub repository:").log(` \u2022 ${N.yellow("PULUMI_ACCESS_TOKEN")} - Pulumi Cloud access token`).log(` \u2022 ${N.yellow("DIGITALOCEAN_TOKEN")} - DigitalOcean API token`).log(` \u2022 ${N.yellow("NPM_TOKEN")} - (optional) NPM token for private packages`),d.breakLine().log(N.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&&d.log(" .github/").log(" \u251C\u2500\u2500 workflows/ # CI/CD workflows").log(" \u2514\u2500\u2500 actions/ # Custom actions"),d.breakLine().log("Happy coding! \u{1F389}").breakLine()}});var $e=[{name:"Hono Microservice",value:"hono-micro",command:ps,supportsAi:!0},{name:"Nest Microservice",value:"nest-micro",command:ms,supportsAi:!0},{name:"Workspace (Infrastructure)",value:"workspace",command:Cs,supportsAi:!1}],ks=()=>{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??"",useAi:!1,aiDescription:"",elapsedTime:0,cwd:process.cwd()}),prompts:[{enabled:t=>!t.projectType,task:async(t,r)=>{let o=await v(r).select({message:"Select Project type",choices:$e});t.projectType=$e.find(s=>s.name===o)?.value||"",r.title=`Using ${H.bold(o)}`}},{enabled:t=>t.projectType!=="workspace"&&t.projectType!=="",task:async(t,r)=>{try{h(),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(`
|
|
560
|
+
`);throw new Error(n)}}},{enabled:t=>t.projectType==="workspace",task:async(t,r)=>{try{let n=h();if(!await v(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=H.yellow("Warning: Creating nested workspace")}catch(n){if(Y(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 v(r).input({message:s,initial:o});t.servicePath=a.trim(),r.title=`Path: ${H.dim(a)}`}},{enabled:t=>!!$e.find(n=>n.value===t.projectType)?.supportsAi&&ee().valid,task:async(t,r)=>{let o=await v(r).toggle({message:"Use AI to generate service code?",initial:!1});t.useAi=o,r.title=o?H.cyan("\u{1F916} AI-powered generation"):"Standard scaffolding"}},{enabled:t=>t.useAi,task:async(t,r)=>{let o=await v(r).input({message:"Describe what this service should do:"});t.aiDescription=o,r.title=`Description: ${H.dim(o.slice(0,50))}${o.length>50?"...":""}`}},{enabled:t=>{if(!t.servicePath)return!1;let r=$(t.servicePath);return!Fe(r)},task:async(t,r)=>{if(!await v(r).toggle({message:H.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}))throw new Error("Project creation was canceled by the user.");t.shouldRemoveDir=!0,r.title=H.yellow("Will overwrite existing directory")}},{title:"Confirm creation",enabled:t=>t.projectType!=="workspace",task:async(t,r)=>{if(!await v(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=>{$e.find(s=>s.value===t.projectType)||e.error(H.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),t.useAi&&(n.ai=!0,n.description=t.aiDescription),await ts(r,t,n,o)}});for(let t of $e)e.addCommand(t.command);return e};import{Command as Gm}from"commander";import{existsSync as xt,readdirSync as xs,unlinkSync as _m}from"fs";import{join as kt}from"path";import Lm from"chokidar";var Wm=e=>{let t=kt(e,"infra","services");if(!xt(t))return[];let r=xs(t).filter(a=>a.endsWith(".ts")&&a!=="index.ts").map(a=>a.replace(".ts","")),n=w(e),o=a=>{let c=kt(e,a);return xt(c)?xs(c).filter(l=>xt(kt(c,l,"package.json"))):[]},s=[...o(n.services),...o(n.apps)],i=r.filter(a=>!s.includes(a));for(let a of i)_m(kt(t,`${a}.ts`));return i},wr=async e=>{let t=Wm(e);t.length>0&&console.log(`\u{1F9F9} Cleaned ${t.length} orphaned infra config(s): ${t.join(", ")}`),await M({cwd:e,quiet:!0}),await he("generate-env",{cwd:e})},Sr=async e=>{await Vo()&&await fr(e)},Ps=e=>{let{eventsPath:t}=C(e);if(!xt(t))return async()=>{};let r=Re(async()=>{console.log(`
|
|
561
|
+
\u{1F4E6} Contracts changed, updating streams...`),await fr(e)},500),n=Lm.watch(`${t}/**/*.ts`,{ignoreInitial:!0,ignored:["**/index.ts","**/*.test.ts","**/*.spec.ts"]});return n.on("add",r).on("change",r),async()=>{await n.close()}};import ws from"chalk";var br=e=>new Promise(t=>setTimeout(t,e)),Ss=e=>process.stdout.write(`${e}
|
|
562
|
+
`),Hm=()=>{process.stdout.write("\x1B[2J\x1B[3J\x1B[H"),process.stdout.isTTY&&process.stdout.write("\x1Bc")},bs=()=>({turboProcess:null,isRestarting:!1,isShuttingDown:!1}),Tr=async(e,t)=>{let r=zr(".env.local",t);r.length>0&&(await Jr(r),await br(50));let{dev:n}=De(t),o=n.filter.flatMap(s=>["--filter",s]);Ss(ws.cyan("\u{1F525} Starting services...")),Ss(ws.dim(` Command: turbo run ${St} --continue${o.length?` ${o.join(" ")}`:""}`)),e.isShuttingDown=!1,e.isRestarting=!1,e.turboProcess=Kr("turbo",["run",St,"--continue","--no-daemon",...o],{cwd:t,envFile:".env.local",onExit:s=>{e.isRestarting||e.isShuttingDown||s===1&&process.exit(T.SUCCESS)}})},Pt=async e=>{let t=e.turboProcess?.pid;if(t){e.isShuttingDown=!0;try{try{process.kill(-t,"SIGTERM")}catch{e.turboProcess?.kill("SIGTERM")}await br(200);try{process.kill(-t,"SIGKILL")}catch{}await br(30)}catch{}e.turboProcess=null,Hm()}};var Ts=new Gm("dev").description("Start development mode with auto-reload").action(async()=>{let e;try{e=h()}catch(a){E(a);return}let t=bs(),r=async()=>{await wr(e),await Sr(e),await Tr(t,e)},o=Re(async()=>{if(!(t.isRestarting||t.isShuttingDown)){t.isRestarting=!0,console.log(`
|
|
560
563
|
\u{1F504} Change detected, restarting...
|
|
561
|
-
`)
|
|
564
|
+
`);try{await Pt(t),await wr(e),await Sr(e),await Tr(t,e)}catch(a){E(a)}finally{t.isRestarting=!1}}},300),s=async()=>{t.isShuttingDown||(console.log(`
|
|
562
565
|
\u{1F6D1} Shutting down...`),await Pt(t),process.exit(T.SUCCESS))};process.removeAllListeners("SIGINT"),process.removeAllListeners("SIGTERM"),process.on("SIGINT",s),process.on("SIGTERM",s);let i;try{await r(),Hr(e,o),i=Ps(e),console.log(`
|
|
563
566
|
\u{1F440} Watching for changes...`),console.log(` Press Ctrl+C twice to exit (first stops Turbo, second triggers cleanup)
|
|
564
|
-
`)}catch(a){await i?.(),await Pt(t),
|
|
567
|
+
`)}catch(a){await i?.(),await Pt(t),E(a)}});import As from"chalk";import{Command as td}from"commander";import{existsSync as Bm,readFileSync as Um,writeFileSync as zm}from"fs";import Vm from"os";import Es from"path";import Er from"chalk";import{Command as Km}from"commander";var{name:Jm,publishConfig:qm}=A,Ym=qm?.registry,Zm=Jm?.split("/")[0],bw=new Km("token:set").description(Er.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)",Zm).option("--registry <registry>","Registry URL",Ym).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)=>$s(e,t.scope||"",t.registry||"",t.local,t.force)).addHelpText("after",()=>`${Er.cyan(`
|
|
565
568
|
Example:`)}
|
|
566
569
|
${Er.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
|
|
567
|
-
`),
|
|
568
|
-
//${n}/:_authToken=${e}`:`//${n}/:_authToken=${e}`},
|
|
570
|
+
`),Xm=e=>e?Es.join(process.cwd(),".npmrc"):Es.join(Vm.homedir(),".npmrc"),Qm=(e,t,r)=>{let n=new URL(r).host;return t?`${t}:registry=https://${n}
|
|
571
|
+
//${n}/:_authToken=${e}`:`//${n}/:_authToken=${e}`},ed=e=>Bm(e)?Um(e,"utf8"):"",$r=(e,t)=>zm(e,t),$s=(e,t,r,n=!1,o=!1)=>{let s=Xm(n),i=Qm(e,t,r),a=new URL(r).host,c=ed(s),l=new RegExp(`//${a}/:_authToken=\\S+`);if(!c){$r(s,`${i}
|
|
569
572
|
`),d.success(`Created new .npmrc and set token for ${a}`);return}if(l.test(c)){if(!o){d.warn(`Token for ${a} already exists in ${s}. Use --force to overwrite.`);return}c=c.replace(l,i),$r(s,c),d.success(`Overwrote existing token for ${a} in ${s}`);return}c+=`
|
|
570
573
|
${i}
|
|
571
|
-
`,$r(s,c),d.success(`Appended token for ${a} to ${s}`)},Is=(e,t)=>$s(e,t.scope||"",t.registry||"",t.local,t.force);var{name:
|
|
574
|
+
`,$r(s,c),d.success(`Appended token for ${a} to ${s}`)},Is=(e,t)=>$s(e,t.scope||"",t.registry||"",t.local,t.force);var{name:rd,publishConfig:nd}=A,od=nd?.registry,sd=rd?.split("/")[0],Ir=new td("token").description("Token management commands");Ir.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)",sd).option("--registry <registry>","Registry URL",od).option("--local","Write token to a local .npmrc in the current directory",!1).option("--force","Force overwrite existing token if already present",!1).action(Is).addHelpText("after",()=>`${As.cyan(`
|
|
572
575
|
Example:`)}
|
|
573
576
|
${As.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
|
|
574
|
-
`);Ir.action(()=>{let e=te({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 Rs=Ir;import Rr from"chalk";import{Command as
|
|
577
|
+
`);Ir.action(()=>{let e=te({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 Rs=Ir;import Rr from"chalk";import{Command as vd}from"commander";var Mw={AI_GENERATION:!0,DEBUG:process.env.PF_DEBUG==="true"};import{confirm as Fs,input as pd,password as md,select as Ms}from"@inquirer/prompts";import k from"chalk";var id=[/embed/i,/whisper/i,/tts/i,/dall-e/i,/davinci/i,/babbage/i,/curie/i,/ada(?!-)/i,/moderation/i,/realtime/i,/audio/i,/transcription/i,/search/i],ad=async(e,t,r=1e4)=>{let n=new AbortController,o=setTimeout(()=>n.abort(),r);try{return await fetch(e,{...t,signal:n.signal})}finally{clearTimeout(o)}},cd=e=>e.replace(/-(\d{8})$/," ($1)").replace(/^claude-/,"Claude ").replace(/^gpt-/,"GPT-").replace(/-/g," ").replace(/(\d)\.(\d)/g,"$1.$2").replace(/\s+/g," ").split(" ").map(t=>/^\d/.test(t)||/^\(\d+\)$/.test(t)?t:t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join(" ").trim(),ld=async(e,t)=>{let r=ve(e),n=await ad(r.modelsApiUrl,{headers:r.buildHeaders(t)});if(!n.ok)throw new Error(`${r.name} API error: ${n.status}`);let o=await n.json(),s=r.parseModelsResponse(o);if(!Array.isArray(s)||s.length===0)throw new Error(`No models returned from ${r.name} API`);let i=s.filter(a=>{let c=r.modelFilters.some(p=>p.test(a.id)),l=id.some(p=>p.test(a.id));return c&&!l}).sort((a,c)=>{let l=typeof a.created=="number"?a.created:new Date(a.created).getTime();return(typeof c.created=="number"?c.created:new Date(c.created).getTime())-l}).map(a=>({name:cd(a.id),value:a.id}));if(i.length===0)throw new Error(`No chat models found from ${r.name} API`);return i};async function Ns(e,t){if(!t)throw new Error("API key is required to fetch available models");return{models:await ld(e,t),fromApi:!0}}function dd(){if(!Ce())return null;try{let e=Le();return console.log(k.dim(`Found existing configuration at ${B}
|
|
575
578
|
`)),e}catch{return console.log(k.yellow(`Found corrupted configuration, starting fresh.
|
|
576
|
-
`)),null}}async function
|
|
579
|
+
`)),null}}async function gd(e,t){return console.log(k.dim(`
|
|
577
580
|
\u{1F4CB} Get your ${e} API key here:`)),console.log(k.cyan(` ${t}
|
|
578
|
-
`)),
|
|
581
|
+
`)),md({message:`Enter your ${e} API key:`,mask:"*",validate:r=>r.trim()?r.length<10?"API key seems too short":!0:"API key cannot be empty"})}async function ud(e,t,r){let n=await Ms({message:"Select model:",choices:e,default:t?.provider===r?t.model:void 0});return await Fs({message:"Enter a custom model ID instead?",default:!1})?pd({message:"Enter custom model ID:",default:n,validate:s=>s.trim()?!0:"Model ID cannot be empty"}):n}function Ds(e){return e.length<=12?"****":`${e.slice(0,4)}...${e.slice(-4)}`}function fd(e,t){console.log(k.green.bold(`
|
|
579
582
|
\u2705 AI configuration saved successfully!
|
|
580
583
|
`)),console.log(k.dim(`Configuration file: ${B}`)),console.log(k.dim("API Key: Stored securely in system keychain")),console.log(k.dim(`Provider: ${e.provider}`)),console.log(k.dim(`Model: ${e.model}`)),console.log(k.dim(`API Key: ${Ds(t)}
|
|
581
584
|
`)),console.log(k.cyan("You can now use AI-powered service generation:")),console.log(k.dim(` pf new hono-micro services/my-service --ai
|
|
582
|
-
`))}async function
|
|
585
|
+
`))}async function hd(e){let t=await _e(e);if(t)return t;let r=ve(e);return process.env[r.defaultApiKeyEnvVar]??null}async function js(){console.log(k.cyan.bold(`
|
|
583
586
|
\u{1F916} AI Configuration Setup
|
|
584
|
-
`));let e=
|
|
585
|
-
\u2713 Found existing API key: ${Ds(o)}`)),await Fs({message:"Use this existing API key?",default:!0})&&(n=o)),n||(n=await
|
|
587
|
+
`));let e=dd();try{let t=await Ms({message:"Select AI provider:",choices:cn(),default:e?.provider??Ft.provider}),r=ve(t),n,o=await hd(t);o&&(console.log(k.green(`
|
|
588
|
+
\u2713 Found existing API key: ${Ds(o)}`)),await Fs({message:"Use this existing API key?",default:!0})&&(n=o)),n||(n=await gd(r.name,r.apiKeyUrl)),console.log(k.dim(`
|
|
586
589
|
Fetching available models...`));let s;try{s=(await Ns(t,n)).models,console.log(k.green(`\u2713 Loaded ${s.length} models from ${r.name} API
|
|
587
590
|
`))}catch(c){console.error(k.red(`
|
|
588
591
|
\u274C Failed to fetch models: ${_r(c)}`)),console.log(k.yellow(`
|
|
589
592
|
Please check your API key and try again.
|
|
590
|
-
`)),process.exit(T.CONFIG_ERROR)}let i=await
|
|
593
|
+
`)),process.exit(T.CONFIG_ERROR)}let i=await ud(s,e,t),a={provider:t,model:i.trim()};ln(a),await pn(t,n),fd(a,n)}catch(t){throw Y(t)&&t.name==="ExitPromptError"&&(console.log(k.yellow(`
|
|
591
594
|
Setup cancelled.
|
|
592
|
-
`)),process.exit(T.CANCELLED)),t}}import{existsSync as
|
|
595
|
+
`)),process.exit(T.CANCELLED)),t}}import{existsSync as Jw,readFileSync as qw}from"fs";import{homedir as Zw}from"os";import{join as Qw}from"path";var Ar=async(e,t=!1)=>{try{return rr(e,t),await Se({verbose:t}),!0}catch{return!1}};var wt=e=>{let t=new vd("setup").description("Configure platform settings");return t.command("completion").description("Install shell autocompletion").option("--verbose","Enable verbose logging").addHelpText("after",`
|
|
593
596
|
Examples:
|
|
594
597
|
$ pf setup completion
|
|
595
598
|
$ pf setup completion --verbose
|
|
@@ -599,6 +602,6 @@ Examples:
|
|
|
599
602
|
`)))}),t.command("ai").description("Configure AI provider and API key for code generation").addHelpText("after",`
|
|
600
603
|
Example:
|
|
601
604
|
$ pf setup ai
|
|
602
|
-
`).action(async()=>{await js()}),t.action(()=>{let r=te({title:"\u2699\uFE0F Platform Setup",commands:[{name:"completion",description:"Install shell autocompletion"},{name:"ai",description:"Configure AI provider"}],footer:'Run "pf setup <command> --help" for more information'});console.log(r)}),t},
|
|
605
|
+
`).action(async()=>{await js()}),t.action(()=>{let r=te({title:"\u2699\uFE0F Platform Setup",commands:[{name:"completion",description:"Install shell autocompletion"},{name:"ai",description:"Configure AI provider"}],footer:'Run "pf setup <command> --help" for more information'});console.log(r)}),t},Cd=wt("pf");import xd from"chalk";import{Command as _s}from"commander";import Os from"chalk";var kd=e=>({debug:()=>{},info:e?()=>{}:t=>console.log(` ${t}`),warn:e?()=>{}:t=>console.log(Os.yellow(` ${t}`)),error:e?()=>{}:t=>console.error(Os.red(` ${t}`))}),Nr=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:kd(s)};sr(a,c)}if(!s&&i?.output){let c=Array.isArray(i.output)?i.output:[i.output];for(let l of c)console.log(l)}return{effects:a,output:i?.output}};var Pd=e=>e.required?`<${e.name}>`:`[${e.name}]`,wd=(e,t)=>{e.argument(Pd(t),t.description)},Sd=(e,t)=>{t.default!==void 0?e.option(t.flags,t.description,t.default):e.option(t.flags,t.description)},bd=(e,t)=>Object.fromEntries(e.args.map((r,n)=>[r.name,t[n]])),Td=e=>e[e.length-2],Ed=(e,t)=>async(...r)=>{try{await Nr({command:e,args:bd(e,r),options:Td(r),context:t})}catch(n){console.error(xd.red(`Error executing ${e.name}:`),n instanceof Error?n.message:n),process.exit(1)}},Ls=(e,t)=>{let r=new _s(e.name).description(e.description);return e.args.forEach(n=>{wd(r,n)}),e.options.forEach(n=>{Sd(r,n)}),r.action(Ed(e,t)),r},Fr=(e,t,r,n)=>{let o=new _s(e).description(t);return r.forEach(s=>{o.addCommand(Ls(s,n))}),o};Ze();process.on("SIGINT",()=>{process.exit(T.CANCELLED)});process.on("unhandledRejection",e=>{throw Lr(e)&&process.exit(T.CANCELLED),e});process.on("uncaughtException",e=>{E(e)});var Ie=new Id,Ws=Object.keys(A.bin||{}),[Dr="pf",Mr]=Ws.length>0?Ws:["pf"],{description:Hs,version:Rd,repository:Gs,homepage:Nd}=A,Bs=Hs?.split(/ —|,|\./)[0]||Hs||"Platform CLI",zs=Gs?.url?`https://${Gs.url.replace(/^(git\+|git@)/,"").replace(/\.git$/,"").replace(":","/")}`:null,Us=zs||Nd,Fd=zs?"GitHub":"README",Md=Us?[Ae.bold(Bs),`
|
|
603
606
|
|
|
604
|
-
`,Ae.cyan("See more at: "),Ae.bold(
|
|
607
|
+
`,Ae.cyan("See more at: "),Ae.bold(Ad(Fd,String(Us)))].join(""):Ae.bold(Bs),Dd=[wt(Dr),ks(),Ts,Rs,tn],jd=async()=>{try{let e=h(),t=De(e);if(!t.plugins?.length)return[];let r=C(e),n=Xe({workspaceRoot:e,availableServices:$t(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=Fr(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[]}},Od=async()=>{let e=await jd(),t=[...Dd,...e];Ie.name(Dr).description(Md).version(Rd||"0.0.1").helpCommand(!1).configureHelp({subcommandTerm:r=>Ae.cyan(r.name())}).addHelpText("after",to),Mr&&Mr!==Dr&&Ie.alias(Mr);for(let r of t)Ie.addCommand(r);Ie.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)}),ro(Ie,$d,t)};Od();
|
package/bin/config-CKQHYOF4.mjs
CHANGED
|
File without changes
|
|
@@ -111,6 +111,9 @@ jobs:
|
|
|
111
111
|
cache-restore-keys: bun-$\{{ runner.os }}-
|
|
112
112
|
npm-token: $\{{ secrets.NPM_TOKEN }}
|
|
113
113
|
|
|
114
|
+
- name: Build workspace packages
|
|
115
|
+
run: bunx turbo run build --filter='./packages/*'
|
|
116
|
+
|
|
114
117
|
- name: Prune
|
|
115
118
|
run: |
|
|
116
119
|
bunx turbo prune --scope=$\{{ matrix.scope.name }} --docker --out-dir out/$\{{ matrix.scope.shortName }}
|
|
@@ -97,15 +97,16 @@ jobs:
|
|
|
97
97
|
runs-on: ubuntu-latest
|
|
98
98
|
steps:
|
|
99
99
|
- uses: actions/checkout@v4
|
|
100
|
-
|
|
101
|
-
- name:
|
|
102
|
-
|
|
100
|
+
|
|
101
|
+
- name: Setup Bun and install dependencies
|
|
102
|
+
uses: ./.github/actions/setup-bun-install
|
|
103
|
+
with:
|
|
104
|
+
enable-cache: 'true'
|
|
105
|
+
cache-key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
|
|
106
|
+
cache-restore-keys: bun-${{ runner.os }}-
|
|
103
107
|
|
|
104
108
|
- name: Build all packages
|
|
105
|
-
run:
|
|
106
|
-
# Turborepo automatically builds in dependency order (see turbo.json)
|
|
107
|
-
# Example order: cloudevents -> infrastructure, telemetry, platform-sdk
|
|
108
|
-
bunx turbo run build --filter='./packages/*'
|
|
109
|
+
run: bunx turbo run build --filter='./packages/*'
|
|
109
110
|
|
|
110
111
|
- name: Upload build artifacts
|
|
111
112
|
uses: actions/upload-artifact@v4
|
|
@@ -134,10 +135,13 @@ jobs:
|
|
|
134
135
|
package: ${{ fromJson(needs.determine-packages.outputs.packages) }}
|
|
135
136
|
steps:
|
|
136
137
|
- uses: actions/checkout@v4
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
|
|
139
|
+
- name: Setup Bun and install dependencies
|
|
140
|
+
uses: ./.github/actions/setup-bun-install
|
|
141
|
+
with:
|
|
142
|
+
enable-cache: 'true'
|
|
143
|
+
cache-key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
|
|
144
|
+
cache-restore-keys: bun-${{ runner.os }}-
|
|
141
145
|
|
|
142
146
|
- name: Download build artifacts
|
|
143
147
|
uses: actions/download-artifact@v4
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
"pulumi": "pulumi"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@crossdelta/cloudevents": "^0.7.
|
|
11
|
-
"@crossdelta/infrastructure": "^0.7.
|
|
10
|
+
"@crossdelta/cloudevents": "^0.7.7",
|
|
11
|
+
"@crossdelta/infrastructure": "^0.7.5",
|
|
12
12
|
"{{scope}}/contracts": "workspace:*",
|
|
13
13
|
"@pulumi/digitalocean": "^4.55.0",
|
|
14
14
|
"@pulumi/kubernetes": "^4.21.0",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"clean": "rm -rf dist"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@crossdelta/cloudevents": "^0.7.
|
|
23
|
-
"@crossdelta/infrastructure": "^0.7.
|
|
22
|
+
"@crossdelta/cloudevents": "^0.7.7",
|
|
23
|
+
"@crossdelta/infrastructure": "^0.7.5",
|
|
24
24
|
"zod": "^4.0.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crossdelta/platform-sdk",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.10",
|
|
4
4
|
"description": "Platform toolkit for event-driven microservices — keeping code and infrastructure in lockstep.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
"@ai-sdk/anthropic": "^2.0.53",
|
|
119
119
|
"@ai-sdk/openai": "^2.0.79",
|
|
120
120
|
"@angular-devkit/core": "^21.0.0",
|
|
121
|
-
"@crossdelta/flowcore": "0.1.
|
|
121
|
+
"@crossdelta/flowcore": "0.1.2",
|
|
122
122
|
"@faker-js/faker": "^9.8.0",
|
|
123
123
|
"@inquirer/prompts": "^7.5.0",
|
|
124
124
|
"@listr2/prompt-adapter-enquirer": "^2.0.15",
|
|
@@ -143,8 +143,8 @@
|
|
|
143
143
|
"zod": "^4.0.0"
|
|
144
144
|
},
|
|
145
145
|
"peerDependencies": {
|
|
146
|
-
"@crossdelta/cloudevents": "0.7.
|
|
147
|
-
"@crossdelta/infrastructure": "0.7.
|
|
146
|
+
"@crossdelta/cloudevents": "0.7.7",
|
|
147
|
+
"@crossdelta/infrastructure": "0.7.5",
|
|
148
148
|
"@nestjs/schematics": "^11.0.5",
|
|
149
149
|
"turbo": "^2.0.0"
|
|
150
150
|
},
|