@flisk-sh/flisk 1.4.2 → 1.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/README.md +119 -43
- package/cli/dist/backend-languages/bun.js +5 -0
- package/cli/dist/backend-languages/go.js +3 -1
- package/cli/dist/cli.js +9 -0
- package/cli/dist/commands/completion.js +8 -1
- package/cli/dist/commands/config.js +130 -55
- package/cli/dist/commands/doctor.js +16 -15
- package/cli/dist/commands/logs.js +1 -0
- package/cli/dist/commands/project.js +1 -0
- package/cli/dist/commands/resource.js +39 -11
- package/cli/dist/commands/status.js +18 -9
- package/cli/dist/commands/up.js +102 -17
- package/cli/dist/frontend-frameworks/next.js +197 -0
- package/cli/dist/frontend-frameworks/react.js +81 -12
- package/cli/dist/frontend-frameworks/registry.js +5 -4
- package/cli/dist/frontend-frameworks/vue.js +82 -12
- package/cli/dist/generator/resource-templates.js +2 -4
- package/cli/dist/generator/template-engine.js +5 -3
- package/cli/dist/utils/cold-preflight.js +3 -2
- package/cli/dist/utils/config-explain.js +197 -0
- package/cli/dist/utils/demo-reset.js +22 -0
- package/cli/dist/utils/discovery-paths.js +7 -1
- package/cli/dist/utils/host-port-plan.js +8 -3
- package/cli/dist/utils/port-conflict-fix.js +16 -14
- package/cli/dist/utils/port-occupant.js +35 -0
- package/cli/dist/utils/project-features.js +7 -16
- package/cli/dist/utils/project-templates.js +8 -8
- package/cli/dist/utils/resource-features.js +5 -5
- package/cli/dist/utils/service-manifest.js +1 -0
- package/cli/dist/utils/service-urls.js +11 -0
- package/cli/dist/utils/startup-report.js +4 -3
- package/cli/dist/utils/tar.js +33 -28
- package/cli/dist/utils/tilt-process.js +4 -3
- package/cli/dist/utils/windows-doctor.js +18 -15
- package/cli/dist-bundle/{chunk-IGN5UC3P.js → chunk-4J2FLFUA.js} +14 -7
- package/cli/dist-bundle/{chunk-ETKUVKJ2.js → chunk-BMHPPX2Q.js} +10 -10
- package/cli/dist-bundle/chunk-BP2M4OJ4.js +2 -0
- package/cli/dist-bundle/{chunk-53L2JN7G.js → chunk-CGTWXWBU.js} +1 -1
- package/cli/dist-bundle/chunk-GPUJ55MI.js +3 -0
- package/cli/dist-bundle/{chunk-5QBYM33Q.js → chunk-LUUJ4JB7.js} +1 -1
- package/cli/dist-bundle/chunk-PEZQEZVV.js +17 -0
- package/cli/dist-bundle/{chunk-MWOVYIBB.js → chunk-SFOFTVYM.js} +5 -5
- package/cli/dist-bundle/{chunk-3XODDLRJ.js → chunk-TIYTGN5R.js} +1 -1
- package/cli/dist-bundle/{chunk-YNCBBJ4V.js → chunk-U42XZWXB.js} +1 -1
- package/cli/dist-bundle/chunk-ULMQVD7J.js +122 -0
- package/cli/dist-bundle/chunk-V36PT2HF.js +24 -0
- package/cli/dist-bundle/{chunk-I7TGIK5N.js → chunk-VMVTECCK.js} +1 -1
- package/cli/dist-bundle/{chunk-DU2BN46C.js → chunk-Z5QEE4SW.js} +1 -1
- package/cli/dist-bundle/cli.js +607 -375
- package/cli/dist-bundle/cold-preflight-3BNDOLGS.js +2 -0
- package/cli/dist-bundle/{demo-stage-OHNTP2UJ.js → demo-stage-G4W23BXW.js} +1 -1
- package/cli/dist-bundle/{extension-fetch-VEFSCG4B.js → extension-fetch-KIPYDIRM.js} +1 -1
- package/cli/dist-bundle/{open-XROJ6YEY.js → open-HQFT6WDC.js} +1 -1
- package/cli/dist-bundle/project-JZO2CPZZ.js +2 -0
- package/cli/dist-bundle/{project-templates-EYSQG2EO.js → project-templates-IMJ3OX5I.js} +1 -1
- package/cli/dist-bundle/{services-BIMF6MVU.js → services-GLFKZBBZ.js} +1 -1
- package/cli/dist-bundle/{tilt-port-owner-ZY5M2JC4.js → tilt-port-owner-PJN4MPYE.js} +1 -1
- package/cli/package.json +1 -1
- package/package.json +1 -1
- package/runtime/engine/topologies/platform/docker/compose/compose.star +40 -4
- package/runtime/engine/topologies/platform/docker/dockerfile/language_dockerfile.star +6 -0
- package/runtime/engine/topologies/platform/docker/dockerfile/next_dockerfile.star +83 -0
- package/runtime/engine/topologies/platform/docker/index.star +4 -0
- package/runtime/engine/topologies/platform/docker/layers/prisma/filesystem_setup.star +7 -0
- package/runtime/engine/topologies/platform/docker/networking/traefik.star +85 -46
- package/runtime/engine/topologies/tilt/common/utils_output.star +1 -0
- package/runtime/engine/topologies/tilt/generators/validators.star +1 -1
- package/runtime/engine/topologies/tilt/generators/vite/frontend.star +2 -2
- package/runtime/engine/topologies/tilt/generators/vite/generators.star +3 -0
- package/runtime/engine/topologies/tilt/manifest/constants.star +3 -0
- package/runtime/engine/topologies/tilt/manifest/parser.star +9 -3
- package/runtime/engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +8 -3
- package/runtime/engine/topologies/tilt/resources/orchestrator/generators/dependencies/resolver.star +50 -24
- package/runtime/engine/topologies/tilt/resources/orchestrator/generators/env.star +11 -2
- package/runtime/engine/topologies/tilt/resources/orchestrator/generators/manifest_resource.star +23 -9
- package/cli/dist-bundle/chunk-43XWL2PB.js +0 -61
- package/cli/dist-bundle/chunk-5F7YP5IR.js +0 -17
- package/cli/dist-bundle/chunk-K6SOCO6V.js +0 -3
- package/cli/dist-bundle/chunk-YHYRGWUH.js +0 -24
- package/cli/dist-bundle/chunk-YL56J2WX.js +0 -2
- package/cli/dist-bundle/cold-preflight-ZOPR7PWJ.js +0 -2
- package/cli/dist-bundle/project-7PTIOHGF.js +0 -2
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
|
|
2
|
+
import{E as H,a as h,ha as D,ia as U,t as x}from"./chunk-PEZQEZVV.js";import{C as j,L as R,j as A,m as w,n as F,t as L,x as T}from"./chunk-U42XZWXB.js";import{execFileSync as K}from"node:child_process";import{existsSync as de,mkdirSync as fe,readFileSync as G,realpathSync as pe,writeFileSync as he}from"node:fs";import{join as $,resolve as me,sep as ge}from"node:path";import{createServer as ae}from"node:net";import{connect as ie}from"node:net";function B(e,t=500){return new Promise(r=>{let s=ie({port:e,host:"127.0.0.1"}),n=o=>{s.destroy(),r(o)};s.setTimeout(t,()=>n(!1)),s.once("connect",()=>n(!0)),s.once("error",()=>n(!1))})}var ce={ingressHttp:{start:8080,end:8180},ingressHttps:{start:8443,end:8543},postgres:{start:15432,end:15532}},b={ingressHttp:"FLISK_HTTP_PORT",ingressHttps:"FLISK_HTTPS_PORT",postgres:"FLISK_POSTGRES_PORT"},E={ingressHttp:80,ingressHttps:443,postgres:5432},O={ingressHttp:E.ingressHttp,ingressHttps:E.ingressHttps};function ue(e,t){return e==="EACCES"&&t==="darwin"}async function I(e){return await B(e)?!1:new Promise(t=>{let r=ae();r.once("error",s=>{t(ue(s.code,process.platform))}),r.listen(e,"127.0.0.1",()=>r.close(()=>t(!0)))})}function le(e,t){let r=Number(t);if(!Number.isInteger(r)||r<1||r>65535)throw new R(`${e} must be an integer between 1 and 65535 (received ${JSON.stringify(t)})`,["Provide a valid port number between 1 and 65535"],1);return r}async function _(e={}){let t=e.env??process.env,r=e.isAvailable??I,s={ingressHttp:!1,ingressHttps:!1,postgres:!1},n={ingressHttp:"",ingressHttps:"",postgres:""},o={explicit:s},c=new Set;for(let a of["ingressHttp","ingressHttps","postgres"]){let u=t[b[a]],i=u!==void 0&&u.trim()!=="",l=e.ranges?.[a]??ce[a],d=O[a],f=i?[le(b[a],u)]:[...d===void 0?[]:[d],...Array.from({length:l.end-l.start+1},(g,k)=>l.start+k)],m;for(let g of f)if(!c.has(g)){if(await r(g)){m=g;break}if(i)throw new R(`${b[a]}=${g} is already in use. Choose a free host port and retry.`,["Choose a different free host port or unset the environment variable to use fallback ranges"],1)}if(m===void 0)throw new R(`No available host port in ${l.start}-${l.end} for ${a}. Set ${b[a]} to a free port and retry.`,[`Free up port range ${l.start}-${l.end} or set ${b[a]} to an available port`],1);c.add(m),o[a]=m,s[a]=i,n[a]=i?"explicit override":m===d?"requested port is free":`selected from fallback range ${l.start}-${l.end}`}return{...o,requested:{...E},reason:n}}function Je(e){return`Host ports: HTTP ${e.ingressHttp}, HTTPS ${e.ingressHttps}, Postgres ${e.postgres}`}var V=$(".flisk",".flisk-out","host-ports.json");function ke(e,t,r){return e.split(`
|
|
3
|
+
`).some(s=>{let[n="",o=""]=s.split("|"),c=n.toLowerCase(),a=t.toLowerCase();return(c.startsWith(`${a}_`)||c.startsWith(`${a}-`))&&o.includes(`:${r}->`)})}function W(e){let t=$(e,V);if(!de(t))return null;try{let r=JSON.parse(G(t,"utf-8"));if(!r||typeof r!="object")return null;let s=r;return!Number.isInteger(s.ingressHttp)||!Number.isInteger(s.ingressHttps)||!Number.isInteger(s.postgres)||!s.requested||!s.explicit||!s.reason?null:s}catch{return null}}function Xe(e,t){let r=$(e,V);fe($(e,".flisk",".flisk-out"),{recursive:!0}),he(r,`${JSON.stringify(t,null,2)}
|
|
4
|
+
`,{encoding:"utf-8",mode:384})}function et(e){process.env.FLISK_HTTP_PORT=String(e.ingressHttp),process.env.FLISK_HTTPS_PORT=String(e.ingressHttps),process.env.FLISK_POSTGRES_PORT=String(e.postgres)}var Pe="com.docker.compose.project.working_dir";function Se(e,t,r){let s=new Set([me(t)]);try{s.add(pe(t))}catch{}return e.split(`
|
|
5
|
+
`).some(n=>{let[,o="",c=""]=n.split("|");return!c||!o.includes(`:${r}->`)?!1:[...s].some(a=>c===a||c.startsWith(`${a}${ge}`))})}function tt(e,t,r=()=>K("docker",["ps","--format",`{{.Names}}|{{.Ports}}|{{.Label "${Pe}"}}`],{encoding:"utf-8",timeout:5e3})){let s=W(e);if(!s||s.ingressHttp===t)return t;try{if(Se(r(),e,s.ingressHttp))return s.ingressHttp}catch{}return t}async function rt(e,t={}){let r=W(e),s=["FLISK_HTTP_PORT","FLISK_HTTPS_PORT","FLISK_POSTGRES_PORT"].some(i=>process.env[i]);if(t.inspectDocker===!1&&r&&!s)return r;let n="";try{let i=JSON.parse(G($(e,".flisk",w),"utf-8"));n=String(i?.project?.name??"flisk-project").replace(/-/g,"_").toLowerCase()}catch{n="flisk_project"}let o="";if(t.inspectDocker!==!1)try{o=K("docker",["ps","--format","{{.Names}}|{{.Ports}}"],{encoding:"utf-8",timeout:5e3})}catch{}let c=i=>ke(o,n,i),a=t.isPortFree??I,u=async i=>await a(i)||c(i);if(r&&!s){for(let i of[r.ingressHttp,r.ingressHttps,r.postgres])if(!await u(i))return _({isAvailable:u});for(let[i,l]of Object.entries(O)){let d=r[i];if(l!==void 0&&d!==l&&await u(l))return _({isAvailable:u})}return r}return _({isAvailable:u})}import{execFileSync as X,execSync as S}from"node:child_process";import{existsSync as C,readdirSync as Te,readFileSync as N}from"node:fs";import{createServer as be}from"node:net";import{join as P}from"node:path";function J(e,t){return e==="pending"||e==="in_progress"||e==="none"||t==="pending"||t==="none"}var M="container is running, but its health check is failing";function z(e){let t=e?.runtimeStatus??"";if(t!=="ok")return t;let r=e?.composeResourceInfo?.healthStatus;return r==="unhealthy"?"error":r==="starting"?"pending":t}var y=1e4,q=3e3,$e="http://localhost:4873";function ee(e){return`'${e.replace(/'/g,"'\\''")}'`}function v(e,t,r,s,n){return process.platform==="win32"&&e===S?X(j(t)??t,r,{...n,windowsHide:!0}):e(s,n)}var ye=[80,443];function ve(e){return e.replace(/-/g,"_")}function we(e,t){let r=new Set(t),s=[];for(let n of e.split(`
|
|
6
|
+
`)){let o=n.trim();if(!o)continue;let c=o.indexOf(" "),a=c>=0?o.slice(0,c):o,u=c>=0?o.slice(c+1):"",i=[];for(let l of r)u.split(/[\s,]+/).some(f=>f.startsWith(`${l}->`)||f.includes(`:${l}->`))&&i.push(l);i.length>0&&s.push({name:a,ports:u,publishedPorts:i})}return s}function te(e,t){let r=e.toLowerCase(),s=t.toLowerCase();return r===`${s}_traefik`||r.startsWith(`${s}_traefik`)}function Re(e,t){return e.filter(r=>!te(r.name,t))}function _e(e){try{let t=e??U();return new Set(t.filter(r=>r.config?.sablier?.enable&&r.config?.sablier?.deferStart).map(r=>r.name))}catch{return new Set}}function xe(e,t=new Set){let s=JSON.parse(e).items??[],n=[],o=0,c=0,a=0;for(let u of s){let i=u.metadata?.name??"unknown",l=u.status?.updateStatus??"",d=z(u.status),f=d==="error"&&u.status?.runtimeStatus==="ok",g=(u.status?.buildHistory?.[0]?.error??"").trim()||(f?M:"");if(l==="error"||d==="error"){n.push({name:i,updateStatus:l,runtimeStatus:d,error:g.replace(/\s+/g," ").slice(0,800)});continue}if(l==="ok"&&(d==="ok"||d==="not_applicable")){a+=1;continue}i!=="(Tiltfile)"&&J(l,d)&&(t.has(i)?c+=1:o+=1)}return{failures:n,pendingCount:o,deferredCount:c,okCount:a,total:s.length}}var He=/failed to resolve source metadata for docker\.io\/library\/([A-Za-z0-9._-]+-l[1-4](?:-[a-z]+)*)(?::[^\s:]+)?:/i;function re(e){let t=e.replace(/\s+/g," ").trim(),r=t.match(/Bind for [^ ]+:(\d+) failed: port is already allocated/i);if(r)return`host port ${r[1]} is already allocated`;if(/port is already allocated/i.test(t))return"a required host port is already allocated";let s=[...t.matchAll(/ConnectionRefused downloading package manifest (@[A-Za-z0-9._/-]+)/gi)].map(a=>a[1]);if(s.length>0){let a=[...new Set(s)],u=a.slice(0,4).join(", "),i=a.length>4?` (+${a.length-4} more)`:"";return`private registry ConnectionRefused for ${u}${i} \u2014 Verdaccio (:4873) is down or unreachable from the build`}let n=t.match(He);if(n)return`base image ${n[1]} was missing when this build started (the golden layers weren't built yet, or golden-layers-build failed) - Tilt does not retry a failed build by itself`;if(/install-deps\.sh/i.test(t)||/bun install(?: --production)?/i.test(t)||/npm (?:ci|install)/i.test(t))return"dependency install failed during ImageBuild \u2014 usually Verdaccio (:4873) unreachable or missing @scoped packages (ConnectionRefused downloading package manifest)";let o=t.match(/No such image:\s*([^\s]+)/i)?.[1]??t.match(/pull access denied for ([^,:\s]+)/i)?.[1]??void 0,c=t.match(/\bup\s+-d\s+--no-build\s+([A-Za-z0-9._-]+)/i)?.[1];if(o||c||/docker compose .*\bup\s+-d\s+--no-build\b/i.test(t)){let a=o??`${c??"service"}:dev`,u=c?` for ${c}`:"";return`compose run failed because image is missing (${a})${u} \u2014 wait for the ImageBuild resource to finish, then re-trigger the *-run-only resource`}return/bun run build/i.test(t)?"ImageBuild failed during `bun run build` (compile/typecheck) \u2014 open the resource logs in Tilt for the TypeScript/build error":(/ImageBuild:/i.test(t)||/^Command "/i.test(t),t.slice(0,220))}function Z(e){return/ConnectionRefused downloading package manifest|Verdaccio|private registry|dependency install failed during ImageBuild|install-deps\.sh|bun install/i.test(e)}function Ee(e=T()??process.cwd()){let t=P(e,".flisk",w);if(!C(t))return!1;try{let r=JSON.parse(N(t,"utf-8"));return r.optional_infra?.verdaccio===!0||Object.values(r.phases??{}).some(s=>(s.enabledStacks??[]).includes("verdaccio"))}catch{return!1}}function se(e){for(let t of[P(e,".npmrc"),P(e,F)])if(C(t))try{let r=N(t,"utf-8");if(/:4873\b/.test(r)||/verdaccio/i.test(r))return!0}catch{}return!1}function Oe(e=T()??process.cwd()){return Ee(e)||se(e)}function kt(e=S,t=T()??process.cwd(),r=process.env.VERDACCIO_URL??process.env.NPM_REGISTRY_URL??$e,s=!0){if(!s&&!se(t))return{name:"Private npm registry",didPass:!0,isSkipped:!0,message:"Verdaccio is enabled in the project config but needs a Premium license, so Flisk will not start it - skipped"};if(!Oe(t))return{name:"Private npm registry",didPass:!0,isSkipped:!0,message:"Private npm registry (Verdaccio) not enabled for this project - skipped"};let n=!1;try{let a=v(e,"docker",["ps","--format","{{.Names}}"],"docker ps --format '{{.Names}}'",{stdio:"pipe",encoding:"utf-8",timeout:y});n=/verdaccio/i.test(a)}catch{}let o=!1,c="";try{let a=process.platform==="win32"?X("curl.exe",["-fsS","-o","NUL","-w","%{http_code}","--max-time","2",r],{stdio:"pipe",encoding:"utf-8",timeout:q+1e3,windowsHide:!0}).trim():e(`curl -fsS -o /dev/null -w '%{http_code}' --max-time 2 ${ee(r)}`,{stdio:"pipe",encoding:"utf-8",timeout:q+1e3}).trim();o=/^[23]\d\d$/.test(a),c=`HTTP ${a}`}catch(a){c=a instanceof Error?a.message.slice(0,120):"request failed"}return o?{name:"Private npm registry",didPass:!0,message:`Private npm registry reachable at ${r}${n?" (verdaccio container running)":""}`}:n?{name:"Private npm registry",didPass:!1,message:`Verdaccio container is running but ${r} is not responding (${c}). ImageBuilds that install @scoped packages will fail with ConnectionRefused downloading package manifest.`,fix:"Check `docker logs` for the verdaccio container, confirm port 4873 is published, then re-run `flisk doctor`."}:{name:"Private npm registry",didPass:!1,message:`Private npm registry (Verdaccio) is not reachable at ${r}. Docker ImageBuilds will fail with ConnectionRefused downloading package manifests for @flisk-sh/* and project-scoped packages.`,fix:"Start the registry with `bun run verdaccio:start` (or `docker compose -f docker-compose.verdaccio.yml up -d`), publish packages with `bun run publish:all` / `scripts/build/publish-to-verdaccio.sh`, then `tilt trigger` failed resources or re-run `flisk up`."}}function Pt(e=S,t=H(),r=ye){let s=ve(t),n="";try{n=v(e,"docker",["ps","--format","{{.Names}}\\t{{.Ports}}"],"docker ps --format '{{.Names}}\\t{{.Ports}}'",{stdio:"pipe",encoding:"utf-8",timeout:y})}catch{return{name:"Ingress Ports",didPass:!0,isSkipped:!0,message:"Docker not available - skipped ingress port check"}}let o=we(n,r),c=Re(o,s);if(c.length===0){let u=o.filter(i=>te(i.name,s));return u.length>0?{name:"Ingress Ports",didPass:!0,message:`Ingress ports ${r.join("/")} held by this project's Traefik (${u.map(i=>i.name).join(", ")})`}:{name:"Ingress Ports",didPass:!0,message:`Ingress ports ${r.join("/")} are free for Traefik`}}return{name:"Ingress Ports",didPass:!1,message:`Traefik cannot bind ingress ports because another container already owns them:
|
|
7
|
+
${c.map(u=>{let i=u.publishedPorts.join(", ");return`${u.name} (host ports ${i})`}).join(`
|
|
8
|
+
`)}`,fix:`Stop the foreign container(s), e.g. \`docker stop ${c[0]?.name}\`, or shut down the other Flisk/Tilt project using that Traefik. Then re-run \`flisk up\`.`}}function Y(e,t){return new Promise(r=>{let s=be();s.once("error",n=>r(n.code==="EADDRINUSE"?"in-use":"unknown")),s.once("listening",()=>s.close(()=>r("free"))),s.listen(e,t)})}async function St(e){for(let t=0;t<2;t++){let r=await Y(e,"0.0.0.0");if(r==="unknown")return r;if(r==="free"){let s=await Y(e,"127.0.0.1");if(s==="free"||s==="unknown")return s}t===0&&await new Promise(s=>setTimeout(s,50))}return"in-use"}function Ie(e){let{status:t}=e;return t===void 0?e.error??"no response":t===404?"HTTP 404: Traefik is answering but has no route for this URL (container not started yet, or not running)":t===502||t===503||t===504?`HTTP ${t}: Traefik found the route but the container isn't answering (still starting, or unhealthy)`:`HTTP ${t}`}function Tt(e){let t=e.filter(o=>o.status!==void 0),r=e.filter(o=>!o.ok);if(t.length===0)return{name:"Service Health",didPass:!0,isSkipped:!0,message:`No services responded - skipped ping of ${h(e.length,"service")} (stack may be down, or Traefik never bound :80)`,fix:"If `flisk up` is already running, check Traefik/port 80 in the Tilt UI. Otherwise start with: flisk up"};if(r.length===0)return{name:"Service Health",didPass:!0,message:`All ${h(e.length,"service")} responding on /health`};let s=r.map(o=>`${o.name} (${Ie(o)})
|
|
9
|
+
${o.url}`).join(`
|
|
10
|
+
`),n=r.some(o=>o.status===404);return{name:"Service Health",didPass:!1,message:`${h(r.length,"service")} not healthy (${e.length-r.length}/${e.length} healthy):
|
|
11
|
+
${s}`,fix:n?"If `flisk up` just started, images may still be building: re-run `flisk doctor` in a minute. Otherwise check `docker ps` and the resource in the Tilt UI, and compare `flisk networks` with the URL above.":"Check container state and routing: docker ps, then flisk networks to compare the advertised URLs against Traefik's routers"}}function bt(e){if(e.length===0)return{name:"Service Smoke",didPass:!0,isSkipped:!0,message:"No read-only smoke checks declared"};let t=e.filter(s=>!s.ok);if(t.length===0)return{name:"Service Smoke",didPass:!0,message:`All ${h(e.length,"service")} pass their smoke checks`};let r=t.map(s=>s.failure??`${s.name}: failed`).join(`
|
|
12
|
+
`);return{name:"Service Smoke",didPass:!1,message:`${h(t.length,"service")} failing a smoke check (${e.length-t.length}/${e.length} passing):
|
|
13
|
+
${r}`,fix:'Add the route the smoke step expects, or correct its "path" in the service.json "smoke" block. Then re-run flisk doctor.'}}function $t(e){let t=e.filter(n=>n.status!==void 0);if(t.length===0)return{name:"Advertised Endpoints",didPass:!0,isSkipped:!0,message:"No services responded - skipped advertised endpoint check"};let r=t.filter(n=>n.status===404);if(r.length===0)return{name:"Advertised Endpoints",didPass:!0,message:`${h(t.length,"advertised endpoint")} reachable`};let s=r.map(n=>`${n.name} (404)
|
|
14
|
+
${n.url}`).join(`
|
|
15
|
+
`);return{name:"Advertised Endpoints",didPass:!0,isWarning:!0,message:`${h(r.length,"advertised link")} ${r.length===1?"returns":"return"} 404 (the service may be healthy, but nothing answers at this exact path):
|
|
16
|
+
${s}`,fix:'Nothing handles this exact path, so opening the link shows a 404 even when /health is fine. If this API has no root route, you can leave it. Otherwise add a GET route for it (for example one that returns the service name), or declare a read-only "smoke" step on a real route in service.json. The URL flisk networks and the Flisk App print stays the same until the CLI changes how it reports it.'}}function yt(e=S){let t="";try{t=v(e,"tilt",["get","uiresources","-o","json"],"tilt get uiresources -o json",{stdio:"pipe",encoding:"utf-8",timeout:y})}catch{return{name:"Tilt Resources",didPass:!0,isSkipped:!0,message:"Tilt is not running - skipped resource status check",fix:"Start them with: flisk up"}}let r;try{r=xe(t,_e())}catch{return{name:"Tilt Resources",didPass:!0,isSkipped:!0,message:"Could not parse Tilt resource status - skipped"}}if(r.total===0)return{name:"Tilt Resources",didPass:!0,isSkipped:!0,message:"No Tilt UIResources found"};if(r.failures.length===0){let p=r.deferredCount>0?`, ${r.deferredCount} deferred`:"";return{name:"Tilt Resources",didPass:!0,message:`Tilt resources healthy (${r.okCount} ok, ${r.pendingCount} pending${p})`}}let s=Ne(r.failures),o=s.slice(0,20),c=s.length-o.length,a=o.map(p=>({failure:p,why:Fe(p,e)})),u=a.map(({failure:p,why:oe})=>`${p.name}: ${oe}`).join(`
|
|
17
|
+
`),i=c>0?`
|
|
18
|
+
\u2026and ${h(c,"more failed resource")}`:"",l=r.pendingCount>0?`
|
|
19
|
+
${h(r.pendingCount,"resource")} still pending/not started \u2014 often blocked by the failures above.`:"",d=r.deferredCount>0?`
|
|
20
|
+
${h(r.deferredCount,"resource")} intentionally deferred (sablier.deferStart) \u2014 not started until first request, unrelated to the failures above.`:"",f=s.some(p=>/port is already allocated/i.test(p.error)),m=s.some(p=>Z(p.error)||Z(re(p.error))),g=a.some(({why:p})=>/Kafka broker unreachable|kafka:9092/i.test(p)),k="Open the Tilt UI URL printed by flisk up (default port "+L.tiltUi+" when TILT_PORT is unset), inspect the red resources, fix the listed errors, then `tilt trigger <resource>` or re-run `flisk up`.";return f?k="Free the conflicting host port (usually 80/443): `docker ps --filter publish=80` then `docker stop <other-traefik>`. Re-trigger Traefik in the Tilt UI or run `flisk up` again.":m?k="Start Verdaccio (`bun run verdaccio:start`), ensure packages are published (`bun run publish:all` or `bash scripts/build/publish-to-verdaccio.sh`), confirm `curl http://localhost:4873` works, then `tilt trigger` the failed resources.":g&&(k="Kafka is not running (optional infra). Start it, point the bridge at a real broker, or disable Kafka-dependent resources until Kafka is enabled."),{name:"Tilt Resources",didPass:!1,message:`Tilt reports ${h(r.failures.length,"failed resource")}:
|
|
21
|
+
${u}${i}${l}${d}`,fix:k}}var Ce=/^(traefik|postgres|nats|infisical|verdaccio|proxy)([.-]|$)/i;function Q(e){return Ce.test(e)}function Ne(e){return[...e].sort((t,r)=>{let s=Q(t.name)?0:1,n=Q(r.name)?0:1;return s!==n?s-n:t.name.localeCompare(r.name)})}function Ae(e,t=S,r=H()){try{let s=v(t,"docker",["ps","-a","--format","{{.Names}}"],"docker ps -a --format '{{.Names}}'",{stdio:"pipe",encoding:"utf-8",timeout:y}).split(`
|
|
22
|
+
`).map(i=>i.trim()).filter(Boolean),n=`-autogenerated-${e}-1`,o=s.find(i=>i===e)??s.find(i=>i.startsWith(`${r}-`)&&i.endsWith(n))??s.find(i=>i.endsWith(n))??s.find(i=>i.includes(e));if(!o)return null;let c=v(t,"docker",["logs","--tail","120",o],`docker logs --tail 120 ${ee(o)} 2>&1`,{stdio:"pipe",encoding:"utf-8",timeout:y});if(/getaddrinfo ENOTFOUND/i.test(c)&&/kafka:9092/i.test(c))return"runtime crash: Kafka broker unreachable (getaddrinfo ENOTFOUND kafka:9092)";if(/ECONNREFUSED/i.test(c)&&/kafka/i.test(c))return"runtime crash: Kafka connection refused";let a=c.match(/ConnectionRefused downloading package manifest (@[A-Za-z0-9._/-]+)/i);if(a?.[1])return`runtime/build log: private registry ConnectionRefused for ${a[1]}`;if(/ZodError/i.test(c)){let i=[...c.matchAll(/"path"\s*:\s*\[\s*"([^"]+)"\s*\]/g)].map(d=>d[1]),l=[...new Set(i)].slice(0,6);return l.length>0?`runtime crash: ZodError missing required config/env: ${l.join(", ")}`:"runtime crash: ZodError during config/env validation"}let u=c.match(/error:\s+Failed to [^:\n]+[^\n]{0,120}/i)?.[0]??c.match(/Failed to (?:start|initialize) [^\n]{0,120}/i)?.[0]??c.match(/^\s*error:\s+[^\n]{0,160}/im)?.[0];if(u)return`runtime crash: ${u.replace(/\s+/g," ").trim().slice(0,180)}`}catch{return null}return null}function Fe(e,t=S){return e.error?re(e.error):e.runtimeStatus==="error"?Ae(e.name,t)??"runtime error (container crashed or unhealthy \u2014 check Tilt/docker logs)":e.updateStatus||e.runtimeStatus||"unknown error"}var Le=/\.(ts|tsx|mts|js|mjs|cjs)$/,je=new Set(["node_modules","dist",A,"tests","__tests__"]);function ne(e){let t=[];for(let r of Te(e,{withFileTypes:!0}))r.isDirectory()?je.has(r.name)||t.push(...ne(P(e,r.name))):Le.test(r.name)&&!/\.(test|spec)\./.test(r.name)&&t.push(P(e,r.name));return t}function De(e){let t=e?.healthCheckPath||"/health";return{container:t,traefik:e?.traefik?.healthCheck||t}}function Ue(e){let t=[];for(let r of e){if(!x(r.config?.appType))continue;let s=P(r.path,"src");if(!C(s))continue;let n=ne(s);if(n.length===0)continue;let o=n.map(i=>N(i,"utf-8")),{container:c,traefik:a}=De(r.config),u=c===a?[{path:c,usedBy:"container and Traefik healthchecks"}]:[{path:c,usedBy:"container healthcheck"},{path:a,usedBy:"Traefik healthcheck"}];for(let{path:i,usedBy:l}of u){let d=["'",'"',"`"].map(f=>`${f}${i}${f}`);o.some(f=>d.some(m=>f.includes(m)))||t.push({name:r.name,healthPath:i,usedBy:l})}}return t}function vt(e=T()??process.cwd()){let t=[];try{t=D(e)}catch{return{name:"Health Routes",didPass:!0,isSkipped:!0,message:"Could not read services - skipped health route check"}}let r=t.filter(o=>x(o.config?.appType));if(r.length===0)return{name:"Health Routes",didPass:!0,isSkipped:!0,message:"No backend services to check"};let s=Ue(r);return s.length===0?{name:"Health Routes",didPass:!0,message:`All ${h(r.length,"backend")} define their health route`}:{name:"Health Routes",didPass:!1,message:`Backends without a health route (the container never turns healthy, so Traefik returns 404):
|
|
23
|
+
${s.map(o=>`${o.name}: no "${o.healthPath}" route in src/ (probed by the ${o.usedBy})`).join(`
|
|
24
|
+
`)}`,fix:`Add the route, e.g. for Hono: app.get("${s[0]?.healthPath}", (c) => c.json({ status: "ok" })). To use a different path, set "healthCheckPath" (container healthcheck) or "traefik.healthCheck" (Traefik) in its service.json.`}}export{_ as a,Je as b,W as c,Xe as d,et as e,tt as f,rt as g,J as h,z as i,ve as j,we as k,_e as l,xe as m,re as n,Ee as o,kt as p,Pt as q,St as r,Tt as s,bt as t,$t as u,yt as v,vt as w};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
|
|
2
|
-
import{r as c}from"./chunk-
|
|
2
|
+
import{r as c}from"./chunk-4J2FLFUA.js";import{execFileSync as u}from"node:child_process";import{realpathSync as l}from"node:fs";import{resolve as p}from"node:path";var m=(o,t)=>u(o,t,{encoding:"utf-8",stdio:"pipe",timeout:5e3,windowsHide:!0});function a(o,t=process.platform,e=m){if(t==="win32")return null;try{let s=e("lsof",["-nP",`-iTCP:${o}`,"-sTCP:LISTEN","-t"]).split(/\r?\n/).map(r=>r.trim()).filter(Boolean);for(let r of s){let n=e("ps",["-p",r,"-o","command="]).trim(),[i]=c(`${r} ${n}`);if(i)return i}}catch{}return null}function f(o){try{return l(o)}catch{return p(o)}}function d(o,t){return o!==null&&f(o.root)!==f(t)}async function P(o,t,e,s=a){let r={running:[],foreign:[]};for(let n of o){if(!await e(n))continue;let i=s(n);i&&d(i,t)?r.foreign.push({port:n,root:i.root}):r.running.push(n)}return r}export{a,d as b,P as c};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
|
|
2
|
-
import{b}from"./chunk-MINZ25AC.js";import{g as m,r as T}from"./chunk-
|
|
2
|
+
import{b}from"./chunk-MINZ25AC.js";import{g as m,r as T}from"./chunk-V36PT2HF.js";import{a as S}from"./chunk-TIYTGN5R.js";import{F as k,H as $,fa as x,p as y,q as w}from"./chunk-PEZQEZVV.js";import{b as n,f as d,m as g,x as h}from"./chunk-U42XZWXB.js";import{Command as R}from"commander";import{readFileSync as N}from"node:fs";import{join as O}from"node:path";function F(o){let e=o.config;return e?Array.isArray(e.featuresEnabled)&&e.featuresEnabled.includes(d)?!0:(Array.isArray(e.dependsOn)?e.dependsOn:[]).some(a=>S.includes(a)):!1}function J(o,e){let s=o.replace(/-/g,"_"),a=[];for(let t of[...e].sort((r,c)=>r.name.localeCompare(c.name))){let r=t.resources.filter(F).map(c=>c.name);r.length!==0&&a.push({name:`${s}_${t.name.replace(/-/g,"_")}`,stack:t.name,services:r.sort()})}return a.length===0?null:{name:"postgres",databases:a}}function E(o){try{let e=JSON.parse(N(O(o,".flisk",g),"utf-8"));return typeof e?.project?.name=="string"?e.project.name:null}catch{return null}}var P=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"];function A(o){let e=process.stderr,s=e.isTTY===!0,a=0,t=o,r,c=()=>e.write(`\r\x1B[2K${n.cyan(P[a])} ${t}`);s?(c(),r=setInterval(()=>{a=(a+1)%P.length,c()},80)):e.write(`- ${t}
|
|
3
3
|
`);let l=(i,u)=>{r&&clearInterval(r),e.write(`${s?"\r\x1B[2K":""}${i} ${u??t}
|
|
4
4
|
`)};return{get text(){return t},set text(i){t=i,s||e.write(`- ${t}
|
|
5
5
|
`)},succeed:i=>l(n.green("\u2714"),i),fail:i=>l(n.red("\u2716"),i),warn:i=>l(n.yellow("\u26A0"),i)}}async function j(o){let{resources:e}=x(o),s=await m(o,{inspectDocker:!1}),{appBase:a}=k(s?.ingressHttp,o);return e.filter(t=>t.config?.appType==="frontend").map(t=>({name:t.name,url:`${a}${$(t)}`}))}async function v(o,e=2e3){try{return(await fetch(o,{signal:AbortSignal.timeout(e)})).status<500}catch{return!1}}async function D(o,e=3e4,s){if(o.length===0)return;let a=Date.now();for(;;){for(let r of o)if(await v(r.url))return r;let t=Date.now()-a;if(t>=e)return;s?.(t),await new Promise(r=>setTimeout(r,2e3))}}async function te(o,e=0,s){let a=await j(o);return D(a,e,s)}async function C(o){let e=o??h();if(!e)return console.log(n.yellow("Not in a Flisk project, so there is no frontend to open.")),console.log(n.gray("Run `flisk project --yes` first, or `flisk open` inside a project.")),null;let s=await j(e);if(s.length===0)return console.log(n.yellow("This project has no frontend service to open.")),console.log(n.gray("Start the stack with `flisk up` and add a frontend with `flisk resource`.")),null;let a=E(e);y(`Opening the first frontend of ${a??"this project"}`);for(let l of s)console.log(n.gray(` - ${l.name}: ${l.url}`));let t=A("Waiting for the frontend to answer..."),r=await D(s,12e4,l=>{t.text=`Waiting for the frontend to answer... ${Math.round(l/1e3)}s`});if(!r){t.fail("No frontend answered yet.");let i=(await m(e,{inspectDocker:!1}))?.ingressHttp,u=i?await T(i)==="in-use":!1;if(i&&!u){console.log(n.yellow(`The stack is running, but this machine cannot reach port ${i}.`)),console.log(n.gray(" Docker is not publishing the port to the host."));let{checkColima:f}=await import("./colima-GBURKN54.js"),p=f();p.isColima&&!p.running?(console.log(n.gray(` ${p.problem??"The Colima VM is not running"}`)),console.log(n.gray(` Fix: ${p.fix??"colima start"}`))):console.log(n.gray(" Restart the Docker runtime (Docker Desktop or Colima), then run `flisk open` again."))}else console.log(n.yellow("The stack is not serving the frontend yet.")),console.log(n.gray(" - Start the stack in another terminal: flisk up")),console.log(n.gray(" - Then run this again: flisk open"));for(let f of s)console.log(n.gray(` - ${f.name}: ${f.url}`));return null}t.succeed(`The frontend is up: ${r.name}`);let c=await b(r.url);return console.log(c?n.green(`
|