likec4 1.24.0 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{c as pt,f as Ep,m as mt,g as Ji,a as Dp,b as Ba,T as vp,N as xa,i as $p,n as Xi,C as _p,d as wp,e as Ma,h as qa,t as Ua,p as bp,u as K,l as Ap,w as Cp,j as Sp,k as Rp,o as zt,q as Ha,r as Va,L as gt,s as Op,v as yt,x as Ip,y as Fp,z as Pp,A as dr,B as za,D as Np,E as Sr,F as Qi,G as Ga,H as Tp,Q as Lp}from"../shared/likec4.DNjEPXYD.mjs";import Te,{hrtime as jp,cwd as Zi,exit as Wa,stdout as kp,argv as Bp}from"node:process";import{strictEqual as xp,notStrictEqual as Mp}from"assert";import es,{
2
+ import{c as pt,f as Ep,m as mt,g as Ji,a as Dp,b as Ba,T as vp,N as xa,i as $p,n as Xi,C as _p,d as wp,e as Ma,h as qa,t as Ua,p as bp,u as K,l as Ap,w as Cp,j as Sp,k as Rp,o as zt,q as Ha,r as Va,L as gt,s as Op,v as yt,x as Ip,y as Fp,z as Pp,A as dr,B as za,D as Np,E as Sr,F as Qi,G as Ga,H as Tp,Q as Lp}from"../shared/likec4.DX7xzn9M.mjs";import Te,{hrtime as jp,cwd as Zi,exit as Wa,stdout as kp,argv as Bp}from"node:process";import{strictEqual as xp,notStrictEqual as Mp}from"assert";import es,{
3
3
  resolve as Qe,dirname as ts,normalize as qp,relative as Up,extname as Hp,basename as Vp}from"path";import{statSync as Ka,readdirSync as zp,readFileSync as rs,writeFile as Gp}from"fs";import Ya,{format as Ja,inspect as Wp}from"util";import{fileURLToPath as Kp}from"url";import be,{resolve as De,dirname as Gt,join as Rr,relative as Wt,extname as Or,isAbsolute as ns,basename as on}from"node:path";import ge,{existsSync as Pt,copyFileSync as Xa,readdirSync as Yp,rmSync as is}from"node:fs";import{mkdtemp as an,
4
4
  writeFile as Kt,mkdir as $t,stat as ss,copyFile as Jp,rm as Xp}from"node:fs/promises";import Ir,{tmpdir as un}from"node:os";import{fileURLToPath as Qa}from"node:url";import Za from"@vitejs/plugin-react";import{sortNaturalByFqn as eu,compareNatural as Qp,hasAtLeast as Zp,invariant as os,nonexhaustive as tu,delay as ru}from"@likec4/core";import{build as Fr,createServer as em,preview as tm}from"vite";import{chromium as nu}from"playwright";import rm from"node:net";import{setTimeout as nm}from"node:timers/promises";
5
5
  import{promisify as Me,isDeepStrictEqual as im}from"node:util";import Pr from"node:crypto";import sm from"node:assert";import"tty";import"os";import"crypto";import"net";import"child_process";import"@likec4/core/types";import"events";import"buffer";import"@hpcc-js/wasm-graphviz";import"@likec4/core/compute-view";import"@likec4/core/utils";import"boxen";import"node:child_process";import"node:events";import"node:stream/promises";import"fs/promises";import"@likec4/core/model";const om={right:dm,center:hm},
@@ -243,8 +243,8 @@ r==="directory"&&a?.isDirectory())return o}catch{}i=be.dirname(i)}}function l0({
243
243
  ${e.join(`
244
244
  `)}`),new Error("likec4 app root does not exist");return r}async function Os(){const t=await an(Rr(un(),".likec4-public-"));return await Kt(Rr(t,"likec4-views.js"),`// generated by likec4
245
245
  `),t}const Is=1e4;function Fs(){const t=zu();return{"likec4/icons":De(t,"icons"),"likec4/react":De(t,"react"),"likec4/model":De(t,"dist/model")}}var Ps={},Gu;function Ns(){return Gu||(Gu=1,function(t){t.isInteger=e=>typeof e=="number"?Number.isInteger(e):typeof e=="string"&&e.trim()!==""?Number.isInteger(Number(e)):!1,t.find=(e,r)=>e.nodes.find(n=>n.type===r),t.exceedsLimit=(e,r,n=1,i)=>i===!1||!t.isInteger(e)||!t.isInteger(r)?!1:(Number(r)-Number(e))/Number(n)>=i,t.escapeNode=(e,r=0,n)=>{const i=e.
246
- nodes[r];i&&(n&&i.type===n||i.type==="open"||i.type==="close")&&i.escaped!==!0&&(i.value="\\"+i.value,i.escaped=!0)},t.encloseBrace=e=>e.type!=="brace"||e.commas>>0+e.ranges>>0?!1:(e.invalid=!0,!0),t.isInvalidBrace=e=>e.type!=="brace"?!1:e.invalid===!0||e.dollar?!0:!(e.commas>>0+e.ranges>>0)||e.open!==!0||e.close!==!0?(e.invalid=!0,!0):!1,t.isOpenOrClose=e=>e.type==="open"||e.type==="close"?!0:e.open===!0||e.close===!0,t.reduce=e=>e.reduce((r,n)=>(n.type==="text"&&r.push(n.value),n.type==="range"&&
247
- (n.type="text"),r),[]),t.flatten=(...e)=>{const r=[],n=i=>{for(let s=0;s<i.length;s++){const o=i[s];if(Array.isArray(o)){n(o);continue}o!==void 0&&r.push(o)}return r};return n(e),r}}(Ps)),Ps}var Ts,Wu;function Ls(){if(Wu)return Ts;Wu=1;const t=Ns();return Ts=(e,r={})=>{const n=(i,s={})=>{const o=r.escapeInvalid&&t.isInvalidBrace(s),a=i.invalid===!0&&r.escapeInvalid===!0;let u="";if(i.value)return(o||a)&&t.isOpenOrClose(i)?"\\"+i.value:i.value;if(i.value)return i.value;if(i.nodes)for(const l of i.
246
+ nodes[r];i&&(n&&i.type===n||i.type==="open"||i.type==="close")&&i.escaped!==!0&&(i.value="\\"+i.value,i.escaped=!0)},t.encloseBrace=e=>e.type!=="brace"?!1:e.commas>>0+e.ranges>>0===0?(e.invalid=!0,!0):!1,t.isInvalidBrace=e=>e.type!=="brace"?!1:e.invalid===!0||e.dollar?!0:e.commas>>0+e.ranges>>0===0||e.open!==!0||e.close!==!0?(e.invalid=!0,!0):!1,t.isOpenOrClose=e=>e.type==="open"||e.type==="close"?!0:e.open===!0||e.close===!0,t.reduce=e=>e.reduce((r,n)=>(n.type==="text"&&r.push(n.value),n.type===
247
+ "range"&&(n.type="text"),r),[]),t.flatten=(...e)=>{const r=[],n=i=>{for(let s=0;s<i.length;s++){const o=i[s];if(Array.isArray(o)){n(o);continue}o!==void 0&&r.push(o)}return r};return n(e),r}}(Ps)),Ps}var Ts,Wu;function Ls(){if(Wu)return Ts;Wu=1;const t=Ns();return Ts=(e,r={})=>{const n=(i,s={})=>{const o=r.escapeInvalid&&t.isInvalidBrace(s),a=i.invalid===!0&&r.escapeInvalid===!0;let u="";if(i.value)return(o||a)&&t.isOpenOrClose(i)?"\\"+i.value:i.value;if(i.value)return i.value;if(i.nodes)for(const l of i.
248
248
  nodes)u+=n(l);return u};return n(e)},Ts}var js,Ku;function h0(){return Ku||(Ku=1,js=function(t){return typeof t=="number"?t-t===0:typeof t=="string"&&t.trim()!==""?Number.isFinite?Number.isFinite(+t):isFinite(+t):!1}),js}var ks,Yu;function p0(){if(Yu)return ks;Yu=1;const t=h0(),e=(f,g,p)=>{if(t(f)===!1)throw new TypeError("toRegexRange: expected the first argument to be a number");if(g===void 0||f===g)return String(f);if(t(g)===!1)throw new TypeError("toRegexRange: expected the second argument t\
249
249
  o be a number.");let m={relaxZeros:!0,...p};typeof m.strictZeros=="boolean"&&(m.relaxZeros=m.strictZeros===!1);let D=String(m.relaxZeros),v=String(m.shorthand),_=String(m.capture),b=String(m.wrap),I=f+":"+g+"="+D+v+_+b;if(e.cache.hasOwnProperty(I))return e.cache[I].result;let U=Math.min(f,g),G=Math.max(f,g);if(Math.abs(U-G)===1){let M=f+"|"+g;return m.capture?`(${M})`:m.wrap===!1?M:`(?:${M})`}let L=$(f)||$(g),B={min:f,max:g,a:U,b:G},N=[],j=[];if(L&&(B.isPadded=L,B.maxLen=String(B.max).length),U<
250
250
  0){let M=G<0?Math.abs(G):1;j=s(M,Math.abs(U),B,m),U=B.a=0}return G>=0&&(N=s(U,G,B,m)),B.negatives=j,B.positives=N,B.result=r(j,N),m.capture===!0?B.result=`(${B.result})`:m.wrap!==!1&&N.length+j.length>1&&(B.result=`(?:${B.result})`),e.cache[I]=B,B.result};function r(f,g,p){let m=o(f,g,"-",!1)||[],D=o(g,f,"",!1)||[],v=o(f,g,"-?",!0)||[];return m.concat(v).concat(D).join("|")}function n(f,g){let p=1,m=1,D=c(f,p),v=new Set([g]);for(;f<=D&&D<=g;)v.add(D),p+=1,D=c(f,p);for(D=d(g+1,m)-1;f<D&&D<=g;)v.add(
@@ -724,10 +724,10 @@ try{await Oc({port:t.port,host:r})}catch(n){if(!["EADDRNOTAVAIL","EINVAL"].inclu
724
724
  responding to the port you want excluded.");if(!Number.isSafeInteger(s))throw new TypeError(`Number ${s} in the exclude option is not a safe integer and can't be used`)}r=new Set(i)}Jr===void 0&&(Jr=setTimeout(()=>{Jr=void 0,Er.old=Er.young,Er.young=new Set},Ug),Jr.unref&&Jr.unref());const n=Hg();for(const i of Vg(e))try{if(r.has(i))continue;let s=await Ic({...t,port:i},n);for(;Er.old.has(s)||Er.young.has(s);){if(i!==0)throw new Rc(i);s=await Ic({...t,port:i},n)}return Er.young.add(s),s}catch(s){
725
725
  if(!["EADDRINUSE","EACCES"].includes(s.code)&&!(s instanceof Rc))throw s}throw new Error("No available ports found")}function Pn(t,e){if(!Number.isInteger(t)||!Number.isInteger(e))throw new TypeError("`from` and `to` must be integer numbers");if(t<In||t>Fn)throw new RangeError(`'from' must be between ${In} and ${Fn}`);if(e<In||e>Fn)throw new RangeError(`'to' must be between ${In} and ${Fn}`);if(t>e)throw new RangeError("`to` must be greater than or equal to `from`");return function*(n,i){for(let s=n;s<=
726
726
  i;s++)yield s}(t,e)}async function Fc({buildWebcomponent:t=!0,hmr:e=!0,webcomponentPrefix:r="likec4",languageServices:n,likec4AssetsDir:i,openBrowser:s,listen:o,...a}){i??=await an(Rr(un(),".likec4-assets-"));const{isDev:u,...l}=await uo({...a,languageServices:n,likec4AssetsDir:i,webcomponentPrefix:r}),c=await lo({port:[5173,...Pn(61e3,61010),...Pn(62002,62010)]}),d=await lo({port:Pn(24678,24690)}),h=await Os();let E;if(t){const y=await co({webcomponentPrefix:r,languageServices:n,outDir:h,base:l.
727
- base});E=Fr({...y,logLevel:"warn"}).catch(f=>(mt.warn("webcomponent build failed",{err:f}),mt.warn("Ignoring error and continuing"),Promise.resolve()))}const $=await em({...l,define:Object.assign({},l.define,e&&{"process.env.NODE_ENV":'"development"'}),mode:e?"development":l.mode,publicDir:h,server:{host:o??"127.0.0.1",port:c,hmr:e&&{overlay:!0,port:d},fs:{strict:!1},open:s??!u}});return await $.listen(),E&&await E,$}async function zg({browserContext:t,views:e,output:r,logger:n,timeout:i,maxAttempts:s,
728
- outputType:o,theme:a}){let u;const l=e.map(h=>({view:h,attempt:1})),c=[];let d;for(;d=l.shift();){const{view:h,attempt:E}=d,$=`/export/${encodeURIComponent(h.id)}`;try{if(E>1){u&&(u.close({runBeforeUnload:!0}).catch(m=>n.error(`failed to close page: ${m}`)),u=void 0);const p=Va(E*200,{min:200,max:1e3});n.info(K.cyan($)+K.dim(` attempt ${E} of ${s} after ${p}ms`)),await nm(p)}else h.hasLayoutDrift&&n.warn(K.yellow("Drift detected, manual layout can not be applied, view may be invalid: ")+K.red(h.
729
- id)),n.info(K.cyan($));u??=await t.newPage(),await u.setViewportSize({width:h.bounds.width+20*2,height:h.bounds.height+20*2}),await u.goto($+`?padding=20&theme=${a}`);const y=u.getByRole("presentation");await y.waitFor(),h.nodes.some(p=>qa(p.icon)&&p.icon.toLowerCase().startsWith("http"))&&await Gg(u,i);let f=".";o==="relative"&&(f=h.relativePath??".",f.includes("/")?f=f.slice(0,f.lastIndexOf("/")):f=".");const g=De(r,f,`${h.id}.png`);await y.screenshot({path:g,omitBackground:!0}),c.push({view:h,
730
- path:g})}catch(y){u?.close({runBeforeUnload:!0}).catch(f=>n.error(`failed to close page: ${f}`)),n.error(K.red("failed "+$+`
727
+ base});E=Fr({...y,logLevel:"warn"}).catch(f=>(mt.warn("webcomponent build failed",{err:f}),mt.warn("Ignoring error and continuing"),Promise.resolve()))}const $=await em({...l,define:Object.assign({},l.define,e&&{"process.env.NODE_ENV":'"development"'}),mode:e?"development":l.mode,publicDir:h,server:{host:o??"127.0.0.1",allowedHosts:!0,port:c,hmr:e&&{overlay:!0,port:d},fs:{strict:!1},open:s??!u}});return await $.listen(),E&&await E,$}async function zg({browserContext:t,views:e,output:r,logger:n,timeout:i,
728
+ maxAttempts:s,outputType:o,theme:a}){let u;const l=e.map(h=>({view:h,attempt:1})),c=[];let d;for(;d=l.shift();){const{view:h,attempt:E}=d,$=`/export/${encodeURIComponent(h.id)}`;try{if(E>1){u&&(u.close({runBeforeUnload:!0}).catch(m=>n.error(`failed to close page: ${m}`)),u=void 0);const p=Va(E*200,{min:200,max:1e3});n.info(K.cyan($)+K.dim(` attempt ${E} of ${s} after ${p}ms`)),await nm(p)}else h.hasLayoutDrift&&n.warn(K.yellow("Drift detected, manual layout can not be applied, view may be invali\
729
+ d: ")+K.red(h.id)),n.info(K.cyan($));u??=await t.newPage(),await u.setViewportSize({width:h.bounds.width+20*2,height:h.bounds.height+20*2}),await u.goto($+`?padding=20&theme=${a}`);const y=u.getByRole("presentation");await y.waitFor(),h.nodes.some(p=>qa(p.icon)&&p.icon.toLowerCase().startsWith("http"))&&await Gg(u,i);let f=".";o==="relative"&&(f=h.relativePath??".",f.includes("/")?f=f.slice(0,f.lastIndexOf("/")):f=".");const g=De(r,f,`${h.id}.png`);await y.screenshot({path:g,omitBackground:!0}),
730
+ c.push({view:h,path:g})}catch(y){u?.close({runBeforeUnload:!0}).catch(f=>n.error(`failed to close page: ${f}`)),n.error(K.red("failed "+$+`
731
731
  `+y)),E<s&&(l.push({view:h,attempt:E+1}),n.info(K.dim(`retry ${$}`))),u=void 0}}return c}async function Gg(t,e){let r=await t.locator("//img").all();if(!r.length)return;const n=r.map(i=>i.evaluate(s=>s.complete||new Promise((o,a)=>{s.onload=o,s.onerror=a}),{timeout:Math.max(3e4,e)}));await Promise.allSettled(n)}async function Pc({logger:t,serverUrl:e,theme:r="light",timeoutMs:n=15e3,views:i,output:s,outputType:o="relative",maxAttempts:a=3}){t.info(`${K.cyan("export output")} ${K.dim(s)}`),t.info(
732
732
  `${K.cyan("from server")} ${K.dim(e)}`);const u=nu.executablePath();t.info(K.cyan("Start chromium")),t.info(K.dim(u));const l=await nu.launch();t.info(K.cyan("Color scheme: ")+r);const c=await l.newContext({deviceScaleFactor:2,colorScheme:r,baseURL:e,ignoreHTTPSErrors:!0,reducedMotion:"reduce",isMobile:!1});c.setDefaultNavigationTimeout(n),c.setDefaultTimeout(n);try{return await zg({browserContext:c,views:i,output:s,outputType:o,logger:t,maxAttempts:a,timeout:n,theme:r})}finally{t.info(K.cyan("c\
733
733
  lose chromium")),await c.close(),await l.close()}}async function Nc({path:t,useDotBin:e,theme:r="light",output:n,outputType:i,serverUrl:s,ignore:o=!1,timeoutMs:a=1e4,maxAttempts:u=3}){const l=pt("c4:export"),c=jp(),d=await gt.fromWorkspace(t,{logger:"vite",graphviz:e?"binary":"wasm"});n??=d.workspace;const h=await d.diagrams();if(!Zp(h,1))throw l.warn("no views found"),new Error("no views found");let E;if(!s&&(l.info(K.cyan("start preview server")),E=await Fc({languageServices:d,buildWebcomponent:!1,
@@ -1131,14 +1131,14 @@ E"],["DRONE","DRONE_BUILD_EVENT"],["DSARI"],["GITHUB_ACTIONS"],["GITLAB","GITLAB
1131
1131
  L_ENV",{ci:!1}],["APPCENTER","APPCENTER_BUILD_ID"],["CODESANDBOX","CODESANDBOX_SSE",{ci:!1}],["STACKBLITZ"],["STORMKIT"],["CLEAVR"],["ZEABUR"],["CODESPHERE","CODESPHERE_APP_ID",{ci:!0}],["RAILWAY","RAILWAY_PROJECT_ID"],["RAILWAY","RAILWAY_SERVICE_ID"],["DENO-DEPLOY","DENO_DEPLOYMENT_ID"],["FIREBASE_APP_HOSTING","FIREBASE_APP_HOSTING",{ci:!0}]];function av(){if(globalThis.process?.env)for(const t of ov){const e=t[1]||t[0];if(globalThis.process?.env[e])return{name:t[0].toLowerCase(),...t[2]}}return globalThis.
1132
1132
  process?.env?.SHELL==="/bin/jsh"&&globalThis.process?.versions?.webcontainer?{name:"stackblitz",ci:!1}:{name:"",ci:!1}}const dp=av();dp.name;function fr(t){return t?t!=="false":!1}const uv=globalThis.process?.platform||"",hp=fr(Vt.CI)||dp.ci!==!1,pp=fr(globalThis.process?.stdout&&globalThis.process?.stdout.isTTY);fr(Vt.DEBUG);const cv=fp==="test"||fr(Vt.TEST),lv=fr(Vt.MINIMAL)||hp||cv||!pp,fv=/^win/i.test(uv);!fr(Vt.NO_COLOR)&&(fr(Vt.FORCE_COLOR)||(pp||fv)&&Vt.TERM);const dv=(globalThis.process?.
1133
1133
  versions?.node||"").replace(/^v/,"")||null;Number(dv?.split(".")[0]);const hv=globalThis.process||Object.create(null),mp={versions:{}};new Proxy(hv,{get(t,e){if(e==="env")return Vt;if(e in t)return t[e];if(e in mp)return mp[e]}});const pv=globalThis.process?.release?.name==="node",mv=!!globalThis.Bun||!!globalThis.process?.versions?.bun,gv=!!globalThis.Deno,yv=!!globalThis.fastly,Ev=!!globalThis.Netlify,Dv=!!globalThis.EdgeRuntime,vv=globalThis.navigator?.userAgent==="Cloudflare-Workers",$v=[[Ev,
1134
- "netlify"],[Dv,"edge-light"],[vv,"workerd"],[yv,"fastly"],[gv,"deno"],[mv,"bun"],[pv,"node"]];function _v(){const t=$v.find(e=>e[0]);if(t)return{name:t[1]}}const wv=_v();wv?.name;const La=new HD({projectName:Ip,serialize:t=>Ct.stringify(t,null,2),deserialize:t=>Ct.parse(t)}),bv=1e3*60*60*24,gp="check-update";function Av(){if(lv||fp===gp)return;const t=La.get("lastUpdateCheck"),e=La.get("latestVersion");(Fp(e)||Xi(t)||t+bv<Date.now())&&Pp("likec4",["check-update"],{stdio:"ignore",preferLocal:!0,detached:!0,
1135
- env:{NODE_ENV:gp}}).catch(()=>{}),e&&Oa.gt(e,dr)&&zt(["Update available: ",K.dim(dr),K.reset(" \u2192 "),K.green(e)].join(""))}async function Cv(){try{const t=await Sv();os(t,"No version found in latest npm"),La.set({lastUpdateCheck:Date.now(),latestVersion:t}),Oa.gt(t,dr)?zt(["Update available: ",K.dim(dr),K.reset(" \u2192 "),K.green(t)].join("")):zt(K.dim("Up to date: ")+" "+K.green(dr))}catch(t){za.error(Np(t))}}async function Sv(){return(await sv("https://registry.npmjs.org/likec4/latest",{headers:{
1136
- accept:"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*"},keepalive:!0}).json()).version}async function Rv(t,e,r){const n=".ts";e=e??De(t.workspace,"likec4.generated"+n),Or(e)!==n&&(e=e+n),await $t(Gt(e),{recursive:!0});const i=await t.diagrams(),s=Ag([...i]);await Kt(e,s),r.info(`${K.dim("generated")} ${Wt(process.cwd(),e)}`)}async function Ov(t,e,r){await $t(e,{recursive:!0}),r.info(`${K.dim("format")} ${K.green("dot")}`),r.info(`${K.dim("outdir")} ${e}`);const n=new Set,
1137
- i=await t.viewsService.computedViews();let s=0;for(const o of i)try{const a=await t.viewsService.layouter.dot(o),u=o.relativePath??"";u!==""&&!n.has(u)&&(await $t(De(e,u),{recursive:!0}),n.add(u));const l=De(e,u,o.id+".dot");await Kt(l,a),r.info(`${K.dim("generated")} ${Wt(process.cwd(),l)}`),s++}catch(a){za.error(`error while generating ${o.id}`,{error:a})}s>0&&r.info(`${K.dim("total")} ${s} files`)}async function Iv(t,e,r,n){await $t(r,{recursive:!0}),n.info(`${K.dim("format")} ${K.green(e)}`),
1138
- n.info(`${K.dim("outdir")} ${r}`);let i,s;switch(e){case"d2":i=".d2",s=_c;break;case"mermaid":i=".mmd",s=wc;break;default:tu(e)}const o=new Set,a=await t.diagrams();let u=0;for(const l of a)try{let c=l.relativePath??".";c.includes("/")?c=c.slice(0,c.lastIndexOf("/")):c=".",c!==""&&!o.has(c)&&(await $t(De(r,c),{recursive:!0}),o.add(c));const d=De(r,c,l.id+i),h=s(l);await Kt(d,h),n.info(`${K.dim("generated")} ${Wt(process.cwd(),d)}`),u++}catch(c){n.error(`error while generating ${l.id}`,{error:c})}
1139
- u>0&&n.info(`${K.dim("total")} ${u} files`)}async function Ki({path:t,useDotBin:e,...r}){const n=pt("c4:codegen"),i=Sr(n),s=await gt.fromWorkspace(t,{logger:"vite",graphviz:e?"binary":"wasm"});if((await s.viewsService.computedViews()).length===0)throw n.warn("no views found"),process.exitCode=1,new Error("no views found");switch(r.format){case"views":{await Rv(s,r.outfile,n);break}case"dot":{await Ov(s,r.outdir??t,n);break}case"d2":case"mermaid":{await Iv(s,r.format,r.outdir??t,n);break}default:
1140
- tu(r)}i.stopAndLog()}async function Fv({path:t,useDotBin:e,outfile:r}){const n=pt("c4:codegen"),i=Sr(n),s=await gt.fromWorkspace(t,{logger:"vite",graphviz:e?"binary":"wasm"});n.info(`${K.dim("format")} ${K.green("model")}`);const o=await s.layoutedModel();for(const d of o.views())d.$view.hasLayoutDrift&&n.warn(K.yellow("drift detected, manual layout can not be applied, view:")+" "+K.red(d.id));let a=De(s.workspace,"likec4-model.ts");if(r&&(a=ns(r)?r:De(r),Pt(r)&&(await ss(r)).isDirectory()))throw new Error(
1141
- `output file is a directory: ${r}`);const u=on(a);n.info(`${K.dim("filename")} ${u}`);const l=Or(u).toLocaleLowerCase();if(![".ts",".mts",".cts"].includes(l))throw n.error(`output file ${r} has extension "${l}"`),new Error(`output file ${r} must be a .ts, .mts or .cts file`);const c=Gt(a);n.info(`${K.dim("outdir")} ${c}`),await $t(c,{recursive:!0}),await Kt(a,wg(o),{encoding:"utf-8"}),zt(Qi(`
1134
+ "netlify"],[Dv,"edge-light"],[vv,"workerd"],[yv,"fastly"],[gv,"deno"],[mv,"bun"],[pv,"node"]];function _v(){const t=$v.find(e=>e[0]);if(t)return{name:t[1]}}const wv=_v();wv?.name;const La=new HD({projectName:Ip,serialize:t=>Ct.stringify(t,null,2),deserialize:t=>Ct.parse(t)}),bv=1e3*60*60*24,gp="check-update";function Av(){if(lv||fp===gp)return;const t=La.get("lastUpdateCheck"),e=La.get("latestVersion");if(Fp(e)||Xi(t)||t+bv<Date.now())try{Pp("likec4",["check-update"],{stdio:"ignore",preferLocal:!0,
1135
+ detached:!0,env:{NODE_ENV:gp}}).catch(()=>{})}catch{}e&&Oa.gt(e,dr)&&zt(["Update available: ",K.dim(dr),K.reset(" \u2192 "),K.green(e)].join(""))}async function Cv(){try{const t=await Sv();os(t,"No version found in latest npm"),La.set({lastUpdateCheck:Date.now(),latestVersion:t}),Oa.gt(t,dr)?zt(["Update available: ",K.dim(dr),K.reset(" \u2192 "),K.green(t)].join("")):zt(K.dim("Up to date: ")+" "+K.green(dr))}catch(t){za.error(Np(t))}}async function Sv(){return(await sv("https://registry.npmjs.or\
1136
+ g/likec4/latest",{headers:{accept:"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*"},keepalive:!0}).json()).version}async function Rv(t,e,r){const n=".ts";e=e??De(t.workspace,"likec4.generated"+n),Or(e)!==n&&(e=e+n),await $t(Gt(e),{recursive:!0});const i=await t.diagrams(),s=Ag([...i]);await Kt(e,s),r.info(`${K.dim("generated")} ${Wt(process.cwd(),e)}`)}async function Ov(t,e,r){await $t(e,{recursive:!0}),r.info(`${K.dim("format")} ${K.green("dot")}`),r.info(`${K.dim("out\
1137
+ dir")} ${e}`);const n=new Set,i=await t.viewsService.computedViews();let s=0;for(const o of i)try{const a=await t.viewsService.layouter.dot(o),u=o.relativePath??"";u!==""&&!n.has(u)&&(await $t(De(e,u),{recursive:!0}),n.add(u));const l=De(e,u,o.id+".dot");await Kt(l,a),r.info(`${K.dim("generated")} ${Wt(process.cwd(),l)}`),s++}catch(a){za.error(`error while generating ${o.id}`,{error:a})}s>0&&r.info(`${K.dim("total")} ${s} files`)}async function Iv(t,e,r,n){await $t(r,{recursive:!0}),n.info(`${K.
1138
+ dim("format")} ${K.green(e)}`),n.info(`${K.dim("outdir")} ${r}`);let i,s;switch(e){case"d2":i=".d2",s=_c;break;case"mermaid":i=".mmd",s=wc;break;default:tu(e)}const o=new Set,a=await t.diagrams();let u=0;for(const l of a)try{let c=l.relativePath??".";c.includes("/")?c=c.slice(0,c.lastIndexOf("/")):c=".",c!==""&&!o.has(c)&&(await $t(De(r,c),{recursive:!0}),o.add(c));const d=De(r,c,l.id+i),h=s(l);await Kt(d,h),n.info(`${K.dim("generated")} ${Wt(process.cwd(),d)}`),u++}catch(c){n.error(`error while\
1139
+ generating ${l.id}`,{error:c})}u>0&&n.info(`${K.dim("total")} ${u} files`)}async function Ki({path:t,useDotBin:e,...r}){const n=pt("c4:codegen"),i=Sr(n),s=await gt.fromWorkspace(t,{logger:"vite",graphviz:e?"binary":"wasm"});if((await s.viewsService.computedViews()).length===0)throw n.warn("no views found"),process.exitCode=1,new Error("no views found");switch(r.format){case"views":{await Rv(s,r.outfile,n);break}case"dot":{await Ov(s,r.outdir??t,n);break}case"d2":case"mermaid":{await Iv(s,r.format,
1140
+ r.outdir??t,n);break}default:tu(r)}i.stopAndLog()}async function Fv({path:t,useDotBin:e,outfile:r}){const n=pt("c4:codegen"),i=Sr(n),s=await gt.fromWorkspace(t,{logger:"vite",graphviz:e?"binary":"wasm"});n.info(`${K.dim("format")} ${K.green("model")}`);const o=await s.layoutedModel();for(const d of o.views())d.$view.hasLayoutDrift&&n.warn(K.yellow("drift detected, manual layout can not be applied, view:")+" "+K.red(d.id));let a=De(s.workspace,"likec4-model.ts");if(r&&(a=ns(r)?r:De(r),Pt(r)&&(await ss(
1141
+ r)).isDirectory()))throw new Error(`output file is a directory: ${r}`);const u=on(a);n.info(`${K.dim("filename")} ${u}`);const l=Or(u).toLocaleLowerCase();if(![".ts",".mts",".cts"].includes(l))throw n.error(`output file ${r} has extension "${l}"`),new Error(`output file ${r} must be a .ts, .mts or .cts file`);const c=Gt(a);n.info(`${K.dim("outdir")} ${c}`),await $t(c,{recursive:!0}),await Kt(a,wg(o),{encoding:"utf-8"}),zt(Qi(`
1142
1142
  ${K.dim("Source with LikeC4Model generated:")}
1143
1143
  ${Wt(Zi(),a)}
1144
1144
 
@@ -1189,13 +1189,13 @@ n",normalize:!0,coerce:De}).option("use-dot",at).epilog(`${K.bold("Examples:")}
1189
1189
 
1190
1190
  ${K.green("$0 export json -o ./generated/likec4.json src/likec4 ")}
1191
1191
  ${K.gray("Search for likec4 files in src/likec4 and output JSON to generated/likec4.json")}
1192
- `),handler:async e=>{await jv({path:e.path,useDotBin:e.useDotBin,outfile:e.outfile})}}).updateStrings({"Commands:":K.bold("Formats:")}),handler:()=>{}};async function Bv(t){const{isDev:e,...r}=await uo({...t,likec4AssetsDir:"",webcomponentPrefix:void 0}),n=await lo({port:Pn(62001,62010)}),i=t?.open??!1;return await tm({...r,mode:"production",preview:{host:t.listen??"127.0.0.1",port:n,open:i}})}async function xv({path:t,output:e,base:r,listen:n}){const i=await gt.fromWorkspace(t,{logger:"vite"}),
1193
- s=await Bv({base:r,languageServices:i,outputDir:e,open:!0,listen:n});Sc(s)}const Mv={command:"preview [path]",describe:"Start local server to preview production build",builder:t=>t.positional("path",{type:"string",desc:`Directory with LikeC4 source files
1192
+ `),handler:async e=>{await jv({path:e.path,useDotBin:e.useDotBin,outfile:e.outfile})}}).updateStrings({"Commands:":K.bold("Formats:")}),handler:()=>{}};async function Bv(t){const{isDev:e,...r}=await uo({...t,likec4AssetsDir:"",webcomponentPrefix:void 0}),n=await lo({port:Pn(62001,62010)}),i=t?.open??!1;return await tm({...r,mode:"production",preview:{host:t.listen??"127.0.0.1",allowedHosts:!0,port:n,open:i}})}async function xv({path:t,output:e,base:r,listen:n}){const i=await gt.fromWorkspace(t,{
1193
+ logger:"vite"}),s=await Bv({base:r,languageServices:i,outputDir:e,open:!0,listen:n});Sc(s)}const Mv={command:"preview [path]",describe:"Start local server to preview production build",builder:t=>t.positional("path",{type:"string",desc:`Directory with LikeC4 source files
1194
1194
  if not specified search in current directory`,normalize:!0}).options({output:{alias:"o",type:"string",desc:"output directory from production build",normalize:!0},base:{type:"string",desc:"base url the app is being served from"},listen:{alias:"l",type:"string",desc:"ip address of the network interface to listen on"}}).coerce(["path","output"],Qe).default("path",Qe("."),".").default("listen","127.0.0.1","localhost"),async handler(t){await xv(t)}};async function qv({path:t,useDotBin:e,webcomponentPrefix:r,
1195
1195
  useHashHistory:n,useOverview:i=!1,base:s,listen:o}){const a=await gt.fromWorkspace(t,{logger:"vite",graphviz:e?"binary":"wasm"}),u=await an(Rr(un(),".likec4-assets-"));process.env.NODE_ENV="development";const l=await Fc({buildWebcomponent:!0,hmr:!0,base:s,webcomponentPrefix:r,languageServices:a,useHashHistory:n,useOverviewGraph:i,likec4AssetsDir:u,listen:o});if(l.config.logger.clearScreen("info"),Sc(l),!i)return;const c=await a.diagrams();if(Ga(c,1)){const d=pt("c4:export"),h=Cc(l);if(!h){d.error(
1196
1196
  "no preview server url");return}d.info(K.cyan("wait 5sec before generating previews")),await ru(5e3);try{await Pc({serverUrl:h,logger:d,views:c,theme:"light",output:u,outputType:"flat"}),await ru(1e3),d.info(K.yellow("Note: changes in sources do not trigger preview updates, restart is required"))}catch(E){d.error(K.red("Failed to generate previews")),d.error(E)}}else l.config.logger.warn("no views found, no previews generated")}const Uv={command:"start [path]",aliases:["serve","dev"],describe:"S\
1197
1197
  tart local dev server to preview LikeC4 views",builder:t=>t.positional("path",Vr).option("base",Uu).option("webcomponent-prefix",As).option("use-hash-history",qu).option("use-overview",Hu).option("use-dot",at).option("listen",u0),handler:async t=>{await qv({path:t.path,useDotBin:t["use-dot"],base:t.base,useOverview:t["use-overview"]??!1,webcomponentPrefix:t["webcomponent-prefix"],useHashHistory:t["use-hash-history"],listen:t.listen})}};async function Hv({path:t,ignoreLayout:e}){const r=await gt.
1198
1198
  fromWorkspace(t,{logger:"vite"}),n=pt("c4:views");let i=!0;return i=await s(r)&&i,i=(e||await o(r,n))&&i,i?0:Wa(1);function s(a){return a.getErrors().length===0}async function o(a,u){const l=await a.diagrams();let c=!1;for(const d of l)d.hasLayoutDrift===!0&&(c=!0,u.error(K.red(`Layout drift detected on view '${d.id}' at ${De(t,d.relativePath??".")}`)));return!c}}const Vv={command:"validate [path]",aliases:[],describe:"Validate model syntax and manual layout",builder:t=>t.positional("path",Vr).option(
1199
- "ignore-layout",{boolean:!0,default:!1,description:"do not validate layout of views"}),handler:async t=>{await Hv({path:t.path,ignoreLayout:t["ignore-layout"]})}};async function zv(){return await Tp({sinks:{console:Lp()},loggers:[{category:"likec4",sinks:["console"],lowestLevel:"info"}]}),Av(),await o0(Am(Bp)).scriptName("likec4").usage("Usage: $0 <command>").command(Uv).command(Kg).command(Lv).command(kv).command(Mv).command(Vv).command({command:"check-update",describe:"Check for updates",handler:async()=>{
1200
- await Cv()}}).help("help").version(dr).alias("v","version").alias("h","help").demandCommand(1,"Please run with valid command").strict().recommendCommands().showHelpOnFail(!0,"Something is wrong, run with --help").updateStrings({"Options:":K.bold("Options:"),"Positionals:":K.bold("Arguments:"),"Commands:":K.bold("Commands:"),"Examples:":K.bold("Examples:")}).wrap(Va(kp.columns-20,{min:80,max:120})).parseAsync()}zv().catch(()=>{Wa(1)}),process.on("unhandledRejection",t=>{console.error("Unhandled r\
1201
- ejection",t)});
1199
+ "ignore-layout",{alias:["skip-layout"],boolean:!0,default:!1,description:"do not validate layout of views"}),handler:async t=>{await Hv({path:t.path,ignoreLayout:t["ignore-layout"]})}};async function zv(){return await Tp({sinks:{console:Lp()},loggers:[{category:"likec4",sinks:["console"],lowestLevel:"info"}]}),Av(),await o0(Am(Bp)).scriptName("likec4").usage("Usage: $0 <command>").command(Uv).command(Kg).command(Lv).command(kv).command(Mv).command(Vv).command({command:"check-update",describe:"Ch\
1200
+ eck for updates",handler:async()=>{await Cv()}}).help("help").version(dr).alias("v","version").alias("h","help").demandCommand(1,"Please run with valid command").strict().recommendCommands().showHelpOnFail(!0,"Something is wrong, run with --help").updateStrings({"Options:":K.bold("Options:"),"Positionals:":K.bold("Arguments:"),"Commands:":K.bold("Commands:"),"Examples:":K.bold("Examples:")}).wrap(Va(kp.columns-20,{min:80,max:120})).parseAsync()}zv().catch(()=>{Wa(1)}),process.on("unhandledReject\
1201
+ ion",t=>{console.error("Unhandled rejection",t)});