@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
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
|
|
2
|
-
import{N as q,b as f,e as G,h as xe,i as Ee,m as ke,n as we,r as z,u as ve,v as be,x as T}from"./chunk-YNCBBJ4V.js";import st,{existsSync as O,readdirSync as nn,readFileSync as rn,statSync as ce}from"node:fs";import{dirname as on,join as w}from"node:path";var j=class{data;options;constructor(t){this.data=new Map,this.options=t}has(t){let n=this.data.get(t);return n?Date.now()-n.timestamp>this.options.ttlMs?(this.data.delete(t),!1):!0:!1}get(t){if(this.has(t))return this.data.get(t)?.value}set(t,n){this.data.set(t,{value:n,timestamp:Date.now()})}delete(t){this.data.delete(t)}clear(){this.data.clear()}keys(){let t=[];for(let n of this.data.keys())this.has(n)&&t.push(n);return t}size(){return this.keys().length}};function Te(e){let t=0;return{isValid(){return Date.now()-t<e},markUpdated(){t=Date.now()},reset(){t=0}}}function ct(e,t,n){return e===1?t:n||`${t}s`}function Re(e,t,n){return`${e} ${ct(e,t,n)}`}var ut={month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"};function Sn(e){return new Date(e).toLocaleString("en-US",ut)}function yn(e){return new Date(e).toLocaleDateString("en-US",{month:"short",day:"numeric"})}var K={success:{color:"green",icon:"\u2713",chalkFn:f.green},error:{color:"red",icon:"\u2717",chalkFn:f.red},warning:{color:"yellow",icon:"\u25CB",chalkFn:f.yellow},unknown:{color:"gray",icon:"?",chalkFn:f.gray}};function H(e){if(!e)return"unknown";let t=e.toLowerCase();return t==="ready"||t==="healthy"||t==="active"||t==="running"?"success":t==="error"||t==="failed"||t==="critical"||t==="stopped"?"error":t==="pending"||t==="starting"||t==="building"||t==="degraded"?"warning":"unknown"}function $n(e){return K[H(e)].color}function xn(e){return K[H(e)].icon}function En(e,t){return K[H(t)].chalkFn(e)}var ft={resources:{singular:"resource",command:"flisk resource <name>",context:`
|
|
3
|
-
To create a resource:`},stacks:{singular:"stack",command:"flisk stack <stack-name>",context:`
|
|
4
|
-
To create a stack, use:`},services:{singular:"service",command:"flisk resource <name>",context:`
|
|
5
|
-
To create a service:`},"stack-services":{singular:"service",command:"flisk resource <name> --stack <stack-name>",context:`
|
|
6
|
-
To add services to this stack:`}};function kn(e,t){let n=ft[e];console.log(t?f.yellow(`No ${n.singular}s found${t}.`):f.yellow(`No ${n.singular}s found.`)),console.log(f.gray(n.context)),console.log(f.gray(` ${n.command}`)),e==="stacks"&&(console.log(f.gray(`
|
|
7
|
-
Or create a new resource with a stack:`)),console.log(f.gray(" flisk resource <name> --stack <stack-name>")))}function wn(e){console.log(f.yellow(e||"Cancelled."))}function vn(e){console.log(f.blue(`Flisk ${e}
|
|
8
|
-
`))}function bn(e,t){console.log(f.green(`All ${e} are ${t}!`))}var J=62;function Tn(e="\u2500",t=J){return e.repeat(t)}function Ae(e,t=J-2){let n=Math.max(0,t-e.length),r=Math.floor(n/2),o=n-r;return" ".repeat(r)+e+" ".repeat(o)}function An(e,t){return e.length>t?`${e.slice(0,t-1)}\u2026`:e.padEnd(t)}function Rn(e,t){return e.length<=t?e:`${e.slice(0,t-3)}...`}function _n(e){console.log(f.green(`\u2713 ${e}`))}function On(e){console.log(f.blue(e))}function Cn(e,t=2){console.log(f.gray(`${" ".repeat(t)}${e}`))}function Dn(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function Fn(e,t,n=J){let r=n-2,o="\u2500".repeat(r);console.log(),console.log(f.cyan(`\u256D${o}\u256E`)),console.log(f.cyan("\u2502")+f.bold.white(Ae(e,r))+f.cyan("\u2502")),t&&(console.log(f.cyan(`\u251C${o}\u2524`)),console.log(f.cyan("\u2502")+f.gray(Ae(t,r))+f.cyan("\u2502"))),console.log(f.cyan(`\u2570${o}\u256F`))}import{existsSync as et,readFileSync as tt}from"node:fs";import{copyFileSync as Ve,mkdirSync as It,rmSync as We,writeFileSync as Ge}from"node:fs";import{join as _}from"node:path";function A(e){return e==="backend"||e==="mcp"||e==="agent"}import{existsSync as At,readFileSync as Rt}from"node:fs";import{join as _t}from"node:path";import{randomBytes as Oe}from"node:crypto";import{existsSync as Z,readFileSync as Ce,writeFileSync as De}from"node:fs";import{join as Q}from"node:path";import{randomBytes as pt}from"node:crypto";import{closeSync as dt,fchmodSync as lt,fsyncSync as mt,openSync as ht,renameSync as gt,rmSync as St,statSync as yt,writeFileSync as $t}from"node:fs";import{basename as xt,dirname as Et,join as kt}from"node:path";function _e(e,t){let n=kt(Et(e),`.${xt(e)}.${process.pid}.${pt(4).toString("hex")}.tmp`),r;try{r=yt(e).mode&511}catch{r=void 0}try{let o=ht(n,"wx");try{r!==void 0&<(o,r),$t(o,t,"utf-8"),mt(o)}finally{dt(o)}gt(n,e)}catch(o){throw St(n,{force:!0}),o}}var b=[{name:"VERDACCIO_URL_DOCKER",description:"Docker-internal URL of the private npm registry (Verdaccio, a paid feature)",required:!1,default:"http://verdaccio:4873",example:"http://verdaccio:4873"},{name:"VERDACCIO_URL",description:"Local URL of the private npm registry (Verdaccio, a paid feature)",required:!1,default:"http://localhost:4873"},{name:"TILT_ENV",description:"Tilt environment name",required:!0,default:"dev",example:"dev",complete:!0},{name:"DATABASE_URL",description:"PostgreSQL connection string (uses the generated DB_PASSWORD below)",required:!1},{name:"DB_PASSWORD",description:"PostgreSQL superuser password (docker-compose POSTGRES_PASSWORD)",required:!0,example:"postgres",complete:!0},{name:"JWT_SECRET",description:"Secret that signs local-jwt tokens (generated once per project; never shared between projects)",required:!1,complete:!0}],Fe=()=>Oe(16).toString("hex"),wt=()=>Oe(32).toString("hex"),Gn=b.filter(e=>e.complete).map(e=>e.name);function Y(e,t){return e==="DB_PASSWORD"?t:e==="JWT_SECRET"?wt():e==="DATABASE_URL"?`postgresql://postgres:${t}@postgres:5432/app_dev`:b.find(n=>n.name===e)?.default??""}function vt(e){let t=e.trim(),n=t[0];if(n==='"'||n==="'"){let o=!1;for(let s=1;s<t.length;s+=1){let a=t[s];if(o){o=!1;continue}if(a==="\\"){o=!0;continue}if(a===n){let i=t.slice(1,s);if(n==='"'){let c={n:`
|
|
9
|
-
`,r:"\r",t:" ",'"':'"',"\\":"\\",$:"$"};return i.replace(/\\([nrt"\\$])/g,(d,p)=>c[p]??p)}return i.replace(/\\'/g,"'")}}return t}let r=e.search(/\s#/);return(r===-1?e:e.slice(0,r)).trim()}function R(e){let t=new Map,n=e.startsWith("\uFEFF")?e.slice(1):e;for(let r of n.split(/\r?\n/)){let o=r.trim();if(!o||o.startsWith("#"))continue;let s=o.startsWith("export ")?o.slice(7).trim():o,a=s.indexOf("=");if(a<=0)continue;let i=s.slice(0,a).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)&&t.set(i,vt(s.slice(a+1)))}return t}function Ne(e){let t=[`# ${e.description}`];return e.required&&t.push("# Required (the value below is a working default)"),e.example&&t.push(`# Example: ${e.example}`),t}function je(){let e=Fe(),t=["# \u{1F527} Flisk Environment Configuration","# Generated by `flisk project`. The defaults work as-is; edit only to change them.","# Keep this file out of git: it holds a generated database password and JWT secret.","#","# After editing, run: flisk config regenerate && flisk up",""];for(let n of b)t.push(...Ne(n)),t.push(`${n.name}=${Y(n.name,e)}`),t.push("");return t.join(`
|
|
10
|
-
`)}function bt(e){let t=e.match(/^[a-z][a-z0-9+.-]*:\/\/[^:/@\s]+:([^@\s]*)@/i);if(!(!t||t[1].includes("$")))return t[1]}function zn(e){let t=Q(e,".env"),n={missing:[],invalid:[],warnings:[]};if(!Z(t))return{missing:b.filter(a=>a.required).map(a=>a.name),invalid:[],warnings:[".env file not found - will be auto-generated"]};let r=R(Ce(t,"utf-8"));for(let a of b)a.required&&!r.has(a.name)&&n.missing.push(a.name),r.has(a.name)&&!(r.get(a.name)??"").trim()&&n.invalid.push(`${a.name} is set but empty`);let o=r.get("DATABASE_URL"),s=r.get("DB_PASSWORD");if(o&&s){let a=bt(o);a!==void 0&&a!==s&&n.warnings.push("DATABASE_URL carries a different password than DB_PASSWORD; the database container uses DB_PASSWORD")}return n}function Tt(e,t,n){if(!R(e).has(t))return e;let o=e.indexOf("=");if(o<0)return e;let s=e.slice(o+1),a=s.search(/\s#/),i=a<0?"":s.slice(a);return e.slice(0,o+1)+n+i}function qn(e){let t=Q(e,".env");if(!Z(t))return De(t,je(),{mode:384}),b.map(u=>u.name);let n=Ce(t,"utf-8"),r=R(n),o=b.filter(u=>u.complete?r.has(u.name)?!(r.get(u.name)??"").trim():!0:!1);if(o.length===0)return[];let s=o.filter(u=>!r.has(u.name)),a=o.filter(u=>r.has(u.name)),i=r.get("DB_PASSWORD"),c=i?.trim()?i:Fe(),d=n.split(/(\r\n|\n|\r)/);for(let u of a){let h=-1;for(let l=0;l<d.length;l+=2)R(d[l]).has(u.name)&&(h=l);if(h<0)throw new Error(`Could not locate empty .env assignment for ${u.name}`);d[h]=Tt(d[h],u.name,Y(u.name,c))}let p=d.join("");if(s.length>0){let u=["","# Added by Flisk: keys this version expects. Existing values above were not changed.",""];for(let l of s)u.push(...Ne(l)),u.push(`${l.name}=${Y(l.name,c)}`),u.push("");let h=p.endsWith(`
|
|
11
|
-
`)||p.endsWith("\r")?"":`
|
|
12
|
-
`;p+=h+u.join(`
|
|
13
|
-
`)}return _e(t,p),o.map(u=>u.name)}function Kn(e){let t=Q(e,".env");return Z(t)?!1:(De(t,je(),{mode:384}),!0)}var Ot="[REDACTED]",X=class extends Error{path;constructor(t,n){super(`Could not read ${t}: ${n}`),this.path=t,this.name="EnvUnreadableError"}},Ct=8;function Dt(e,t=[]){let n=[...Pe(_t(e,".env")),...t.flatMap(r=>Pe(r))];return[...new Set(n)].sort((r,o)=>o.length-r.length)}function Pe(e){if(!At(e))return[];let t;try{t=Rt(e,"utf-8")}catch(n){throw new X(e,n instanceof Error?n.message:String(n))}return[...R(t).values()].filter(n=>n.length>=Ct)}function Me(e,t){let n=e;for(let r of t)n=n.split(r).join(Ot);return n}function Ie(e,t){return t.length===0?e:typeof e=="string"?Me(e,t):Array.isArray(e)?e.map(n=>Ie(n,t)):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Ie(r,t)])):e}function Be(e,t=[]){let n;try{n=Dt(e,t)}catch(r){return()=>{throw r}}return r=>Me(r,n)}import{readFileSync as Ft}from"node:fs";import{join as Nt}from"node:path";function or(){return Ue(T())}function Ue(e){if(e)try{let t=Ft(Nt(e,".flisk",ke),"utf-8"),n=JSON.parse(t);if(n?.project?.name)return n.project.name}catch{}return"flisk-project"}function ee(e,t){let n=Ue(t??T()),r=process.env.FLISK_SERVICE_BASE_URL??`http://${n}.localhost${e?`:${e}`:""}`;try{let o=new URL(r.includes("://")?r:`http://${r}`),s=o.hostname,a=o.protocol==="https:"?"443":"80",i=o.port||(e?String(e):""),c=i===a?"":i;if(s==="localhost"||/^\d+\.\d+\.\d+\.\d+$/.test(s))return{appBase:`${o.protocol}//${s}${c?`:${c}`:""}`,apiBase:`${o.protocol}//${s}${c?`:${c}`:""}`};let d=s.replace(/^(app|api)\./,"");return{appBase:`${o.protocol}//app.${d}${c?`:${c}`:""}`,apiBase:`${o.protocol}//api.${d}${c?`:${c}`:""}`}}catch{return{appBase:`http://app.${n}.localhost`,apiBase:`http://api.${n}.localhost`}}}function jt(e){return`${e.replace(/\/+$/,"")}/health`}function te(e){if(A(e.config?.appType)){let t=e.name.replace(/-api$/,"");return e.config?.apiPath??`/api/${t}`}return e.config?.basePath??`/${e.name}`}function sr(e,t){return Le(e,t,n=>jt(n))}function ar(e,t){return Le(e,t,n=>n)}function Le(e,t,n){let{appBase:r,apiBase:o}=ee(t);return e.filter(s=>s.config?.appType==="frontend"||A(s.config?.appType)).map(s=>{let a=A(s.config.appType)?o:r;return{name:s.name,appType:s.config.appType,url:`${a}${n(te(s))}`}})}async function Pt(e,t){try{let n=await fetch(e.url,{method:"GET",redirect:"manual",signal:AbortSignal.timeout(t)});return{...e,ok:n.ok,status:n.status}}catch(n){let r=n instanceof Error&&n.name==="TimeoutError"?`no response within ${t}ms`:n instanceof Error?n.message:String(n);return{...e,ok:!1,error:r}}}async function ir(e,t){return Promise.all(e.map(n=>Pt(n,t)))}var Ye=60,ze=1e3,qe=1e4,Ke=200,He=64*1024,Je=new Set([404,502,503,504]),Mt=new Set(["ECONNREFUSED","ENOTFOUND","EAI_AGAIN","EHOSTUNREACH","ENETUNREACH"]),Bt=new Set(["GET","HEAD","OPTIONS"]);function E(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ut(e,t){if(Bt.has(t))return!0;if(!E(e))return!1;let n=E(e.cause)?e.cause:void 0,r=e.code??n?.code;return typeof r=="string"&&Mt.has(r)}function re(e){if(!E(e))return['smoke: must be an object with "via" and "steps"'];let t=[];return e.via!=="proxy"&&t.push('smoke.via: only "proxy" is supported (the check must go through the public URL)'),e.timeoutSeconds!==void 0&&!(typeof e.timeoutSeconds=="number"&&e.timeoutSeconds>0)&&t.push("smoke.timeoutSeconds: must be a number greater than 0"),!Array.isArray(e.steps)||e.steps.length===0?(t.push("smoke.steps: needs at least one step"),t):(e.steps.forEach((n,r)=>{let o=`smoke.steps[${r}]`;if(!E(n)){t.push(`${o}: must be an object`);return}let s=n.path;(typeof s!="string"||!s.startsWith("/")||s.startsWith("//"))&&t.push(`${o}.path: must start with "/" and is appended to the public URL; a full URL or relative path would skip the proxy`),n.expect!==void 0&&!(typeof n.expect=="number"&&Number.isInteger(n.expect)&&n.expect>=100&&n.expect<=599)&&t.push(`${o}.expect: must be an HTTP status between 100 and 599`),n.bodyContains!==void 0&&typeof n.bodyContains!="string"&&t.push(`${o}.bodyContains: must be a string`),n.save!==void 0&&(E(n.save)&&Object.values(n.save).every(i=>typeof i=="string"&&i.startsWith("$."))||t.push(`${o}.save: must map names to paths such as "$.id"`))}),t)}function hr(e,t){let{appBase:n,apiBase:r}=ee(t),o=[];for(let s of e){let a=s.config;if(!a?.smoke)continue;let i=a.appType,c=A(i)||i===G;if(!c&&i!=="frontend"||a.exposeViaProxy===!1)continue;let d=c?r:n,p=a.healthCheckPath||(c&&i!==G?"/health":void 0);o.push({name:s.name,baseUrl:`${d}${te(s).replace(/\/+$/,"")}`,...p?.startsWith("/")?{readyPath:p}:{},smoke:a.smoke})}return o}var Lt=10;function gr(e,t={}){let n=t.timeoutSeconds??Lt;return e.flatMap(r=>{let o=r.smoke.steps.filter(a=>(a.method??"GET").toUpperCase()==="GET"&&a.body===void 0&&!a.path.includes("{{")).map(a=>({...a,bodyContains:void 0}));if(o.length===0)return[];let s=Math.min(r.smoke.timeoutSeconds??Ye,n);return[{name:r.name,baseUrl:r.baseUrl,smoke:{via:r.smoke.via,timeoutSeconds:s,steps:o}}]})}function Vt(e,t){let n=t.replace(/^\$\.?/,"").match(/[^.[\]]+/g)??[],r=e;for(let o of n){if(r==null||o==="__proto__"||o==="constructor"||o==="prototype"||!Object.hasOwn(r,o))return;let s=Object.getOwnPropertyDescriptor(r,o);if(!s||!("value"in s))return;r=s.value}return r}function Ze(e,t){return e.replace(/\{\{(\w+)\}\}/g,(n,r)=>t[r]??n)}function ne(e,t){return typeof e=="string"?Ze(e,t):Array.isArray(e)?e.map(n=>ne(n,t)):E(e)?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,ne(r,t)])):e}function M(e){let t=e.replace(/\s+/g," ").trim();return t.length>Ke?`${t.slice(0,Ke)}...`:t}function Qe(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"step"}function Wt(e,t){let n=Qe(t),r=(e.get(n)??0)+1;return e.set(n,r),r===1?n:`${n}-${r}`}function Gt(e,t,n,r,o){try{let s=_(e,Qe(n.service),t);It(s,{recursive:!0});let a=_(s,"latest.json"),i=_(s,"body.txt");return r===void 0?We(i,{force:!0}):Ge(i,r),Ge(a,`${JSON.stringify({...n,bodyPath:r===void 0?null:"body.txt"},null,2)}
|
|
14
|
-
`),o&&(Ve(a,_(s,"last-success.json")),r===void 0?We(_(s,"last-success-body.txt"),{force:!0}):Ve(i,_(s,"last-success-body.txt"))),a}catch{return}}function zt(e){let t=Buffer.from(e,"utf8");if(t.length<=He)return{body:e,truncated:!1,bytes:t.length};let n=t.subarray(0,He).toString("utf8").replace(/\uFFFD$/,"");return{body:n,truncated:!0,bytes:Buffer.byteLength(n,"utf8")}}async function qt(e,t={}){let n=t.fetch??((p,u)=>fetch(p,u)),r=t.now??Date.now,o=t.sleep??(p=>new Promise(u=>setTimeout(u,p))),s=(e.smoke.timeoutSeconds??Ye)*1e3,a=r()+s,i={},c=re(e.smoke);if(c.length>0)return{name:e.name,ok:!1,failure:`${e.name}: invalid smoke block: ${c.join("; ")}`};if(e.readyPath){let p=`${e.baseUrl}${e.readyPath}`;for(;;){try{let u=await n(p,{method:"GET",signal:AbortSignal.timeout(qe)});if(await u.text(),!Je.has(u.status)&&u.status<500)break}catch{}if(r()>=a)break;await o(ze)}}a=r()+s;let d=new Map;for(let[p,u]of e.smoke.steps.entries()){let h=u.name??`step ${p+1}`,l=(u.method??"GET").toUpperCase(),me=`${e.baseUrl}${Ze(u.path,i)}`,C=u.expect??200,he=u.body!==void 0,S,D="",x,L;for(;;){x=void 0,L=void 0,S=void 0;let g=!1;try{let m=await n(me,{method:l,headers:he?{"content-type":"application/json"}:void 0,body:he?JSON.stringify(ne(u.body,i)):void 0,signal:AbortSignal.timeout(qe)});S=m.status,D=await m.text()}catch(m){g=Ut(m,l),x=m instanceof Error?m.message:String(m);let v=E(m)?m.code??(E(m.cause)?m.cause.code:void 0):void 0;L=typeof v=="string"?v:void 0}if(!(x!==void 0&&g||S!==void 0&&S!==C&&Je.has(S))||r()>=a)break;await o(ze)}let ge=!1,V=g=>{if(!ge){if(!t.redact)return g;try{return t.redact(g)}catch($){ge=!0;let m=$ instanceof Error?$.message:String($);t.warn?.(`${e.name}: ${h}: the response text was neither shown nor stored: ${m}`);return}}},W=V(me),y=S===void 0?void 0:V(D),Se=x===void 0?void 0:V(x),ye=x===void 0?void 0:L??Se,F=`${e.name}: ${h}: ${l} ${W??"(url withheld)"}`,$e;if(t.recordDir){let g=y===void 0?void 0:zt(y),$=x===void 0&&S===C&&(u.bodyContains===void 0||D.includes(u.bodyContains));$e=Gt(t.recordDir,Wt(d,h),{service:e.name,step:h,method:l,...W===void 0?{}:{url:W},expectedStatus:C,status:S??null,...ye===void 0?{}:{error:ye},truncated:g?.truncated??!1,bodyBytes:g?.bytes??0},g?.body,$)}let N=g=>({name:e.name,ok:!1,failure:g,recordPath:$e});if(x!==void 0)return N(`${F} never answered (${Se??"the error was withheld"})`);if(S!==C)return N(`${F} returned ${S}, expected ${C}${y?`: ${M(y)}`:""}`);if(u.bodyContains!==void 0&&!D.includes(u.bodyContains))return N(`${F} returned ${S} but the body does not contain "${u.bodyContains}"${y?`: ${M(y)}`:""}`);if(u.save){let g;try{g=JSON.parse(D)}catch{return N(`${F} returned a body that is not JSON, cannot save${y?`: ${M(y)}`:""}`)}for(let[$,m]of Object.entries(u.save)){let v=Vt(g,m);if(v==null||typeof v=="object")return N(`${F} response has no ${m} to save as {{${$}}}${y?`: ${M(y)}`:""}`);i[$]=String(v)}}}return{name:e.name,ok:!0}}function Sr(e){return`Smoke check failed: ${e.failure}${e.recordPath?` (record: ${e.recordPath})`:""}`}function yr(e,t,n={}){return{redact:Be(e,n.envFiles??[]),...t?{warn:t}:{}}}async function $r(e,t={}){return Promise.all(e.map(n=>qt(n,t)))}var Xe=1,wr="https://flisk.sh/schema.service.json",Kt={dependencies:"deprecated, use dependsOn (still read for now)",envVars:"deprecated, use params (still read when params is absent)",jwtSecret:"ignored. A secret must not be committed: remove it and set JWT_SECRET in the project .env"},Ht=new Set(["$schema","agent","apiBasePath","apiPath","appName","appType","backendName","basePath","build","buildContext","databaseName","dependencies","dev","dependsOn","dockerfile","enabled","exposeViaProxy","featuresEnabled","framework","healthCheckPath","image","language","name","nats","params","playwright","port","replicas","restart","runtime","sablier","schemaVersion","secrets","smoke","stack","syncs","traefik","type"]),Jt=[{path:["healthCheckPath"],pattern:/^\/[a-z0-9/-]*$/,expected:"a path such as /health"},{path:["traefik","host"],pattern:/^[A-Za-z0-9.-]+$/,expected:"a hostname such as shop.backend.myproject.local"},{path:["traefik","pathPrefix"],pattern:/^\/[a-z0-9/-]*$/,expected:"a path such as /api/v1/shop-management"},{path:["traefik","healthCheck"],pattern:/^\/[a-z0-9/-]*$/,expected:"a path such as /health"},{path:["nats","queueGroup"],pattern:/^[A-Za-z0-9_.-]+$/,expected:"letters, digits, '_', '.' or '-'"},{path:["databaseName"],pattern:/^[A-Za-z0-9_-]+$/,expected:"letters, digits, '_' or '-'"},{path:["stack"],pattern:/^[A-Za-z0-9_-]+$/,expected:"letters, digits, '_' or '-'"},{path:["image"],pattern:/^[A-Za-z0-9._/:@-]+$/,expected:"an image reference such as ghcr.io/acme/app:1.0"}];function B(e,t){let n=[],r=new Set;for(let{path:o,pattern:s,expected:a}of Jt){let i=e;for(let d of o)i=i&&typeof i=="object"&&!Array.isArray(i)?i[d]:void 0;if(i==null||i==="")continue;let c=`${t}.${o.join(".")}`;(typeof i!="string"||!s.test(i))&&r.add(c),typeof i!="string"?n.push(`${c}: expected a string`):s.test(i)||n.push(`${c}: must be ${a} (no spaces, line breaks or YAML syntax)`)}for(let[o,s]of Yt(e,t))r.has(o)||n.push(`${o}: ${s}`);return n}function oe(e){for(let t=0;t<e.length;t++){let n=e.charCodeAt(t);if(n<32||n===127||n===133||n===8232||n===8233)return!0}return!1}function Yt(e,t){let n=[],r=Object.entries(e).filter(([o])=>o!=="smoke").map(([o,s])=>[s,`${t}.${o}`]);for(let o of Object.keys(e))oe(o)&&n.push([t,"a key contains a line break"]);for(;r.length>0;){let[o,s]=r.pop();if(typeof o=="string")oe(o)&&n.push([s,"must not contain line breaks or control characters"]);else if(Array.isArray(o))for(let[a,i]of o.entries())r.push([i,`${s}[${a}]`]);else if(o&&typeof o=="object")for(let[a,i]of Object.entries(o))oe(a)?n.push([s,"a key contains a line break"]):r.push([i,`${s}.${a}`])}return n.sort(([o],[s])=>o.localeCompare(s))}var Zt=["apiPath","basePath"];function se(e){if(!e||typeof e!="object"||Array.isArray(e))return[];let t=e;return Zt.filter(n=>n in t&&typeof t[n]!="string")}function ae(e,t){if(!e||typeof e!="object"||Array.isArray(e))return{errors:[`${t}: expected a JSON object`],warnings:[]};let n=e,r=[];for(let i of["appName","appType","stack","schemaVersion"])i in n||r.push(`${t}.${i}: required field is missing`);for(let i of["appName","appType","stack"])i in n&&typeof n[i]!="string"&&r.push(`${t}.${i}: expected a string`);"schemaVersion"in n&&n.schemaVersion!==Xe&&r.push(`${t}.schemaVersion: unsupported version ${String(n.schemaVersion)} (supported: ${Xe})`);for(let i of se(n))r.push(`${t}.${i}: expected a string`);let o=n.dev,s=o&&typeof o=="object"&&!Array.isArray(o)?o.liveReload:void 0;if(s!==void 0&&typeof s!="boolean"&&r.push(`${t}.dev.liveReload: expected true or false`),r.push(...B(n,t)),"smoke"in n)for(let i of re(n.smoke))r.push(`${t}.${i}`);let a=Object.keys(n).flatMap(i=>{let c=Kt[i];return c?[`${t}.${i}: ${c}`]:Ht.has(i)?[]:[`${t}.${i}: unknown field is preserved`]});return s===!0&&n.language!=="go"&&a.push(`${t}.dev.liveReload: only applies to Go services (language "go"); it is ignored here`),{errors:r,warnings:a,manifest:n}}function vr(e,t){if(!et(e))return[];try{let n=JSON.parse(tt(e,"utf-8"));return!n||typeof n!="object"||Array.isArray(n)?[]:B(n,t)}catch{return[]}}function br(e,t){if(!et(e))return{errors:[`${t}: file is missing`],warnings:[]};try{let n=JSON.parse(tt(e,"utf-8"));return ae(n,t)}catch(n){let r=n instanceof Error?n.message:String(n);return{errors:[`${t}: invalid JSON (${r})`],warnings:[]}}}function nt(e){if(e.length===0||e.every(n=>n==="unknown"))return"unknown";let t=e.filter(n=>n==="ready").length/e.length;return t>.9?"healthy":t>.5?"degraded":"error"}var Qt=/^[a-z0-9-]+$/;function rt(e){return Qt.test(e)}var Xt="Use lowercase letters, numbers, and hyphens only";function ot(e,t){return`${e} "${t}" is not valid. ${Xt}, e.g. "${e==="Resource name"?"my-service":"my-stack"}".`}function en(e){return e.trim()?rt(e)?{valid:!0}:{valid:!1,error:ot("Resource name",e)}:{valid:!1,error:"Resource name is required"}}function tn(e){return e.trim()?rt(e)?{valid:!0}:{valid:!1,error:ot("Stack name",e)}:{valid:!1,error:"Stack name is required"}}function _r(e){let t=e==="resource"?en:tn;return n=>{let r=t(n);return r.valid?!0:r.error??"Invalid name"}}function Or(e){return ie(z,e)?{valid:!0}:{valid:!1,error:`Invalid service. Must be one of: ${z.join(", ")}`}}function Cr(e){return Number.isInteger(e)&&e>0&&e<=65535}function Dr(e){return!e.includes("\0")&&!/[<>:"|?*]/.test(e)}function Fr(e,t="_"){return e.replace(/[^a-zA-Z0-9-]/g,t).substring(0,100)}function ie(e,t){return e.includes(t)}var sn=xe;function de(e,t=5,n=0){let r=[];if(n>t)return r;let o=st.readdirSync(e,{withFileTypes:!0});for(let s of o){let a=w(e,s.name);if(s.isDirectory()){if(an(s.name))continue;r.push(...de(a,t,n+1))}else s.isFile()&&s.name===sn&&r.push(a)}return r}function zr(e){return de(e)}function an(e){return ie(ve,e)||e.startsWith(".")}function cn(e){if(!e||typeof e!="object")return!1;let t=e,n=typeof t.runtime=="string"||typeof t.appType=="string"||typeof t.type=="string";return typeof t.appName=="string"&&n}var P=new Set;function qr(){P.clear()}var k=class extends Error{reason;constructor(t){super(t),this.reason=t,this.name="InvalidServiceJsonError"}};function ue(e){return e instanceof Error?e.message:String(e)}function un(e){let t;try{t=st.readFileSync(e,"utf-8")}catch(c){throw new k(`could not read file: ${ue(c)}`)}let n;try{n=JSON.parse(t)}catch(c){throw new k(`invalid JSON: ${ue(c)}`)}if(!cn(n))throw new k("missing required fields (appName, runtime or appType)");let r=se(n);if(r.length>0)throw new k(r.map(c=>`${c}: expected a string`).join("; "));let o=B(n,e);if(o.length>0)throw new k(o.join("; "));let s=n;for(let c of ae(n,e).warnings)P.has(c)||(P.add(c),console.warn(`\u26A0\uFE0F ${c}`));let a={...s,appType:s.appType||s.type},i=on(e);return{name:a.appName,path:i,configPath:e,config:a,stack:a.stack,port:a.port,type:a.appType}}function at(e){let t=de(e),n=[],r=[];for(let o of t)try{n.push(un(o))}catch(s){r.push({path:o,reason:s instanceof k?s.reason:ue(s)})}return{resources:n,problems:r}}function fn(e){for(let t of e){let n=`skipped ${t.path}: ${t.reason}`;P.has(n)||(P.add(n),console.warn(`\u26A0\uFE0F ${n}`))}}function it(e){let{resources:t,problems:n}=at(e);return fn(n),t}function U(){let e=T();if(!e)throw q.notInProject();return it(e)}function Kr(e){let t=e;if(!t){let n=T();if(!n)throw q.notInProject();t=at(n)}if(t.problems.length>0)throw new Error(t.problems.map(n=>`Invalid service.json at ${n.path}: ${n.reason}`).join(`
|
|
15
|
-
`));return t.resources}function Hr(e,t){let n=t??it(e);return pn(n)}function pn(e){let t=e||U(),n=new Set;for(let r of t)r.stack&&n.add(r.stack);return Array.from(n).sort()}function Jr(e=U()){let t=new Map;for(let r of e)if(r.stack){let o=t.get(r.stack);o?o.push(r):t.set(r.stack,[r])}let n=[];for(let[r,o]of t)n.push({name:r,description:Re(o.length,"resource"),resources:o,resourceCount:o.length});return n.sort((r,o)=>r.name.localeCompare(o.name))}function Yr(e,t){return(t??U()).filter(r=>r.stack===e)}function Zr(e,t){return(t??U()).some(r=>r.stack===e)}var le=5e3,fe=new j({ttlMs:le}),pe=new j({ttlMs:le}),I=Te(le);function Qr(){fe.clear(),pe.clear(),I.reset()}function dn(e,t){if(e==="Dockerfile"||e.startsWith("docker-compose"))return"docker";if(e==="Tiltfile"||e.endsWith(".star"))return"tilt";if(e==="vite.config.ts"||e==="tsconfig.json"||e===we)return"config";if(e==="schema.prisma"||e.includes("migration"))return"prisma";if(t){let n=t.split(`
|
|
16
|
-
`).slice(0,10).join(`
|
|
17
|
-
`);if(n.includes("GENERATED BY Flisk")||n.includes("AUTOGENERATED"))return"generated"}return"unknown"}function ln(e){let t=e.configPath;if(I.isValid()){let l=fe.get(t);if(l)return l}let n=e.path,r=ce(e.configPath),o=r.mtime.toISOString(),s=r.mtime.toISOString(),a=mn(n),i=O(w(n,"Dockerfile")),c=O(w(n,"Tiltfile")),d=O(w(n,Ee))||O(w(n,"docker-compose.yaml")),p=e.config?.appType,u=p||"backend";p||(e.name.includes("frontend")?u="frontend":(e.name.includes("sdk")||e.name.includes("lib")||e.name.includes("infra"))&&(u="library"));let h={name:e.name,stack:e.stack,type:u,port:e.config?.port,createdAt:o,lastModified:s,dependencies:e.config?.dependsOn??[],hasDockerfile:i,hasTiltfile:c,hasDockerCompose:d,autogeneratedFiles:a,status:"unknown"};return fe.set(t,h),I.markUpdated(),h}function mn(e){let t=[];for(let r of be){let o=w(e,r);if(O(o)){let s=ce(o),a=rn(o,"utf-8");t.push({name:r,path:o,type:dn(r,a),size:s.size,lastModified:s.mtime.toISOString()})}}let n=w(e,"prisma");if(O(n)){let r=nn(n);for(let o of r)if(o==="schema.prisma"||o.includes("migration")){let s=w(n,o),a=ce(s);t.push({name:`prisma/${o}`,path:s,type:"prisma",size:a.size,lastModified:a.mtime.toISOString()})}}return t.sort((r,o)=>r.name.localeCompare(o.name))}function Xr(e){let t=e.name;if(I.isValid()){let c=pe.get(t);if(c)return c}let n=e.resources.map(c=>ln(c)),r=n.map(c=>new Date(c.createdAt).getTime()),o=Math.min(...r),s=Math.max(...r),a=nt(n.map(c=>c.status)),i={name:e.name,resourceCount:n.length,createdAt:new Date(o).toISOString(),lastModified:new Date(s).toISOString(),resources:n,overallStatus:a};return pe.set(t,i),I.markUpdated(),i}export{Re as a,Sn as b,yn as c,$n as d,xn as e,En as f,kn as g,wn as h,vn as i,bn as j,J as k,Tn as l,An as m,Rn as n,_n as o,On as p,Cn as q,Dn as r,Fn as s,A as t,_e as u,Gn as v,R as w,zn as x,qn as y,Kn as z,X as A,Dt as B,Me as C,Ie as D,or as E,ee as F,jt as G,te as H,sr as I,ar as J,ir as K,hr as L,gr as M,Sr as N,yr as O,$r as P,Xe as Q,wr as R,ae as S,vr as T,br as U,nt as V,en as W,tn as X,_r as Y,Or as Z,Cr as _,Dr as $,Fr as aa,ie as ba,zr as ca,qr as da,at as ea,fn as fa,it as ga,U as ha,Kr as ia,Hr as ja,pn as ka,Jr as la,Yr as ma,Zr as na,Qr as oa,ln as pa,Xr as qa};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
|
|
2
|
-
import{randomUUID as F}from"node:crypto";import{existsSync as p,mkdirSync as g,readFileSync as y,statSync as M,writeFileSync as h}from"node:fs";import{homedir as P}from"node:os";import{join as a}from"node:path";import{spawnSync as _}from"node:child_process";import{existsSync as N,mkdirSync as w,mkdtempSync as C,readdirSync as $,renameSync as L,rmSync as v,statSync as j,writeFileSync as O}from"node:fs";import{tmpdir as D}from"node:os";import{join as c}from"node:path";function S(e,n){let r=C(c(D(),"flisk-ext-")),o=c(r,"bundle.tar.gz");O(o,e),w(n,{recursive:!0});let t=process.platform==="win32"?"tar.exe":"tar",i=_(t,["xzf",o,"-C",n,"--strip-components=1"],{stdio:"pipe",windowsHide:!0});if(i.status!==0){let s=c(r,"fallback");w(s,{recursive:!0});let f=_(t,["xzf",o,"-C",s],{stdio:"pipe",windowsHide:!0});if(f.status!==0)throw v(r,{recursive:!0,force:!0}),new Error(`tar extraction failed: ${f.stderr?.toString()||i.stderr?.toString()||"unknown error"}`);let l=$(s),[u]=l,m=l.length===1&&u!==void 0&&N(c(s,u))&&j(c(s,u)).isDirectory()?c(s,u):s;for(let d of $(m))L(c(m,d),c(n,d))}v(r,{recursive:!0,force:!0})}var U="https://tdk-extension-dist.oranguman.workers.dev/v1/premium/bundle.tar.gz",A=["playwright","c4-diagram","logging","agents-md","sablier","verdaccio"],z=720*60*1e3,k={"typescript/playwright_config.star":"engine/topologies/tilt/generators/typescript/playwright_config.star","generators/agents_md.star":"engine/topologies/tilt/generators/agents_md.star","c4_diagram.star":"engine/topologies/tilt/generators/c4_diagram.star","observability/logging.star":"engine/topologies/platform/observability/logging.star","generators/database_provisioner.star":"engine/topologies/tilt/generators/database_provisioner.star","generators/dependency_manifest.star":"engine/topologies/tilt/generators/dependency_manifest.star","generators/fixed_frontend_tsconfig.star":"engine/topologies/tilt/generators/typescript/fixed_frontend_tsconfig.star","synthetic_monitor.star":"engine/resources/synthetic_monitor.star","synthetic-monitor-topology.star":"engine/topologies/platform/services/synthetic-monitor.star","database-management-service.yaml":"platform/services/platform/database-management/service.yaml","networking/sablier_container_cycle.star":"engine/topologies/platform/docker/networking/sablier_container_cycle.star","registries/verdaccio_loader.star":"engine/topologies/platform/registries/verdaccio_loader.star"};function I(){return process.env.FLISK_LICENSE_KEY?.trim()||null}function R(){return process.env.FLISK_PREMIUM_ENDPOINT?.trim()||U}function x(e){let n=a(e,".flisk",".project-id");if(p(n))return y(n,"utf-8").trim();let r=F();return g(a(e,".flisk"),{recursive:!0}),h(n,`${r}
|
|
3
|
-
`),r}function B(e){let n=e.replace(/[^a-zA-Z0-9_-]/g,"_");return a(P(),".flisk","cache",`premium-${n}`,"premium.tar.gz")}function T(e){return p(e)?Date.now()-M(e).mtimeMs<z:!1}async function E(e,n,r){let o=`${R()}?resource=${encodeURIComponent(n)}&projectId=${encodeURIComponent(r)}`,t=await fetch(o,{headers:{Authorization:`Bearer ${e}`}});return t.status!==401?t:(await t.arrayBuffer().catch(()=>{}),fetch(`${o}&key=${encodeURIComponent(e)}`))}async function H(e,n){let r=[];for(let o of A){let t;try{t=await E(e,o,n)}catch(i){return console.warn(`\u26A0\uFE0F Premium fetch failed (network error): ${i.message}`),null}if(t.ok){let i=Buffer.from(await t.arrayBuffer());return console.info(`\u{1F50E} Premium entitlement probe: granted resource=${o} (HTTP ${t.status}); prior denials=${r.join(", ")||"none"}`),console.info(`\u{1F50E} Premium bundle download: ${i.byteLength} bytes`),i}if(t.status===401||t.status===403){r.push(`${o}=${t.status}`);continue}return console.warn(`\u26A0\uFE0F Premium fetch failed: ${o} returned HTTP ${t.status}; prior entitlement probes: ${r.join(", ")||"none"}`),null}return console.warn(`\u26A0\uFE0F Premium entitlement probes denied: ${r.join(", ")}`),null}async function re(e,n){let r=I();if(!r)return!1;let o=B(r);if(T(o))console.info("\u{1F50E} Premium bundle cache: hit (cached bundle reused)");else{console.info("\u{1F50E} Premium bundle cache: miss; requesting bundle from distribution service");let t=x(e),i=await H(r,t);if(!i)return console.warn("\u26A0\uFE0F No premium resources unlocked for this key - using free tier only."),!1;g(a(o,".."),{recursive:!0}),h(o,i)}try{let t=a(o,"..","extracted");g(t,{recursive:!0}),S(y(o),t);let i=0,s=[];for(let[l,u]of Object.entries(k)){let m=a(t,l);if(!p(m)){s.push(l);continue}let d=a(n,u);g(a(d,".."),{recursive:!0}),h(d,y(m)),i++}let f=a(t,"networking/sablier_container_cycle.star");if(console.info(`\u{1F50E} Premium bundle contents: mapped=${i}/${Object.keys(k).length}; sablier_overlay=${p(f)?"present":"MISSING"}`),s.length>0&&console.info(`\u{1F50E} Premium bundle missing mapped files: ${s.join(", ")}`),!p(f)&&process.env.FLISK_PREMIUM_DIAGNOSTICS==="1"){let l=await G(e);console.info(`\u{1F50E} Sablier entitlement check: ${l?"granted":"not confirmed"}; compare with sablier_overlay above to distinguish license access from bundle contents`)}return i>0?(console.log(`\u2713 Premium resources unlocked (${i} file${i===1?"":"s"})`),!0):!1}catch(t){return console.warn(`\u26A0\uFE0F Failed to apply premium overlay: ${t.message}`),!1}}function K(e,n){let r=e.replace(/[^a-zA-Z0-9_-]/g,"_");return a(P(),".flisk","cache",`premium-${r}`,`${n}-access.json`)}async function b(e,n){let r=I();if(!r)return!1;let o=K(r,n);if(T(o))try{let s=JSON.parse(y(o,"utf-8"));return console.info(`\u{1F50E} ${n} entitlement probe: cache=${s.granted===!0?"granted":"denied"}`),s.granted===!0}catch{}let t=x(e),i=!1;try{let s=await E(r,n,t);i=s.ok,console.info(`\u{1F50E} ${n} entitlement probe: HTTP ${s.status} (${i?"granted":"denied"})`),s.body&&await s.arrayBuffer().catch(()=>{})}catch(s){return console.warn(`\u26A0\uFE0F ${n} license check failed (network error): ${s.message}`),!1}try{g(a(o,".."),{recursive:!0}),h(o,JSON.stringify({granted:i,checked:new Date().toISOString()}))}catch{}return i}async function ne(e){return b(e,"verdaccio")}async function oe(e){return b(e,"ddd")}async function G(e){return b(e,"sablier")}export{S as a,re as b,ne as c,oe as d,G as e};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
|
|
2
|
-
import{E as x,a as h,ga as j,ha as D,t as _}from"./chunk-5F7YP5IR.js";import{C as L,j as N,m as w,n as A,t as F,x as T}from"./chunk-YNCBBJ4V.js";import{execFileSync as B}from"node:child_process";import{existsSync as de,mkdirSync as le,readFileSync as K,realpathSync as fe,writeFileSync as pe}from"node:fs";import{join as b,resolve as he,sep as me}from"node:path";import{createServer as ie}from"node:net";import{connect as oe}from"node:net";function U(e,t=500){return new Promise(r=>{let s=oe({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 ae={ingressHttp:{start:8080,end:8180},ingressHttps:{start:8443,end:8543},postgres:{start:15432,end:15532}},v={ingressHttp:"FLISK_HTTP_PORT",ingressHttps:"FLISK_HTTPS_PORT",postgres:"FLISK_POSTGRES_PORT"},H={ingressHttp:80,ingressHttps:443,postgres:5432},E={ingressHttp:H.ingressHttp,ingressHttps:H.ingressHttps};function ce(e,t){return e==="EACCES"&&t==="darwin"}async function O(e){return await U(e)?!1:new Promise(t=>{let r=ie();r.once("error",s=>{t(ce(s.code,process.platform))}),r.listen(e,"127.0.0.1",()=>r.close(()=>t(!0)))})}function ue(e,t){let r=Number(t);if(!Number.isInteger(r)||r<1||r>65535)throw new Error(`${e} must be an integer between 1 and 65535 (received ${JSON.stringify(t)})`);return r}async function R(e={}){let t=e.env??process.env,r=e.isAvailable??O,s={ingressHttp:!1,ingressHttps:!1,postgres:!1},n={ingressHttp:"",ingressHttps:"",postgres:""},o={explicit:s},a=new Set;for(let c of["ingressHttp","ingressHttps","postgres"]){let u=t[v[c]],i=u!==void 0&&u.trim()!=="",d=e.ranges?.[c]??ae[c],l=E[c],f=i?[ue(v[c],u)]:[...l===void 0?[]:[l],...Array.from({length:d.end-d.start+1},(g,k)=>d.start+k)],m;for(let g of f)if(!a.has(g)){if(await r(g)){m=g;break}if(i)throw new Error(`${v[c]}=${g} is already in use. Choose a free host port and retry.`)}if(m===void 0)throw new Error(`No available host port in ${d.start}-${d.end} for ${c}. Set ${v[c]} to a free port and retry.`);a.add(m),o[c]=m,s[c]=i,n[c]=i?"explicit override":m===l?"requested port is free":`selected from fallback range ${d.start}-${d.end}`}return{...o,requested:{...H},reason:n}}function Ve(e){return`Host ports: HTTP ${e.ingressHttp}, HTTPS ${e.ingressHttps}, Postgres ${e.postgres}`}var G=b(".flisk",".flisk-out","host-ports.json");function ge(e,t,r){return e.split(`
|
|
3
|
-
`).some(s=>{let[n="",o=""]=s.split("|"),a=n.toLowerCase(),c=t.toLowerCase();return(a.startsWith(`${c}_`)||a.startsWith(`${c}-`))&&o.includes(`:${r}->`)})}function V(e){let t=b(e,G);if(!de(t))return null;try{let r=JSON.parse(K(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 Ye(e,t){let r=b(e,G);le(b(e,".flisk",".flisk-out"),{recursive:!0}),pe(r,`${JSON.stringify(t,null,2)}
|
|
4
|
-
`,{encoding:"utf-8",mode:384})}function Qe(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 ke="com.docker.compose.project.working_dir";function Pe(e,t,r){let s=new Set([he(t)]);try{s.add(fe(t))}catch{}return e.split(`
|
|
5
|
-
`).some(n=>{let[,o="",a=""]=n.split("|");return!a||!o.includes(`:${r}->`)?!1:[...s].some(c=>a===c||a.startsWith(`${c}${me}`))})}function Xe(e,t,r=()=>B("docker",["ps","--format",`{{.Names}}|{{.Ports}}|{{.Label "${ke}"}}`],{encoding:"utf-8",timeout:5e3})){let s=V(e);if(!s||s.ingressHttp===t)return t;try{if(Pe(r(),e,s.ingressHttp))return s.ingressHttp}catch{}return t}async function et(e,t={}){let r=V(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(K(b(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=B("docker",["ps","--format","{{.Names}}|{{.Ports}}"],{encoding:"utf-8",timeout:5e3})}catch{}let a=i=>ge(o,n,i),c=t.isPortFree??O,u=async i=>await c(i)||a(i);if(r&&!s){for(let i of[r.ingressHttp,r.ingressHttps,r.postgres])if(!await u(i))return R({isAvailable:u});for(let[i,d]of Object.entries(E)){let l=r[i];if(d!==void 0&&l!==d&&await u(d))return R({isAvailable:u})}return r}return R({isAvailable:u})}import{execFileSync as Q,execSync as S}from"node:child_process";import{existsSync as I,readdirSync as Se,readFileSync as C}from"node:fs";import{createServer as Te}from"node:net";import{join as P}from"node:path";function W(e,t){return e==="pending"||e==="in_progress"||e==="none"||t==="pending"||t==="none"}var J="container is running, but its health check is failing";function M(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,z=3e3,be="http://localhost:4873";function X(e){return`'${e.replace(/'/g,"'\\''")}'`}function $(e,t,r,s,n){return process.platform==="win32"&&e===S?Q(L(t)??t,r,{...n,windowsHide:!0}):e(s,n)}var ye=[80,443];function $e(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 a=o.indexOf(" "),c=a>=0?o.slice(0,a):o,u=a>=0?o.slice(a+1):"",i=[];for(let d of r)u.split(/[\s,]+/).some(f=>f.startsWith(`${d}->`)||f.includes(`:${d}->`))&&i.push(d);i.length>0&&s.push({name:c,ports:u,publishedPorts:i})}return s}function ee(e,t){let r=e.toLowerCase(),s=t.toLowerCase();return r===`${s}_traefik`||r.startsWith(`${s}_traefik`)}function ve(e,t){return e.filter(r=>!ee(r.name,t))}function Re(e){try{let t=e??D();return new Set(t.filter(r=>r.config?.sablier?.enable&&r.config?.sablier?.deferStart).map(r=>r.name))}catch{return new Set}}function _e(e,t=new Set){let s=JSON.parse(e).items??[],n=[],o=0,a=0,c=0;for(let u of s){let i=u.metadata?.name??"unknown",d=u.status?.updateStatus??"",l=M(u.status),f=l==="error"&&u.status?.runtimeStatus==="ok",g=(u.status?.buildHistory?.[0]?.error??"").trim()||(f?J:"");if(d==="error"||l==="error"){n.push({name:i,updateStatus:d,runtimeStatus:l,error:g.replace(/\s+/g," ").slice(0,800)});continue}if(d==="ok"&&(l==="ok"||l==="not_applicable")){c+=1;continue}i!=="(Tiltfile)"&&W(d,l)&&(t.has(i)?a+=1:o+=1)}return{failures:n,pendingCount:o,deferredCount:a,okCount:c,total:s.length}}var xe=/failed to resolve source metadata for docker\.io\/library\/([A-Za-z0-9._-]+-l[1-4](?:-[a-z]+)*)(?::[^\s:]+)?:/i;function te(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(c=>c[1]);if(s.length>0){let c=[...new Set(s)],u=c.slice(0,4).join(", "),i=c.length>4?` (+${c.length-4} more)`:"";return`private registry ConnectionRefused for ${u}${i} \u2014 Verdaccio (:4873) is down or unreachable from the build`}let n=t.match(xe);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,a=t.match(/\bup\s+-d\s+--no-build\s+([A-Za-z0-9._-]+)/i)?.[1];if(o||a||/docker compose .*\bup\s+-d\s+--no-build\b/i.test(t)){let c=o??`${a??"service"}:dev`,u=a?` for ${a}`:"";return`compose run failed because image is missing (${c})${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 q(e){return/ConnectionRefused downloading package manifest|Verdaccio|private registry|dependency install failed during ImageBuild|install-deps\.sh|bun install/i.test(e)}function He(e=T()??process.cwd()){let t=P(e,".flisk",w);if(!I(t))return!1;try{let r=JSON.parse(C(t,"utf-8"));return r.optional_infra?.verdaccio===!0||Object.values(r.phases??{}).some(s=>(s.enabledStacks??[]).includes("verdaccio"))}catch{return!1}}function re(e){for(let t of[P(e,".npmrc"),P(e,A)])if(I(t))try{let r=C(t,"utf-8");if(/:4873\b/.test(r)||/verdaccio/i.test(r))return!0}catch{}return!1}function Ee(e=T()??process.cwd()){return He(e)||re(e)}function mt(e=S,t=T()??process.cwd(),r=process.env.VERDACCIO_URL??process.env.NPM_REGISTRY_URL??be,s=!0){if(!s&&!re(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(!Ee(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 c=$(e,"docker",["ps","--format","{{.Names}}"],"docker ps --format '{{.Names}}'",{stdio:"pipe",encoding:"utf-8",timeout:y});n=/verdaccio/i.test(c)}catch{}let o=!1,a="";try{let c=process.platform==="win32"?Q("curl.exe",["-fsS","-o","NUL","-w","%{http_code}","--max-time","2",r],{stdio:"pipe",encoding:"utf-8",timeout:z+1e3,windowsHide:!0}).trim():e(`curl -fsS -o /dev/null -w '%{http_code}' --max-time 2 ${X(r)}`,{stdio:"pipe",encoding:"utf-8",timeout:z+1e3}).trim();o=/^[23]\d\d$/.test(c),a=`HTTP ${c}`}catch(c){a=c instanceof Error?c.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 (${a}). 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 gt(e=S,t=x(),r=ye){let s=$e(t),n="";try{n=$(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),a=ve(o,s);if(a.length===0){let u=o.filter(i=>ee(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
|
-
${a.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 ${a[0]?.name}\`, or shut down the other Flisk/Tilt project using that Traefik. Then re-run \`flisk up\`.`}}function Z(e,t){return new Promise(r=>{let s=Te();s.once("error",n=>r(n.code==="EADDRINUSE"?"in-use":"unknown")),s.once("listening",()=>s.close(()=>r("free"))),s.listen(e,t)})}async function kt(e){for(let t=0;t<2;t++){let r=await Z(e,"0.0.0.0");if(r==="unknown")return r;if(r==="free"){let s=await Z(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 Oe(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 Pt(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} (${Oe(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 St(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 Tt(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 bt(e=S){let t="";try{t=$(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=_e(t,Re())}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=Ce(r.failures),o=s.slice(0,20),a=s.length-o.length,c=o.map(p=>({failure:p,why:Ae(p,e)})),u=c.map(({failure:p,why:ne})=>`${p.name}: ${ne}`).join(`
|
|
17
|
-
`),i=a>0?`
|
|
18
|
-
\u2026and ${h(a,"more failed resource")}`:"",d=r.pendingCount>0?`
|
|
19
|
-
${h(r.pendingCount,"resource")} still pending/not started \u2014 often blocked by the failures above.`:"",l=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=>q(p.error)||q(te(p.error))),g=c.some(({why:p})=>/Kafka broker unreachable|kafka:9092/i.test(p)),k="Open the Tilt UI URL printed by flisk up (default port "+F.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}${d}${l}`,fix:k}}var Ie=/^(traefik|postgres|nats|infisical|verdaccio|proxy)([.-]|$)/i;function Y(e){return Ie.test(e)}function Ce(e){return[...e].sort((t,r)=>{let s=Y(t.name)?0:1,n=Y(r.name)?0:1;return s!==n?s-n:t.name.localeCompare(r.name)})}function Ne(e,t=S,r=x()){try{let s=$(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 a=$(t,"docker",["logs","--tail","120",o],`docker logs --tail 120 ${X(o)} 2>&1`,{stdio:"pipe",encoding:"utf-8",timeout:y});if(/getaddrinfo ENOTFOUND/i.test(a)&&/kafka:9092/i.test(a))return"runtime crash: Kafka broker unreachable (getaddrinfo ENOTFOUND kafka:9092)";if(/ECONNREFUSED/i.test(a)&&/kafka/i.test(a))return"runtime crash: Kafka connection refused";let c=a.match(/ConnectionRefused downloading package manifest (@[A-Za-z0-9._/-]+)/i);if(c?.[1])return`runtime/build log: private registry ConnectionRefused for ${c[1]}`;if(/ZodError/i.test(a)){let i=[...a.matchAll(/"path"\s*:\s*\[\s*"([^"]+)"\s*\]/g)].map(l=>l[1]),d=[...new Set(i)].slice(0,6);return d.length>0?`runtime crash: ZodError missing required config/env: ${d.join(", ")}`:"runtime crash: ZodError during config/env validation"}let u=a.match(/error:\s+Failed to [^:\n]+[^\n]{0,120}/i)?.[0]??a.match(/Failed to (?:start|initialize) [^\n]{0,120}/i)?.[0]??a.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 Ae(e,t=S){return e.error?te(e.error):e.runtimeStatus==="error"?Ne(e.name,t)??"runtime error (container crashed or unhealthy \u2014 check Tilt/docker logs)":e.updateStatus||e.runtimeStatus||"unknown error"}var Fe=/\.(ts|tsx|mts|js|mjs|cjs)$/,Le=new Set(["node_modules","dist",N,"tests","__tests__"]);function se(e){let t=[];for(let r of Se(e,{withFileTypes:!0}))r.isDirectory()?Le.has(r.name)||t.push(...se(P(e,r.name))):Fe.test(r.name)&&!/\.(test|spec)\./.test(r.name)&&t.push(P(e,r.name));return t}function je(e){let t=e?.healthCheckPath||"/health";return{container:t,traefik:e?.traefik?.healthCheck||t}}function De(e){let t=[];for(let r of e){if(!_(r.config?.appType))continue;let s=P(r.path,"src");if(!I(s))continue;let n=se(s);if(n.length===0)continue;let o=n.map(i=>C(i,"utf-8")),{container:a,traefik:c}=je(r.config),u=a===c?[{path:a,usedBy:"container and Traefik healthchecks"}]:[{path:a,usedBy:"container healthcheck"},{path:c,usedBy:"Traefik healthcheck"}];for(let{path:i,usedBy:d}of u){let l=["'",'"',"`"].map(f=>`${f}${i}${f}`);o.some(f=>l.some(m=>f.includes(m)))||t.push({name:r.name,healthPath:i,usedBy:d})}}return t}function yt(e=T()??process.cwd()){let t=[];try{t=j(e)}catch{return{name:"Health Routes",didPass:!0,isSkipped:!0,message:"Could not read services - skipped health route check"}}let r=t.filter(o=>_(o.config?.appType));if(r.length===0)return{name:"Health Routes",didPass:!0,isSkipped:!0,message:"No backend services to check"};let s=De(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{R as a,Ve as b,V as c,Ye as d,Qe as e,Xe as f,et as g,W as h,M as i,$e as j,we as k,Re as l,_e as m,te as n,He as o,mt as p,gt as q,kt as r,Pt as s,St as t,Tt as u,bt as v,yt as w};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
|
|
2
|
-
var s={demo:{repo:"https://github.com/flisk-sh/tdk-restaurant-example.git",description:"The demo stack: restaurant ops with reservations, kitchen and floor control",fixedDir:"flisk-demo"},restaurant:{repo:"https://github.com/flisk-sh/tdk-restaurant-example.git",description:"Restaurant ops: reservations, kitchen, floor control (Hono + Vite + Bun)"},saas:{repo:"https://github.com/flisk-sh/tdk-saas-starter.git",description:"SaaS starter: account dashboard and a working checkout button (Hono + Vite + Bun)"},erp:{repo:"https://github.com/flisk-sh/tdk-erp-system.git",description:"Enterprise ERP: 100 microservices across 7 business domains"},"user-management":{repo:"https://github.com/flisk-sh/tdk-user-management.git",description:"User/auth management services"},ecommerce:{repo:"https://github.com/flisk-sh/tdk-ecommerce-example.git",description:"Vue 3 storefront and Hono catalog API (needs Flisk 1.3.75+ for --framework vue)"},example:{repo:"https://github.com/flisk-sh/tdk-example.git",bundledPath:"examples/tdk-example",description:"Hono + Postgres + NATS worker + Vite example with a routed write path"},"agent-stack":{repo:"https://github.com/flisk-sh/tdk-agent-stack.git",description:"AI agent stack: Bun agent + MCP tool server + Postgres + NATS"}};function r(e){let t=e[2];if(!(!t||t.startsWith("-")))return t in s?t:void 0}export{s as a,r as b};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
|
|
2
|
-
import{A as d,B as e,C as f,D as g,E as h,F as i,G as j,x as a,y as b,z as c}from"./chunk-43XWL2PB.js";import"./chunk-MWOVYIBB.js";import"./chunk-IGN5UC3P.js";import"./chunk-K6SOCO6V.js";import"./chunk-3J6XI3NX.js";import"./chunk-YHYRGWUH.js";import"./chunk-3XODDLRJ.js";import"./chunk-53L2JN7G.js";import"./chunk-5F7YP5IR.js";import"./chunk-YNCBBJ4V.js";import"./chunk-KJZUBHLO.js";export{c as MACHINE_CHECK_IDS,a as RUNTIME_CHECK_IDS,b as SCAFFOLD_CHECK_IDS,h as assertMachineReadyOrExit,i as detectRuntimePrerequisites,g as formatColdPreflight,j as formatRuntimeNextSteps,d as nodeTooOld,e as requireVerifiedDockerVersions,f as runColdPreflight};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{createRequire as __fliskRequire}from'node:module';const require=__fliskRequire(import.meta.url);
|
|
2
|
-
import{g as a,h as b,i as c,j as d}from"./chunk-ETKUVKJ2.js";import"./chunk-YL56J2WX.js";import"./chunk-MWOVYIBB.js";import"./chunk-K6SOCO6V.js";import"./chunk-53L2JN7G.js";import"./chunk-5F7YP5IR.js";import"./chunk-YNCBBJ4V.js";import"./chunk-KJZUBHLO.js";export{c as cloneProjectTemplate,a as enableDiscoveredStacks,d as projectCommand,b as templateTargetDir};
|