@flisk-sh/flisk 1.3.204 → 1.3.206
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 +26 -0
- package/cli/dist/cli.js +251 -90
- package/cli/dist/commands/doctor.js +29 -15
- package/cli/dist/commands/project.js +108 -60
- package/cli/dist/commands/resource.js +3 -1
- package/cli/dist/commands/up.js +8 -5
- package/cli/dist/generator/template-engine.js +17 -9
- package/cli/dist/utils/cli-command.js +3 -1
- package/cli/dist/utils/colima.js +23 -4
- package/cli/dist/utils/demo-stage.js +315 -0
- package/cli/dist/utils/doctor-fix.js +35 -9
- package/cli/dist/utils/machine-output.js +27 -0
- package/cli/dist/utils/native-windows.js +20 -0
- package/cli/dist/utils/one-command.js +15 -8
- package/cli/dist/utils/project-templates.js +1 -0
- package/cli/dist-bundle/chunk-3QQGL3NQ.js +35 -0
- package/cli/dist-bundle/chunk-4W6OXDLK.js +17 -0
- package/cli/dist-bundle/chunk-53M5D4KE.js +2 -0
- package/cli/dist-bundle/{chunk-BS6G2SLM.js → chunk-5CFVN3W3.js} +1 -1
- package/cli/dist-bundle/{chunk-RFHMXJTK.js → chunk-6Y6G7PSD.js} +1 -1
- package/cli/dist-bundle/chunk-7C5VA6CW.js +57 -0
- package/cli/dist-bundle/chunk-D2BXXJDM.js +7 -0
- package/cli/dist-bundle/chunk-GANRXKBM.js +2 -0
- package/cli/dist-bundle/chunk-GIMHTZNR.js +2 -0
- package/cli/dist-bundle/chunk-GOEBYLFN.js +2 -0
- package/cli/dist-bundle/chunk-LI3BXAX5.js +2 -0
- package/cli/dist-bundle/{chunk-WMF4AFAE.js → chunk-NCEK46NX.js} +10 -10
- package/cli/dist-bundle/chunk-ODVBKN6S.js +2 -0
- package/cli/dist-bundle/{chunk-Z6UD7UZH.js → chunk-PHI5AT3H.js} +2 -2
- package/cli/dist-bundle/chunk-XSPMLWAE.js +10 -0
- package/cli/dist-bundle/chunk-YZRPX76N.js +2 -0
- package/cli/dist-bundle/cli.js +269 -267
- package/cli/dist-bundle/cold-preflight-4I24DQLW.js +2 -0
- package/cli/dist-bundle/{colima-4ID4BGHC.js → colima-SVZX2UML.js} +1 -1
- package/cli/dist-bundle/demo-stage-EOMANLAD.js +7 -0
- package/cli/dist-bundle/native-windows-X5XVLFJS.js +2 -0
- package/cli/dist-bundle/one-command-P6XVAXWV.js +5 -0
- package/cli/dist-bundle/open-6374RNL6.js +2 -0
- package/cli/dist-bundle/project-IRWFRXWA.js +2 -0
- package/cli/dist-bundle/project-templates-JDRE7AVL.js +2 -0
- package/cli/dist-bundle/services-VIIBMWD4.js +2 -0
- package/cli/dist-bundle/tilt-port-owner-AN3ITRTR.js +2 -0
- package/cli/dist-bundle/url-actions-D6ROTHZG.js +2 -0
- package/cli/package.json +4 -4
- package/engine/assets/docker/wake-gateway/Dockerfile +1 -1
- package/engine/topologies/platform/docker/compose/compose.star +20 -18
- package/engine/topologies/platform/docker/compose/unsafe_value.star +23 -0
- package/engine/topologies/platform/docker/networking/traefik.star +19 -0
- package/package.json +2 -2
- package/cli/dist-bundle/chunk-CBFVK3TF.js +0 -21
- package/cli/dist-bundle/chunk-CF46CD6R.js +0 -6
- package/cli/dist-bundle/chunk-DTIHDMED.js +0 -5
- package/cli/dist-bundle/chunk-EPBYRJE3.js +0 -2
- package/cli/dist-bundle/chunk-GD5676UE.js +0 -52
- package/cli/dist-bundle/chunk-MKJNQTIN.js +0 -2
- package/cli/dist-bundle/chunk-QSPFSZCS.js +0 -34
- package/cli/dist-bundle/chunk-ZVGY7COV.js +0 -4
- package/cli/dist-bundle/cold-preflight-FXOZ5SR5.js +0 -2
- package/cli/dist-bundle/one-command-YP6L6MMM.js +0 -5
- package/cli/dist-bundle/open-UQ6DF3XN.js +0 -2
- package/cli/dist-bundle/project-GTYHCCFG.js +0 -2
- package/cli/dist-bundle/spinner-YLB6FYQH.js +0 -2
- package/cli/dist-bundle/tilt-port-owner-KLNX2ZI2.js +0 -2
- /package/cli/dist-bundle/{devtools-ZUHXW33W.js → devtools-MGITLOWZ.js} +0 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(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-7C5VA6CW.js";import"./chunk-NCEK46NX.js";import"./chunk-5CFVN3W3.js";import"./chunk-42IVF3YT.js";import"./chunk-YZRPX76N.js";import"./chunk-PHI5AT3H.js";import"./chunk-GANRXKBM.js";import"./chunk-LI3BXAX5.js";import"./chunk-4W6OXDLK.js";import"./chunk-XSPMLWAE.js";import"./chunk-6EA4DGCY.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 +1,2 @@
|
|
|
1
1
|
import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
|
|
2
|
-
import{a,b,c,d}from"./chunk-
|
|
2
|
+
import{a,b,c,d}from"./chunk-YZRPX76N.js";import"./chunk-6EA4DGCY.js";export{b as checkColima,a as isColimaDocker,d as nativeLimaPath,c as planColimaRepair};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
|
|
2
|
+
import{b as R}from"./chunk-ODVBKN6S.js";import{b as c}from"./chunk-XSPMLWAE.js";import"./chunk-6EA4DGCY.js";var v=12,_=24,F={plain:e=>e,bold:c.bold,dim:c.gray,ok:c.green,warn:c.yellow,err:c.red},S={pending:"\u25CB",active:"\u25D0",done:"\u2714",failed:"\u2716"},j={pending:"dim",active:"warn",done:"ok",failed:"err"};function o(e){return R(String(e)).replace(/[\n\r\t]/g," ")}function g(e){if(!Number.isFinite(e)||e<0)return"0.0s";if(e<1e4)return`${(e/1e3).toFixed(1)}s`;if(e<6e4)return`${Math.round(e/1e3)}s`;let n=Math.floor(e/6e4),i=Math.round(e%6e4/1e3);return`${n}m ${i}s`}function $(e){return e.reduce((n,i)=>n+i.text.length,0)}function k(e,n){if(n<=0)return[];let i=[],l=0;for(let s of e){if(l>=n)break;let t=n-l;if(s.text.length<=t){i.push(s),l+=s.text.length;continue}i.push({...s,text:`${s.text.slice(0,Math.max(0,t-1))}\u2026`}),l=n}return i}function w(e,n){let i=k(e,n),l=n-$(i);return l<=0?i:[...i,{text:" ".repeat(l),style:"plain"}]}function M(e,n,i){let l=$(n),s=i-l-1;if(s<4)return w(k([...e,...n],i),i);let t=k(e,s),r=i-$(t)-l;return[...t,{text:" ".repeat(Math.max(1,r)),style:"plain"},...n]}function b(e){return[{text:` ${"\u2500".repeat(Math.max(0,e-2))}`,style:"dim"}]}function P(e,n){return M([{text:" ",style:"plain"},{text:S[e.status],style:j[e.status]},{text:" ",style:"plain"},{text:o(e.label),style:e.status==="pending"?"dim":"plain"}],e.elapsedMs===void 0?[]:[{text:g(e.elapsedMs),style:"dim"}],n)}function Y(e){let n=Math.max(0,e.servicesTotal);if(n===0)return"no services found";let l=[`${Math.min(Math.max(0,e.servicesReady),n)} of ${n} services ready`];return e.servicesBuilding>0&&l.push(`${e.servicesBuilding} building`),l.join(" \xB7 ")}function E(e,n=80){let i=Number.isFinite(n)&&n>0?n:80,l=Math.max(_,Math.min(i-1,78)),s=[],t=a=>s.push(w(a,l)),r=()=>t([]);if(e.done){t(M([{text:" ",style:"plain"},{text:"\u2714",style:"ok"},{text:" Your stack is running",style:"ok"}],[{text:g(e.elapsedMs),style:"dim"}],l)),t([{text:" ",style:"plain"},{text:o(e.subtitle),style:"dim"}]),r();for(let a of e.done.urls.slice(0,2))t([{text:" ",style:"plain"},{text:o(a),style:"plain"}]);r(),t(b(l)),t([{text:" ",style:"plain"},{text:o(e.done.summary),style:"plain"}]),t([{text:" ",style:"plain"},{text:o(e.done.hint),style:"dim"}]),r(),t([{text:" ",style:"plain"},{text:`flisk ${o(e.done.version)}`,style:"dim"}])}else if(e.failure){let a=e.phases.find(p=>p.status==="failed");t(M([{text:" ",style:"plain"},{text:"\u2716",style:"err"},{text:" ",style:"plain"},{text:o(a?.label??"The demo stopped"),style:"err"}],[{text:g(e.elapsedMs),style:"dim"}],l)),r(),t([{text:" ",style:"plain"},{text:o(e.failure.message),style:"plain"}]),e.failure.fix&&t([{text:" ",style:"plain"},{text:o(e.failure.fix),style:"dim"}]),r(),t(b(l)),e.detail&&t([{text:" ",style:"plain"},{text:o(e.detail),style:"dim"}]),e.failure.logPath&&t([{text:" ",style:"plain"},{text:`log: ${o(e.failure.logPath)}`,style:"dim"}])}else{t([{text:" ",style:"plain"},{text:o(e.title),style:"bold"}]),t([{text:" ",style:"plain"},{text:o(e.subtitle),style:"dim"}]),r();let a=e.phases.slice(0,4);for(let p of a)t(P(p,l));for(let p=a.length;p<4;p+=1)r();r(),t(b(l)),t([{text:" ",style:"plain"},{text:o(e.detail??""),style:"dim"}]),t(M([{text:" ",style:"plain"},{text:Y(e),style:"plain"}],[{text:g(e.elapsedMs),style:"dim"}],l))}for(;s.length<v;)s.push(w([],l));return s.slice(0,v)}function A(e){return e.map(n=>n.map(i=>i.text).join(""))}function D(e){return e.map(n=>F[n.style](n.text)).join("")}function H(e,n=process.stderr,i=Date.now){let l=n.isTTY===!0,s=i(),t={...e},r=!1,a="",p="",f,T=()=>{let u=!!(t.done||t.failure);return{...t,elapsedMs:u?t.elapsedMs:i()-s}},x=()=>{let u=T(),m=E(u,n.columns??80),y=A(m);if(!l){let h=y.join(`
|
|
3
|
+
`);if(h===p)return;p=h,n.write(`${y.filter(L=>L.trim()!=="").join(`
|
|
4
|
+
`)}
|
|
5
|
+
`);return}let d=y.join(`
|
|
6
|
+
`);if(!(d===a&&r)){a=d,r&&n.write(`\x1B[${v}A`);for(let h of m)n.write(`\r\x1B[2K${D(h)}
|
|
7
|
+
`);r=!0}};return l&&(x(),f=setInterval(x,200),f.unref?.()),{update(u){t={...t,...u,phases:u.phases??t.phases},x()},fail(u,m,y){t={...t,elapsedMs:i()-s,failure:{message:u,fix:m,logPath:y},phases:t.phases.map(d=>d.status==="active"?{...d,status:"failed"}:d)},x()},finish(u){t={...t,elapsedMs:i()-s,done:u},x()},stop(){f&&clearInterval(f),f=void 0}}}export{v as FRAME_ROWS,H as createDemoStage,g as formatElapsed,A as frameToPlain,E as renderDemoFrame,o as sanitizeCell,D as styleRow};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
|
|
2
|
+
import"./chunk-6EA4DGCY.js";import{spawn as d}from"node:child_process";import{readdirSync as p}from"node:fs";import{join as l}from"node:path";var m="Frontend URLs";function y(r){let i=r.split(`
|
|
3
|
+
`),t=i.findIndex(e=>e.includes(m));if(t!==-1)for(let e of i.slice(t+1)){let n=e.match(/^\s*-\s+\S+:\s+(https?:\/\/\S+)/);if(n)return n[1];if(e.trim()===""||e.includes("URLs:"))break}}function j(r,i,t=process.env,e=d){return new Promise(n=>{let o=e(process.execPath,[r,"project","--yes","--quiet"],{cwd:i,env:t,stdio:["ignore","pipe","pipe"]}),c="";o.stdout?.on("data",s=>{c+=String(s)}),o.stderr?.on("data",s=>{c+=String(s)}),o.on("error",s=>n({ok:!1,error:s.message,output:c})),o.on("close",s=>{if(s===0){n({ok:!0,output:c});return}let u=c.split(`
|
|
4
|
+
`).map(a=>a.trim()).filter(Boolean).pop();n({ok:!1,error:u??`the project setup failed (code ${s})`,output:c})})})}function h(r){for(let i of r.split(`
|
|
5
|
+
`)){let t=i.trim();if(t.startsWith("{"))try{let e=JSON.parse(t),o=(e.data??{}).ok===!0;return{ok:o,data:e.data??{},error:o?void 0:e.errors?.[0]?.message??"the stack did not come up",raw:r}}catch{}}}function P(r,i,t=process.env,e=d){return new Promise(n=>{let o=e(process.execPath,[r,"up","--json"],{cwd:i,env:t,stdio:["inherit","pipe","pipe"]}),c="",s=!1,u=a=>{s||(s=!0,o.unref?.(),n(a))};o.stdout?.on("data",a=>{c+=String(a);let f=h(c);f&&u(f)}),o.stderr?.on("data",a=>{c+=String(a)}),o.on("error",a=>u({ok:!1,error:a.message,raw:c})),o.on("close",a=>u({ok:!1,error:`the stack stopped before it was ready (code ${a})`,raw:c}))})}function R(r,i){if(!i(r))return r;for(let t=2;t<1e3;t+=1){let e=`${r}-${t}`;if(!i(e))return e}return r}function k(r,i=4){let t=[],e=(n,o)=>{if(o>i)return;let c;try{c=p(n,{withFileTypes:!0}).map(s=>s.name)}catch{return}c.includes("package.json")&&t.push(n);for(let s of p(n,{withFileTypes:!0}))!s.isDirectory()||s.name==="node_modules"||s.name.startsWith(".")||e(l(n,s.name),o+1)};return e(r,0),t}async function D(r,i=x){let t=[];for(let e of k(r)){let n=await i("bun",["install"],e);t.push({dir:e,ok:n===0})}return t}function x(r,i,t){return new Promise(e=>{let n=d(r,i,{cwd:t,stdio:"ignore"});n.on("error",()=>e(1)),n.on("close",o=>e(o??1))})}export{y as findFrontendUrl,k as findServiceDirs,j as initializeProject,D as installServiceDependencies,R as nextAvailableProjectDir,h as parseStackEnvelope,P as runStackQuiet};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
|
|
2
|
+
import{d as a,e as b,f as c,g as d,h as e,i as f}from"./chunk-D2BXXJDM.js";import"./chunk-GOEBYLFN.js";import"./chunk-PHI5AT3H.js";import"./chunk-GANRXKBM.js";import"./chunk-LI3BXAX5.js";import"./chunk-4W6OXDLK.js";import"./chunk-XSPMLWAE.js";import"./chunk-6EA4DGCY.js";export{d as findReadyFrontend,b as isFrontendReady,a as listFrontendTargets,f as openCommand,e as openFirstFrontend,c as pickReadyFrontend};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
|
|
2
|
+
import{g as a,h as b,i as c,j as d}from"./chunk-3QQGL3NQ.js";import"./chunk-GIMHTZNR.js";import"./chunk-NCEK46NX.js";import"./chunk-42IVF3YT.js";import"./chunk-LI3BXAX5.js";import"./chunk-4W6OXDLK.js";import"./chunk-XSPMLWAE.js";import"./chunk-6EA4DGCY.js";export{c as cloneProjectTemplate,a as enableDiscoveredStacks,d as projectCommand,b as templateTargetDir};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
|
|
2
|
+
import{ca as a,da as b,ea as c,fa as d,ga as e,ha as f,ia as g,ja as h,ka as i,la as j,ma as k,na as l,oa as m,pa as n,qa as o}from"./chunk-4W6OXDLK.js";import"./chunk-XSPMLWAE.js";import"./chunk-6EA4DGCY.js";export{m as clearMetadataCache,f as discoverResources,e as discoverResourcesFromRoot,g as discoverResourcesStrict,c as discoverResourcesWithProblems,a as discoverServiceManifestPaths,h as discoverStackNames,j as discoverStacks,i as getAllStacks,n as getResourceMetadata,k as getResourcesForStack,o as getStackMetadata,b as resetPrintedServiceWarnings,l as stackExists,d as warnAboutSkippedFiles};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
|
|
2
|
+
import{a,b,c}from"./chunk-6Y6G7PSD.js";import"./chunk-5CFVN3W3.js";import"./chunk-GANRXKBM.js";import"./chunk-LI3BXAX5.js";import"./chunk-4W6OXDLK.js";import"./chunk-XSPMLWAE.js";import"./chunk-6EA4DGCY.js";export{c as classifyTiltPorts,a as findTiltPortOwner,b as isForeignTilt};
|
package/cli/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tdk-cli-internal",
|
|
3
3
|
"private": true,
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.206",
|
|
5
5
|
"description": "Flisk CLI — start services on your machine.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"flisk",
|
|
@@ -61,9 +61,9 @@
|
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@biomejs/biome": "^2.5.13",
|
|
64
|
-
"@types/node": "^
|
|
64
|
+
"@types/node": "^26.6.5",
|
|
65
65
|
"@types/react": "^19.3.0",
|
|
66
|
-
"@vitest/coverage-v8": "
|
|
66
|
+
"@vitest/coverage-v8": "5.0.5",
|
|
67
67
|
"ajv": "^8.17.1",
|
|
68
68
|
"chalk": "^6.0.1",
|
|
69
69
|
"esbuild": "^0.28.2",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"react-devtools-core": "^8.0.0",
|
|
74
74
|
"typescript": "^7.0.2",
|
|
75
75
|
"vite": "^8.3.3",
|
|
76
|
-
"vitest": "
|
|
76
|
+
"vitest": "5.0.5"
|
|
77
77
|
},
|
|
78
78
|
"engines": {
|
|
79
79
|
"node": ">=22.12.0"
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# documented `tilt trigger` command rather than depending on Tilt's
|
|
8
8
|
# undocumented internal HTTP API).
|
|
9
9
|
|
|
10
|
-
FROM oven/bun:1.3
|
|
10
|
+
FROM oven/bun:1.4.3-alpine@sha256:629e17411f1f129dbec3af78d5af9c9f2a937435c80349437206c6b0b7422373 AS base
|
|
11
11
|
|
|
12
12
|
# Pin to the same Tilt version this workspace runs (v0.37.7) so `tilt trigger`
|
|
13
13
|
# talks the same protocol as the real daemon it's connecting to. Installed
|
|
@@ -20,6 +20,7 @@ OUTPUT = struct(AUTOGENERATED_FOLDER = ".autogenerated")
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
load("./compose_helpers.star", "compose_build_config")
|
|
23
|
+
load("./unsafe_value.star", "reject_unsafe_value")
|
|
23
24
|
load("../networking/traefik.star", "get_frontend_traefik_labels", "get_backend_traefik_labels")
|
|
24
25
|
load("../networking/api_path_constants.star", "get_api_path_for_domain", "get_frontend_base_path")
|
|
25
26
|
load("../secrets/infisical.star", "get_infisical_environment_vars")
|
|
@@ -80,7 +81,7 @@ def generate_frontend_compose(resource_path, resource_name, res, manifest=None):
|
|
|
80
81
|
"""Generate frontend docker-compose entry with Traefik routing."""
|
|
81
82
|
res_name = res['name']
|
|
82
83
|
image_name = PlatformDockerConstants.app_image_name(resource_name, res_name)
|
|
83
|
-
stack = manifest.get('stack', resource_name) if manifest else resource_name
|
|
84
|
+
stack = reject_unsafe_value(manifest.get('stack', resource_name) if manifest else resource_name, 'stack')
|
|
84
85
|
|
|
85
86
|
target_path = res.get('target_path', manifest.get('target_path', '/usr/share/nginx/html'))
|
|
86
87
|
use_nginx = 'nginx' in target_path or target_path == '/usr/share/nginx/html'
|
|
@@ -90,16 +91,16 @@ def generate_frontend_compose(resource_path, resource_name, res, manifest=None):
|
|
|
90
91
|
# healthcheck probe a port nothing listens on, which left the container marked
|
|
91
92
|
# unhealthy -- and Traefik's Docker provider skips unhealthy containers, so the
|
|
92
93
|
# router was never registered and every request 404'd.
|
|
93
|
-
port = NGINX_CONTAINER_PORT if use_nginx else manifest.get('port', BASE_PORT_FRONTEND)
|
|
94
|
+
port = NGINX_CONTAINER_PORT if use_nginx else reject_unsafe_value(manifest.get('port', BASE_PORT_FRONTEND), 'port')
|
|
94
95
|
|
|
95
96
|
# Base path for routing on {project}.localhost. Shared with the Vite config and
|
|
96
97
|
# PUBLIC_URL generators -- see get_frontend_base_path for why they must agree.
|
|
97
|
-
base_path = get_frontend_base_path(manifest, res_name)
|
|
98
|
+
base_path = reject_unsafe_value(get_frontend_base_path(manifest, res_name), 'basePath')
|
|
98
99
|
|
|
99
100
|
traefik_cfg = manifest.get('traefik', {}) if manifest else {}
|
|
100
|
-
traefik_host = traefik_cfg.get('host')
|
|
101
|
+
traefik_host = reject_unsafe_value(traefik_cfg.get('host'), 'traefik.host')
|
|
101
102
|
# Use custom dockerfile from manifest if specified, otherwise use autogenerated default
|
|
102
|
-
dockerfile_path = res.get('dockerfile', OUTPUT.AUTOGENERATED_FOLDER + '/Dockerfile.app.autogenerated')
|
|
103
|
+
dockerfile_path = reject_unsafe_value(res.get('dockerfile', OUTPUT.AUTOGENERATED_FOLDER + '/Dockerfile.app.autogenerated'), 'dockerfile')
|
|
103
104
|
# Handle flat service structure (e.g., services/product/identity-management-frontend) vs nested (services/product/domain/service)
|
|
104
105
|
# Detect flat structure: services/product/{service} (3 path parts after root)
|
|
105
106
|
# vs nested: services/product/{domain}/{service} (4+ path parts)
|
|
@@ -162,7 +163,7 @@ def _generate_single_backend_entry(resource_path, resource_name, res, manifest,
|
|
|
162
163
|
Generate a single backend docker-compose entry.
|
|
163
164
|
"""
|
|
164
165
|
res_name = res['name']
|
|
165
|
-
stack = manifest.get('stack', resource_name) if manifest else resource_name
|
|
166
|
+
stack = reject_unsafe_value(manifest.get('stack', resource_name) if manifest else resource_name, 'stack')
|
|
166
167
|
|
|
167
168
|
# Get full service path from resource (for cross-root service support)
|
|
168
169
|
full_resource_path = res.get('_resource_path', resource_path + '/' + res_name)
|
|
@@ -170,30 +171,30 @@ def _generate_single_backend_entry(resource_path, resource_name, res, manifest,
|
|
|
170
171
|
# Calculate correct relative path to env_file from compose file location
|
|
171
172
|
env_file_rel_path = _compute_env_file_rel_path(resource_path, full_resource_path, '.env.backend.autogenerated')
|
|
172
173
|
|
|
173
|
-
internal_port = manifest.get('port', BASE_PORT_BACKEND) if manifest else BASE_PORT_BACKEND
|
|
174
|
+
internal_port = reject_unsafe_value(manifest.get('port', BASE_PORT_BACKEND), 'port') if manifest else BASE_PORT_BACKEND
|
|
174
175
|
dev_port = internal_port
|
|
175
176
|
# Use PROJECT_NAME from PlatformDockerConstants for portable database naming
|
|
176
177
|
_db_prefix = PlatformDockerConstants.PROJECT_NAME + "_"
|
|
177
|
-
db_name = manifest.get('databaseName', _db_prefix + stack) if manifest else _db_prefix + stack
|
|
178
|
+
db_name = reject_unsafe_value(manifest.get('databaseName', _db_prefix + stack) if manifest else _db_prefix + stack, 'databaseName')
|
|
178
179
|
|
|
179
180
|
# Compute database URLs using centralized constants
|
|
180
181
|
db_url_for_tilt = PlatformDockerConstants.get_database_url_for_env(db_name)
|
|
181
182
|
db_url_with_fallback = PlatformDockerConstants.get_compose_env_database_url(db_name)
|
|
182
183
|
|
|
183
|
-
health_path = manifest.get('healthCheckPath', HEALTH_CHECK_PATH) if manifest else HEALTH_CHECK_PATH
|
|
184
|
+
health_path = reject_unsafe_value(manifest.get('healthCheckPath', HEALTH_CHECK_PATH) if manifest else HEALTH_CHECK_PATH, 'healthCheckPath')
|
|
184
185
|
# A bring-your-own service without healthCheckPath may not serve HTTP. None means no HTTP probe: no Traefik health check labels.
|
|
185
186
|
if manifest and manifest.get('appType') == 'bring-your-own' and not manifest.get('healthCheckPath'):
|
|
186
187
|
health_path = None
|
|
187
188
|
|
|
188
189
|
traefik_cfg = manifest.get('traefik', {}) if manifest else {}
|
|
189
|
-
traefik_host = traefik_cfg.get('host', stack + '.backend.' + _PROJECT_NAME + '.local')
|
|
190
|
+
traefik_host = reject_unsafe_value(traefik_cfg.get('host', stack + '.backend.' + _PROJECT_NAME + '.local'), 'traefik.host')
|
|
190
191
|
# ALPHA: Use proper API v1 path with -management suffix via api_path_constants
|
|
191
192
|
# Old default: '/api/' + stack
|
|
192
193
|
# New default: get_api_path_for_domain → /api/v1/{stack}-management
|
|
193
|
-
traefik_path = traefik_cfg.get('pathPrefix', get_api_path_for_domain(stack, manifest))
|
|
194
|
+
traefik_path = reject_unsafe_value(traefik_cfg.get('pathPrefix', get_api_path_for_domain(stack, manifest)), 'traefik.pathPrefix')
|
|
194
195
|
|
|
195
196
|
nats_cfg = manifest.get('nats', {}) if manifest else {}
|
|
196
|
-
nats_queue = nats_cfg.get('queueGroup', stack + '_backend_svc')
|
|
197
|
+
nats_queue = reject_unsafe_value(nats_cfg.get('queueGroup', stack + '_backend_svc'), 'nats.queueGroup')
|
|
197
198
|
nats_url = PlatformDockerConstants.NATS_URL
|
|
198
199
|
|
|
199
200
|
# Auth configuration: one shared builder keeps this identical to the generated env file (see AuthConfig.from_manifest).
|
|
@@ -203,6 +204,7 @@ def _generate_single_backend_entry(resource_path, resource_name, res, manifest,
|
|
|
203
204
|
# secrets.required / secrets.optional, read from the project .env by Compose (empty with TDK_SECRET_PROVIDER=infisical)
|
|
204
205
|
secrets_env = get_secret_environment_lines(manifest, res_name)
|
|
205
206
|
|
|
207
|
+
byo_image = reject_unsafe_value(manifest.get('image'), 'image') if manifest else None
|
|
206
208
|
# Use .autogenerated/Dockerfile.app.autogenerated by default for build config (primary only)
|
|
207
209
|
if manifest and manifest.get('appType') == 'bring-your-own':
|
|
208
210
|
if manifest.get('image'):
|
|
@@ -216,10 +218,10 @@ def _generate_single_backend_entry(resource_path, resource_name, res, manifest,
|
|
|
216
218
|
# `buildContext` (relative to the service directory) moves the context
|
|
217
219
|
# to the source tree an imported Dockerfile lives in; `dockerfile` is then
|
|
218
220
|
# relative to that context, as in Compose.
|
|
219
|
-
custom_context = manifest.get('buildContext')
|
|
221
|
+
custom_context = reject_unsafe_value(manifest.get('buildContext'), 'buildContext')
|
|
220
222
|
if custom_context and custom_context != '.':
|
|
221
223
|
build_context = build_context + '/' + custom_context
|
|
222
|
-
dockerfile = manifest.get('dockerfile', 'Dockerfile')
|
|
224
|
+
dockerfile = reject_unsafe_value(manifest.get('dockerfile', 'Dockerfile'), 'dockerfile')
|
|
223
225
|
if dockerfile.startswith('./'):
|
|
224
226
|
dockerfile = dockerfile[2:]
|
|
225
227
|
build_config = """ build:
|
|
@@ -276,7 +278,7 @@ def _generate_single_backend_entry(resource_path, resource_name, res, manifest,
|
|
|
276
278
|
agent_env = ""
|
|
277
279
|
agent_volume_section = ""
|
|
278
280
|
if manifest and type(manifest.get('agent')) == 'dict':
|
|
279
|
-
agent_durability = manifest['agent'].get('durability', 'files')
|
|
281
|
+
agent_durability = reject_unsafe_value(manifest['agent'].get('durability', 'files'), 'agent.durability')
|
|
280
282
|
agent_env = " - AGENT_DURABILITY={}\n".format(agent_durability)
|
|
281
283
|
if agent_durability == 'files':
|
|
282
284
|
agent_volume = res_name + '-agent-state'
|
|
@@ -289,7 +291,7 @@ def _generate_single_backend_entry(resource_path, resource_name, res, manifest,
|
|
|
289
291
|
else:
|
|
290
292
|
# Traefik's load-balancer check can be overridden separately in service.json
|
|
291
293
|
# (`traefik.healthCheck`); it defaults to the container check's path.
|
|
292
|
-
traefik_health_path = traefik_cfg.get('healthCheck') or health_path
|
|
294
|
+
traefik_health_path = reject_unsafe_value(traefik_cfg.get('healthCheck'), 'traefik.healthCheck') or health_path
|
|
293
295
|
traefik_labels = get_backend_traefik_labels(
|
|
294
296
|
resource_entry_name=resource_entry_name,
|
|
295
297
|
traefik_host=traefik_host,
|
|
@@ -354,8 +356,8 @@ def _generate_single_backend_entry(resource_path, resource_name, res, manifest,
|
|
|
354
356
|
res_name=res_name,
|
|
355
357
|
resource_name=resource_name,
|
|
356
358
|
image_name=(
|
|
357
|
-
|
|
358
|
-
if manifest and manifest.get('appType') == 'bring-your-own' and
|
|
359
|
+
byo_image
|
|
360
|
+
if manifest and manifest.get('appType') == 'bring-your-own' and byo_image
|
|
359
361
|
else PlatformDockerConstants.app_image_name(resource_name, res_name)
|
|
360
362
|
),
|
|
361
363
|
build_config=build_config,
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Copyright (c) 2026 Flisk Landscape contributors
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Defence in depth for values written into generated Compose / Traefik YAML.
|
|
5
|
+
# parser.star already refuses these values, but a caller that reaches a generator directly bypasses it.
|
|
6
|
+
# A line break is the only way to add a YAML key, so refuse it here too (GHSA-phgf-pww4-7jxc, #710).
|
|
7
|
+
# Keep in step with _LINE_BREAK_OR_CONTROL in engine/topologies/tilt/manifest/parser.star and
|
|
8
|
+
# hasLineBreakOrControl in cli/src/utils/service-manifest.ts. This file has no load() on purpose.
|
|
9
|
+
# =============================================================================
|
|
10
|
+
|
|
11
|
+
_LINE_BREAK_OR_CONTROL = [chr(i) for i in range(32)] + [chr(127), "\u0085", "\u2028", "\u2029"]
|
|
12
|
+
|
|
13
|
+
def reject_unsafe_value(value, field):
|
|
14
|
+
"""Return value unchanged, or fail() if a string contains a line break or control character.
|
|
15
|
+
|
|
16
|
+
Non-strings (None, numbers) pass through. The value is not echoed, because it may contain the line break that makes it dangerous.
|
|
17
|
+
"""
|
|
18
|
+
if type(value) != "string":
|
|
19
|
+
return value
|
|
20
|
+
for bad in _LINE_BREAK_OR_CONTROL:
|
|
21
|
+
if bad in value:
|
|
22
|
+
fail("MANIFEST ERROR: '{}' must not contain line breaks or control characters".format(field))
|
|
23
|
+
return value
|
|
@@ -37,10 +37,17 @@ load("./sablier_container_cycle.star",
|
|
|
37
37
|
"sablier_middleware_suffix",
|
|
38
38
|
"sablier_container_labels",
|
|
39
39
|
)
|
|
40
|
+
load("../compose/unsafe_value.star", "reject_unsafe_value")
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
def get_frontend_traefik_labels(res_name, domain, base_path, port, traefik_host=None, manifest=None):
|
|
43
44
|
"""Generate Traefik labels for frontend services."""
|
|
45
|
+
reject_unsafe_value(res_name, 'res_name')
|
|
46
|
+
reject_unsafe_value(domain, 'domain')
|
|
47
|
+
reject_unsafe_value(base_path, 'base_path')
|
|
48
|
+
reject_unsafe_value(port, 'port')
|
|
49
|
+
reject_unsafe_value(traefik_host, 'traefik_host')
|
|
50
|
+
|
|
44
51
|
# Priority based on path length ensures more specific paths win over broader ones
|
|
45
52
|
router_priority = TRAEFIK_FRONTEND_PRIORITY_BASE + len(base_path or "")
|
|
46
53
|
frontend_route_rule = frontend_rule(res_name, base_path, traefik_host)
|
|
@@ -111,6 +118,18 @@ def get_backend_traefik_labels(
|
|
|
111
118
|
manifest=None,
|
|
112
119
|
):
|
|
113
120
|
"""Generate Traefik labels for backend services with enhanced health checks."""
|
|
121
|
+
reject_unsafe_value(resource_entry_name, 'resource_entry_name')
|
|
122
|
+
reject_unsafe_value(traefik_host, 'traefik_host')
|
|
123
|
+
reject_unsafe_value(traefik_path, 'traefik_path')
|
|
124
|
+
reject_unsafe_value(traefik_resource_name, 'traefik_resource_name')
|
|
125
|
+
reject_unsafe_value(health_path, 'health_path')
|
|
126
|
+
reject_unsafe_value(internal_port, 'internal_port')
|
|
127
|
+
if manifest:
|
|
128
|
+
reject_unsafe_value(manifest.get('stack'), 'stack')
|
|
129
|
+
traefik_cfg = manifest.get('traefik') or {}
|
|
130
|
+
reject_unsafe_value(traefik_cfg.get('host'), 'traefik.host')
|
|
131
|
+
reject_unsafe_value(traefik_cfg.get('pathPrefix'), 'traefik.pathPrefix')
|
|
132
|
+
|
|
114
133
|
backend_route_rule = backend_rule(traefik_host, traefik_path)
|
|
115
134
|
backend_entrypoints = build_entrypoints(
|
|
116
135
|
TRAEFIK_BACKEND_ENABLE_HTTP,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flisk-sh/flisk",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.206",
|
|
4
4
|
"description": "Flisk CLI — start services on your machine.",
|
|
5
5
|
"homepage": "https://flisk.sh",
|
|
6
6
|
"repository": {
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"chalk": "^6.0.1",
|
|
83
83
|
"ink": "^8.0.0",
|
|
84
84
|
"react": "^19.3.0",
|
|
85
|
-
"@types/node": "^
|
|
85
|
+
"@types/node": "^26.6.5",
|
|
86
86
|
"knip": "^6.38.0",
|
|
87
87
|
"yaml": "^2.9.1"
|
|
88
88
|
},
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
|
|
2
|
-
import{b as f}from"./chunk-CF46CD6R.js";var ar="Container Runtime",_="bring-your-own";var De="database-management",cr=".tiltignore",Ie="service.json",Q="docker-compose.yml",ur=".autogenerated",Ct="TILT_TECH_STACK.star",Dt="TILT_RESOURCE_DEFAULTS.star",B="project.json",je="package.json",fr=[Ct,Dt,"spec.master"],pr=["backend","frontend","library","sdk","worker","migrator","mcp","agent",_],lr={backend:["dev","build","start"],worker:["dev","build","start"],migrator:["dev","build","start"],mcp:["dev","build","start"],agent:["dev","build","start"],frontend:["dev","build"],library:["dev","build"],sdk:["dev","build"],[_]:[]};var Z=["monitoring","elk","debezium","golden_image","verdaccio"],dr={frontend:{base:3e3,min:3e3,max:3999,range:"3000-3999"},backend:{base:4e3,min:4e3,max:4999,range:"4000-4999"},mcp:{base:4e3,min:4e3,max:5999,range:"4000-5999"},agent:{base:4e3,min:4e3,max:5999,range:"4000-5999"},[_]:{base:4e3,min:4e3,max:5999,range:"4000-5999"},worker:{base:6e3,min:6e3,max:6999,range:"6000-6999"},health:{base:5e3,min:5e3,max:5999,range:"5000-5999"},migrator:{base:7e3,min:7e3,max:7999,range:"7000-7999"}},mr={tiltUi:10350,traefik:8080},ee="https://flisk.sh/docs/quickstart/";var Ne=["node_modules",".git",".tilt",".tilt-engine","dist","build",".prisma",".turbo","coverage","tmp","temp","__tests__","test","tests",".github",".vscode","docs"],Pe=["Dockerfile",Q,"docker-compose.yaml","Tiltfile","vite.config.ts","tsconfig.json","tsconfig.build.json"],It={infra:"\u{1F3D7}\uFE0F",core:"\u{1F527}",api:"\u26A1",app:"\u{1F3A8}",orchestrator:"\u2699\uFE0F"};function hr(e){let t=e.toLowerCase();for(let[n,r]of Object.entries(It))if(t.includes(n))return r;return"\u{1F4E6}"}import{existsSync as Nt}from"node:fs";import{dirname as Pt,join as Ft,resolve as Ue}from"node:path";import{cwd as Ut}from"node:process";var Fe={name:"tdk-cli-internal",private:!0,version:"1.3.204",description:"Flisk CLI \u2014 start services on your machine.",keywords:["flisk","tilt","cli","local-dev","microservices"],homepage:"https://github.com/flisk-sh/flisk#readme",bugs:{url:"https://github.com/flisk-sh/flisk/issues"},repository:{type:"git",url:"git+https://github.com/flisk-sh/flisk.git",directory:"cli"},license:"MIT",author:"Flisk Team",type:"module",main:"./dist/index.js",types:"./dist/index.d.ts",bin:{flisk:"bin/tdk.js"},files:["dist","dist-bundle","bin","templates","README.md","Tiltfile","engine","discovery","specs","ext","!ext/ide-components/code_executor","shared-platform-engineering/docker-templates"],scripts:{build:"tsc && node scripts/bundle.mjs","build:watch":"tsc --watch","check:dist":"npm run build && ../scripts/check-cli-dist.sh",lint:"biome check .","lint:fix":"biome check . --write",typecheck:"tsc --project tsconfig.typecheck.json",clean:"rm -rf dist",dev:"bun run build:watch",test:"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage --coverage.reportOnFailure --coverage.reporter=text --coverage.reporter=html --coverage.reporter=json-summary --coverage.reporter=json --coverage.reportsDirectory=coverage --reporter=default --reporter=json --outputFile.json=test-results/vitest.json",prepack:"../scripts/stage-npm-engine.sh && npm run build"},dependencies:{commander:"^15.0.0",handlebars:"^4.7.8"},devDependencies:{"@biomejs/biome":"^2.5.13","@types/node":"^22.0.0","@types/react":"^19.3.0","@vitest/coverage-v8":"^5.0.2",ajv:"^8.17.1",chalk:"^6.0.1",esbuild:"^0.28.2",ink:"^8.0.0",knip:"^6.38.0",react:"^19.3.0","react-devtools-core":"^8.0.0",typescript:"^7.0.2",vite:"^8.3.3",vitest:"^5.0.0"},engines:{node:">=22.12.0"}};function E(e=Ut()){let t=Ue(e),n=Ue("/");for(;t!==n;){if(Nt(Ft(t,".tdk",B)))return t;let r=Pt(t);if(r===t)break;t=r}return null}var V=null;function Mt(){if(V)return V;let e=Fe;if(!e||typeof e!="object"||Array.isArray(e))throw new Error("Invalid package.json: expected object");let t=e;return V={name:String(t.name??"@flisk-sh/flisk"),version:String(t.version??"0.0.0"),fullPackage:t},V}function wr(){return Mt().version}import{existsSync as Me}from"node:fs";import{delimiter as Le,extname as Be,join as Ve}from"node:path";import{delimiter as br,extname as Lt}from"node:path";function U(){return process.platform==="win32"}function Bt(e){return e==="linux"?"linux":e==="darwin"?"darwin":e==="win32"?"windows":null}function Vt(e){return e==="x64"?"amd64":e==="arm64"?"arm64":null}function Gt(e,t){let n=Bt(e),r=Vt(t);if(!n||!r||n==="windows"&&r!=="amd64")return null;let o=`tdk-${n}-${r}`;return n==="windows"?`${o}.exe`:o}function Ar(){return Gt(process.platform,process.arch)}function Rr(){return U()?"tdk.exe":"flisk"}function te(e,t=U()){return t?Lt(e)?[e]:[e,`${e}.exe`,`${e}.cmd`,`${e}.bat`]:[e]}function G(e){let t=process.env.PATH??process.env.Path??"",n=U(),r=te(e,n);if(n&&!Be(e))for(let o of(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";")){let s=o.toLowerCase();s&&!r.includes(`${e}${s}`)&&r.push(`${e}${s}`)}for(let o of t.split(Le))if(o)for(let s of r){let i=Ve(o,s);if(Me(i))return i}return null}function Ir(e){let t=process.env.PATH??process.env.Path??"",n=U(),r=te(e,n);if(n&&!Be(e))for(let i of(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";")){let a=i.toLowerCase();a&&!r.includes(`${e}${a}`)&&r.push(`${e}${a}`)}let o=[],s=new Set;for(let i of t.split(Le))if(i)for(let a of r){let c=Ve(i,a);if(!Me(c))continue;let p=n?c.toLowerCase():c;s.has(p)||(s.add(p),o.push(c))}return o}import{execFileSync as Wt,execSync as Kt}from"node:child_process";var Ge=1e4;function We(){let e=!1;if(process.platform==="win32")try{return Wt(G("docker")??"docker",["ps"],{stdio:"ignore",timeout:Ge,windowsHide:!0}),"running"}catch(t){return t.code==="ETIMEDOUT"?"unresponsive":"missing"}for(let t of["docker ps","colima status","podman ps"])try{return Kt(t,{stdio:"ignore",timeout:Ge}),"running"}catch(n){n.code==="ETIMEDOUT"&&(e=!0)}return e?"unresponsive":"missing"}function W(e,t){return e[t]??0}function Ht(e,t){let n=Array.from({length:t.length+1},(r,o)=>o);for(let r=1;r<=e.length;r++){let o=[r];for(let s=1;s<=t.length;s++){let i=e[r-1]===t[s-1]?0:1;o[s]=Math.min(W(o,s-1)+1,W(n,s)+1,W(n,s-1)+i)}n=o}return W(n,t.length)}function zt(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length-1;n++)if(e[n]!==t[n]&&e[n]===t[n+1]&&e[n+1]===t[n]&&e.slice(0,n)===t.slice(0,n)&&e.slice(n+2)===t.slice(n+2))return!0;return!1}function Ke(e,t){if(e.length<2||t.length===0||t.includes(e))return;let n=e.toLowerCase(),r,o=Number.POSITIVE_INFINITY;for(let s of t){if(s.length===0)continue;let i=s.toLowerCase(),a=zt(n,i)?1:Ht(n,i),c=Math.max(1,Math.min(2,Math.floor(Math.max(n.length,i.length)/3)));a>c||(a<o||a===o&&(r===void 0||s<r))&&(r=s,o=a)}return r}import{spawn as Jt}from"node:child_process";import{join as qt}from"node:path";function Yt(e,t=[],n={}){return new Promise((r,o)=>{let s=[e,...t];n.verbose&&console.log(`Executing: tilt ${s.join(" ")}`);let i=Jt(G("tilt")??"tilt",s,{stdio:n.inheritStdio?"inherit":"pipe",shell:!1,windowsHide:process.platform==="win32",timeout:n.timeoutMs}),a="",c="";n.inheritStdio||(i.stdout?.on("data",p=>{a+=p.toString()}),i.stderr?.on("data",p=>{c+=p.toString()})),i.on("close",p=>{r({exitCode:p??1,stdout:a,stderr:c})}),i.on("error",p=>{o(new Error(`Failed to spawn tilt: ${p.message}`))})})}async function He(){try{return(await Yt("version",[],{inheritStdio:!1,timeoutMs:1e4})).exitCode===0}catch{return!1}}function Xt(){let e=E();if(!e)throw $.notInProject();return qt(e,".tdk",".tdk-out","Tiltfile")}function ze(e){let t=Xt();e.push("-f",t)}function Wr(e,t={}){let n=[];return ze(n),t.focusTargets&&t.focusTargets.length>0&&n.push("--",`--focus=${t.focusTargets.join(",")}`),n.push(...e),t.verbose&&!t.quiet&&n.push("--verbose"),t.watch&&n.push("--watch"),n}function Kr(e={}){let t=[];return ze(t),e.focusTargets&&e.focusTargets.length>0&&t.push("--",`--focus=${e.focusTargets.join(",")}`),t}function Je(e){return e instanceof Error?e.message:String(e)}function Zr(e,t){if(process.env.TDK_VERBOSE){let n=t!==void 0?`: ${Je(t)}`:"";console.warn(f.gray(`${e}${n}`))}}var S=class extends Error{suggestions;exitCode;constructor(t,n=[],r=1){super(t),this.name="TdkError",this.suggestions=n,this.exitCode=r}display(){oe(this.message,void 0,this.suggestions)}exit(){this.display(),process.exit(this.exitCode)}},re=class extends Error{code;constructor(t=1){super(`process.exit(${t})`),this.name="ProcessExitError",this.code=t}};function ne(e,t,n=!1){let r=new Set;for(let o of e){let s=Ke(o,t);s&&r.add(n?`Did you mean "${s}" for "${o}"?`:`Did you mean "${s}"?`)}return[...r]}var $={tiltNotInstalled:()=>new S("Tilt CLI is not installed",["Install Tilt: `brew install tilt` (macOS)","Or download from: https://docs.tilt.dev/install.html","Verify with: `tilt version`",`Setup guide: ${ee}`]),dockerNotAvailable:()=>new S("Docker (or a compatible container runtime) is not running",["Start Docker Desktop, then verify with: `docker ps`","Or start Colima: `colima start`","Or start the Docker service on Linux: `sudo systemctl start docker`",`Setup guide: ${ee}`]),dockerNotResponding:()=>new S("Docker is running but not responding (`docker ps` hung for 10s)",["Quit and reopen Docker Desktop, or run `colima restart`","Then verify with: `docker ps`"]),stackNotFound:(e,t=[])=>new S(`Stack "${e}" not found`,[...ne([e],t),"Run `flisk stacks` to see available stacks","Run `flisk stack` to assign resources to a stack"]),resourceNotFound:(e,t=[])=>new S(`Resource "${e}" not found`,[...ne([e],t),"Run `flisk resources` to list all resources","Check the resource name spelling"]),unknownServices:(e,t)=>{let n=ne(e,t,e.length>1);return new S(`Unknown service ${e.join(", ")}. Valid names: ${t.join(", ")}`,n,2)},directoryExists:e=>new S(`Directory already exists: ${e}`,["Use `--path` to specify a different location","Remove the existing directory if no longer needed"]),invalidPath:e=>new S(`Invalid path: ${e}`,["Path must be within the project directory",'Path cannot contain special characters like <>:"|?*']),notInProject:()=>new S("Could not find project root (no .tdk/project.json found)",["Run this from within a Flisk project","Run `flisk project --yes` to initialize a new project"])};function eo(){let e=E();return e||$.notInProject().exit()}function Qt(e){e instanceof S&&e.exit(),oe(Je(e)),process.exit(1)}async function Zt(e,t){try{return await e()}catch(n){if(n instanceof re)throw n;return t?.verbose&&n instanceof Error&&n.stack&&console.error(f.gray(n.stack)),Qt(n)}}async function to(e,t){let n=[],r=We();return r==="unresponsive"?n.push($.dockerNotResponding()):r==="missing"&&n.push($.dockerNotAvailable()),await He()||n.push($.tiltNotInstalled()),n.length>0&&(console.error(f.red(`
|
|
3
|
-
Flisk can't start - missing prerequisites:
|
|
4
|
-
`)),n.forEach((o,s)=>{s>0&&console.error(""),o.display()}),console.error(f.gray("\nRun `flisk doctor` for a full environment check.")),process.exit(1)),Zt(e,t)}function no(e,t=1,n){oe(e,void 0,n),process.exit(t)}function oe(e,t,n){if(console.error(f.red(`\u274C ${e}`)),t&&console.error(f.gray(` ${t}`)),n&&n.length>0){console.error(f.yellow(`
|
|
5
|
-
\u{1F4A1} Suggestions:`));for(let r of n)console.error(f.cyan(` \u2192 ${r}`))}}function ro(e,t){console.error(f.red(`
|
|
6
|
-
tilt ${e} failed with exit code ${t}`)),process.exit(t)}function en(e,t,n){return e===1?t:n||`${t}s`}function Ye(e,t,n){return`${e} ${en(e,t,n)}`}var tn={month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"};function io(e){return new Date(e).toLocaleString("en-US",tn)}function ao(e){return new Date(e).toLocaleDateString("en-US",{month:"short",day:"numeric"})}var se={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 ie(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 co(e){return se[ie(e)].color}function uo(e){return se[ie(e)].icon}function fo(e,t){return se[ie(t)].chalkFn(e)}var nn={resources:{singular:"resource",command:"flisk resource <name>",context:`
|
|
7
|
-
To create a resource:`},stacks:{singular:"stack",command:"flisk stack <stack-name>",context:`
|
|
8
|
-
To create a stack, use:`},services:{singular:"service",command:"flisk resource <name>",context:`
|
|
9
|
-
To create a service:`},"stack-services":{singular:"service",command:"flisk resource <name> --stack <stack-name>",context:`
|
|
10
|
-
To add services to this stack:`}};function po(e,t){let n=nn[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(`
|
|
11
|
-
Or create a new resource with a stack:`)),console.log(f.gray(" flisk resource <name> --stack <stack-name>")))}function lo(e){console.log(f.yellow(e||"Cancelled."))}function mo(e){console.log(f.blue(`Flisk ${e}
|
|
12
|
-
`))}function ho(e,t){console.log(f.green(`All ${e} are ${t}!`))}var ae=62;function go(e="\u2500",t=ae){return e.repeat(t)}function qe(e,t=ae-2){let n=Math.max(0,t-e.length),r=Math.floor(n/2),o=n-r;return" ".repeat(r)+e+" ".repeat(o)}function So(e,t){return e.length>t?`${e.slice(0,t-1)}\u2026`:e.padEnd(t)}function xo(e,t){return e.length<=t?e:`${e.slice(0,t-3)}...`}function yo(e){console.log(f.green(`\u2713 ${e}`))}function Eo(e){console.log(f.blue(e))}function ko(e,t=2){console.log(f.gray(`${" ".repeat(t)}${e}`))}function $o(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function wo(e,t,n=ae){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(qe(e,r))+f.cyan("\u2502")),t&&(console.log(f.cyan(`\u251C${o}\u2524`)),console.log(f.cyan("\u2502")+f.gray(qe(t,r))+f.cyan("\u2502"))),console.log(f.cyan(`\u2570${o}\u256F`))}import{randomBytes as Qe}from"node:crypto";import{existsSync as ue,readFileSync as Ze,writeFileSync as et}from"node:fs";import{join as fe}from"node:path";import{randomBytes as rn}from"node:crypto";import{closeSync as on,fchmodSync as sn,fsyncSync as an,openSync as cn,renameSync as un,rmSync as fn,statSync as pn,writeFileSync as ln}from"node:fs";import{basename as dn,dirname as mn,join as hn}from"node:path";function Xe(e,t){let n=hn(mn(e),`.${dn(e)}.${process.pid}.${rn(4).toString("hex")}.tmp`),r;try{r=pn(e).mode&511}catch{r=void 0}try{let o=cn(n,"wx");try{r!==void 0&&sn(o,r),ln(o,t,"utf-8"),an(o)}finally{on(o)}un(n,e)}catch(o){throw fn(n,{force:!0}),o}}var R=[{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}],tt=()=>Qe(16).toString("hex"),gn=()=>Qe(32).toString("hex"),Io=R.filter(e=>e.complete).map(e=>e.name);function ce(e,t){return e==="DB_PASSWORD"?t:e==="JWT_SECRET"?gn():e==="DATABASE_URL"?`postgresql://postgres:${t}@postgres:5432/app_dev`:R.find(n=>n.name===e)?.default??""}function Sn(e){let t=e.trim(),n=t[0];if(n==='"'||n==="'"){let o=!1;for(let s=1;s<t.length;s+=1){let i=t[s];if(o){o=!1;continue}if(i==="\\"){o=!0;continue}if(i===n){let a=t.slice(1,s);if(n==='"'){let c={n:`
|
|
13
|
-
`,r:"\r",t:" ",'"':'"',"\\":"\\",$:"$"};return a.replace(/\\([nrt"\\$])/g,(p,l)=>c[l]??l)}return a.replace(/\\'/g,"'")}}return t}let r=e.search(/\s#/);return(r===-1?e:e.slice(0,r)).trim()}function O(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,i=s.indexOf("=");if(i<=0)continue;let a=s.slice(0,i).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(a)&&t.set(a,Sn(s.slice(i+1)))}return t}function nt(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 rt(){let e=tt(),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 R)t.push(...nt(n)),t.push(`${n.name}=${ce(n.name,e)}`),t.push("");return t.join(`
|
|
14
|
-
`)}function xn(e){let t=e.match(/^[a-z][a-z0-9+.-]*:\/\/[^:/@\s]+:([^@\s]*)@/i);if(!(!t||t[1].includes("$")))return t[1]}function jo(e){let t=fe(e,".env"),n={missing:[],invalid:[],warnings:[]};if(!ue(t))return{missing:R.filter(i=>i.required).map(i=>i.name),invalid:[],warnings:[".env file not found - will be auto-generated"]};let r=O(Ze(t,"utf-8"));for(let i of R)i.required&&!r.has(i.name)&&n.missing.push(i.name),r.has(i.name)&&!(r.get(i.name)??"").trim()&&n.invalid.push(`${i.name} is set but empty`);let o=r.get("DATABASE_URL"),s=r.get("DB_PASSWORD");if(o&&s){let i=xn(o);i!==void 0&&i!==s&&n.warnings.push("DATABASE_URL carries a different password than DB_PASSWORD; the database container uses DB_PASSWORD")}return n}function yn(e,t,n){if(!O(e).has(t))return e;let o=e.indexOf("=");if(o<0)return e;let s=e.slice(o+1),i=s.search(/\s#/),a=i<0?"":s.slice(i);return e.slice(0,o+1)+n+a}function No(e){let t=fe(e,".env");if(!ue(t))return et(t,rt(),{mode:384}),R.map(u=>u.name);let n=Ze(t,"utf-8"),r=O(n),o=R.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)),i=o.filter(u=>r.has(u.name)),a=r.get("DB_PASSWORD"),c=a?.trim()?a:tt(),p=n.split(/(\r\n|\n|\r)/);for(let u of i){let h=-1;for(let d=0;d<p.length;d+=2)O(p[d]).has(u.name)&&(h=d);if(h<0)throw new Error(`Could not locate empty .env assignment for ${u.name}`);p[h]=yn(p[h],u.name,ce(u.name,c))}let l=p.join("");if(s.length>0){let u=["","# Added by Flisk: keys this version expects. Existing values above were not changed.",""];for(let d of s)u.push(...nt(d)),u.push(`${d.name}=${ce(d.name,c)}`),u.push("");let h=l.endsWith(`
|
|
15
|
-
`)||l.endsWith("\r")?"":`
|
|
16
|
-
`;l+=h+u.join(`
|
|
17
|
-
`)}return Xe(t,l),o.map(u=>u.name)}function Po(e){let t=fe(e,".env");return ue(t)?!1:(et(t,rt(),{mode:384}),!0)}import{readFileSync as En}from"node:fs";import{join as kn}from"node:path";function C(e){return e==="backend"||e==="mcp"||e==="agent"}function Wo(){return ot(E())}function ot(e){if(e)try{let t=En(kn(e,".tdk",B),"utf-8"),n=JSON.parse(t);if(n?.project?.name)return n.project.name}catch{}return"tdk-project"}function pe(e,t){let n=ot(t??E()),r=process.env.TDK_SERVICE_BASE_URL??`http://${n}.localhost${e?`:${e}`:""}`;try{let o=new URL(r.includes("://")?r:`http://${r}`),s=o.hostname,i=o.protocol==="https:"?"443":"80",a=o.port||(e?String(e):""),c=a===i?"":a;if(s==="localhost"||/^\d+\.\d+\.\d+\.\d+$/.test(s))return{appBase:`${o.protocol}//${s}${c?`:${c}`:""}`,apiBase:`${o.protocol}//${s}${c?`:${c}`:""}`};let p=s.replace(/^(app|api)\./,"");return{appBase:`${o.protocol}//app.${p}${c?`:${c}`:""}`,apiBase:`${o.protocol}//api.${p}${c?`:${c}`:""}`}}catch{return{appBase:`http://app.${n}.localhost`,apiBase:`http://api.${n}.localhost`}}}function $n(e){return`${e.replace(/\/+$/,"")}/health`}function le(e){if(C(e.config?.appType)){let t=e.name.replace(/-api$/,"");return e.config?.apiPath??`/api/${t}`}return e.config?.basePath??`/${e.name}`}function Ko(e,t){return st(e,t,n=>$n(n))}function Ho(e,t){return st(e,t,n=>n)}function st(e,t,n){let{appBase:r,apiBase:o}=pe(t);return e.filter(s=>s.config?.appType==="frontend"||C(s.config?.appType)).map(s=>{let i=C(s.config.appType)?o:r;return{name:s.name,appType:s.config.appType,url:`${i}${n(le(s))}`}})}async function wn(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 zo(e,t){return Promise.all(e.map(n=>wn(n,t)))}var vn=/^[a-z0-9-]+$/;function it(e){return vn.test(e)}var Tn="Use lowercase letters, numbers, and hyphens only";function at(e,t){return`${e} "${t}" is not valid. ${Tn}, e.g. "${e==="Resource name"?"my-service":"my-stack"}".`}function bn(e){return e.trim()?it(e)?{valid:!0}:{valid:!1,error:at("Resource name",e)}:{valid:!1,error:"Resource name is required"}}function An(e){return e.trim()?it(e)?{valid:!0}:{valid:!1,error:at("Stack name",e)}:{valid:!1,error:"Stack name is required"}}function Yo(e){let t=e==="resource"?bn:An;return n=>{let r=t(n);return r.valid?!0:r.error??"Invalid name"}}function Xo(e){return de(Z,e)?{valid:!0}:{valid:!1,error:`Invalid service. Must be one of: ${Z.join(", ")}`}}function Qo(e){return Number.isInteger(e)&&e>0&&e<=65535}function Zo(e){return!e.includes("\0")&&!/[<>:"|?*]/.test(e)}function es(e,t="_"){return e.replace(/[^a-zA-Z0-9-]/g,t).substring(0,100)}function de(e,t){return e.includes(t)}import Rt,{existsSync as I,readdirSync as qn,readFileSync as Yn,statSync as Ee}from"node:fs";import{dirname as Xn,join as b}from"node:path";var M=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 ct(e){let t=0;return{isValid(){return Date.now()-t<e},markUpdated(){t=Date.now()},reset(){t=0}}}import{existsSync as Tt,readFileSync as bt}from"node:fs";import{copyFileSync as dt,mkdirSync as jn,rmSync as mt,writeFileSync as ht}from"node:fs";import{join as D}from"node:path";import{existsSync as Rn,readFileSync as _n}from"node:fs";import{join as On}from"node:path";var Cn="[REDACTED]",me=class extends Error{path;constructor(t,n){super(`Could not read ${t}: ${n}`),this.path=t,this.name="EnvUnreadableError"}},Dn=8;function In(e,t=[]){let n=[...ut(On(e,".env")),...t.flatMap(r=>ut(r))];return[...new Set(n)].sort((r,o)=>o.length-r.length)}function ut(e){if(!Rn(e))return[];let t;try{t=_n(e,"utf-8")}catch(n){throw new me(e,n instanceof Error?n.message:String(n))}return[...O(t).values()].filter(n=>n.length>=Dn)}function pt(e,t){let n=e;for(let r of t)n=n.split(r).join(Cn);return n}function ft(e,t){return t.length===0?e:typeof e=="string"?pt(e,t):Array.isArray(e)?e.map(n=>ft(n,t)):e!==null&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,ft(r,t)])):e}function lt(e,t=[]){let n;try{n=In(e,t)}catch(r){return()=>{throw r}}return r=>pt(r,n)}var kt=60,gt=1e3,St=1e4,xt=200,yt=64*1024,Et=new Set([404,502,503,504]),Nn=new Set(["ECONNREFUSED","ENOTFOUND","EAI_AGAIN","EHOSTUNREACH","ENETUNREACH"]),Pn=new Set(["GET","HEAD","OPTIONS"]);function v(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Fn(e,t){if(Pn.has(t))return!0;if(!v(e))return!1;let n=v(e.cause)?e.cause:void 0,r=e.code??n?.code;return typeof r=="string"&&Nn.has(r)}function ge(e){if(!v(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(!v(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&&(v(n.save)&&Object.values(n.save).every(a=>typeof a=="string"&&a.startsWith("$."))||t.push(`${o}.save: must map names to paths such as "$.id"`))}),t)}function ds(e,t){let{appBase:n,apiBase:r}=pe(t),o=[];for(let s of e){let i=s.config;if(!i?.smoke)continue;let a=i.appType,c=C(a)||a===_;if(!c&&a!=="frontend"||i.exposeViaProxy===!1)continue;let p=c?r:n,l=i.healthCheckPath||(c&&a!==_?"/health":void 0);o.push({name:s.name,baseUrl:`${p}${le(s).replace(/\/+$/,"")}`,...l?.startsWith("/")?{readyPath:l}:{},smoke:i.smoke})}return o}var Un=10;function ms(e,t={}){let n=t.timeoutSeconds??Un;return e.flatMap(r=>{let o=r.smoke.steps.filter(i=>(i.method??"GET").toUpperCase()==="GET"&&i.body===void 0&&!i.path.includes("{{")).map(i=>({...i,bodyContains:void 0}));if(o.length===0)return[];let s=Math.min(r.smoke.timeoutSeconds??kt,n);return[{name:r.name,baseUrl:r.baseUrl,smoke:{via:r.smoke.via,timeoutSeconds:s,steps:o}}]})}function Mn(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 $t(e,t){return e.replace(/\{\{(\w+)\}\}/g,(n,r)=>t[r]??n)}function he(e,t){return typeof e=="string"?$t(e,t):Array.isArray(e)?e.map(n=>he(n,t)):v(e)?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,he(r,t)])):e}function K(e){let t=e.replace(/\s+/g," ").trim();return t.length>xt?`${t.slice(0,xt)}...`:t}function wt(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"step"}function Ln(e,t){let n=wt(t),r=(e.get(n)??0)+1;return e.set(n,r),r===1?n:`${n}-${r}`}function Bn(e,t,n,r,o){try{let s=D(e,wt(n.service),t);jn(s,{recursive:!0});let i=D(s,"latest.json"),a=D(s,"body.txt");return r===void 0?mt(a,{force:!0}):ht(a,r),ht(i,`${JSON.stringify({...n,bodyPath:r===void 0?null:"body.txt"},null,2)}
|
|
18
|
-
`),o&&(dt(i,D(s,"last-success.json")),r===void 0?mt(D(s,"last-success-body.txt"),{force:!0}):dt(a,D(s,"last-success-body.txt"))),i}catch{return}}function Vn(e){let t=Buffer.from(e,"utf8");if(t.length<=yt)return{body:e,truncated:!1,bytes:t.length};let n=t.subarray(0,yt).toString("utf8").replace(/\uFFFD$/,"");return{body:n,truncated:!0,bytes:Buffer.byteLength(n,"utf8")}}async function Gn(e,t={}){let n=t.fetch??((l,u)=>fetch(l,u)),r=t.now??Date.now,o=t.sleep??(l=>new Promise(u=>setTimeout(u,l))),s=(e.smoke.timeoutSeconds??kt)*1e3,i=r()+s,a={},c=ge(e.smoke);if(c.length>0)return{name:e.name,ok:!1,failure:`${e.name}: invalid smoke block: ${c.join("; ")}`};if(e.readyPath){let l=`${e.baseUrl}${e.readyPath}`;for(;;){try{let u=await n(l,{method:"GET",signal:AbortSignal.timeout(St)});if(await u.text(),!Et.has(u.status)&&u.status<500)break}catch{}if(r()>=i)break;await o(gt)}}i=r()+s;let p=new Map;for(let[l,u]of e.smoke.steps.entries()){let h=u.name??`step ${l+1}`,d=(u.method??"GET").toUpperCase(),be=`${e.baseUrl}${$t(u.path,a)}`,j=u.expect??200,Ae=u.body!==void 0,x,N="",w,q;for(;;){w=void 0,q=void 0,x=void 0;let g=!1;try{let m=await n(be,{method:d,headers:Ae?{"content-type":"application/json"}:void 0,body:Ae?JSON.stringify(he(u.body,a)):void 0,signal:AbortSignal.timeout(St)});x=m.status,N=await m.text()}catch(m){g=Fn(m,d),w=m instanceof Error?m.message:String(m);let A=v(m)?m.code??(v(m.cause)?m.cause.code:void 0):void 0;q=typeof A=="string"?A:void 0}if(!(w!==void 0&&g||x!==void 0&&x!==j&&Et.has(x))||r()>=i)break;await o(gt)}let Re=!1,Y=g=>{if(!Re){if(!t.redact)return g;try{return t.redact(g)}catch(k){Re=!0;let m=k instanceof Error?k.message:String(k);t.warn?.(`${e.name}: ${h}: the response text was neither shown nor stored: ${m}`);return}}},X=Y(be),y=x===void 0?void 0:Y(N),_e=w===void 0?void 0:Y(w),Oe=w===void 0?void 0:q??_e,P=`${e.name}: ${h}: ${d} ${X??"(url withheld)"}`,Ce;if(t.recordDir){let g=y===void 0?void 0:Vn(y),k=w===void 0&&x===j&&(u.bodyContains===void 0||N.includes(u.bodyContains));Ce=Bn(t.recordDir,Ln(p,h),{service:e.name,step:h,method:d,...X===void 0?{}:{url:X},expectedStatus:j,status:x??null,...Oe===void 0?{}:{error:Oe},truncated:g?.truncated??!1,bodyBytes:g?.bytes??0},g?.body,k)}let F=g=>({name:e.name,ok:!1,failure:g,recordPath:Ce});if(w!==void 0)return F(`${P} never answered (${_e??"the error was withheld"})`);if(x!==j)return F(`${P} returned ${x}, expected ${j}${y?`: ${K(y)}`:""}`);if(u.bodyContains!==void 0&&!N.includes(u.bodyContains))return F(`${P} returned ${x} but the body does not contain "${u.bodyContains}"${y?`: ${K(y)}`:""}`);if(u.save){let g;try{g=JSON.parse(N)}catch{return F(`${P} returned a body that is not JSON, cannot save${y?`: ${K(y)}`:""}`)}for(let[k,m]of Object.entries(u.save)){let A=Mn(g,m);if(A==null||typeof A=="object")return F(`${P} response has no ${m} to save as {{${k}}}${y?`: ${K(y)}`:""}`);a[k]=String(A)}}}return{name:e.name,ok:!0}}function hs(e){return`Smoke check failed: ${e.failure}${e.recordPath?` (record: ${e.recordPath})`:""}`}function gs(e,t,n={}){return{redact:lt(e,n.envFiles??[]),...t?{warn:t}:{}}}async function Ss(e,t={}){return Promise.all(e.map(n=>Gn(n,t)))}var vt=1,ks="https://flisk.sh/schema.service.json",Wn={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"},Kn=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"]),Hn=[{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 H(e,t){let n=[],r=new Set;for(let{path:o,pattern:s,expected:i}of Hn){let a=e;for(let p of o)a=a&&typeof a=="object"&&!Array.isArray(a)?a[p]:void 0;if(a==null||a==="")continue;let c=`${t}.${o.join(".")}`;(typeof a!="string"||!s.test(a))&&r.add(c),typeof a!="string"?n.push(`${c}: expected a string`):s.test(a)||n.push(`${c}: must be ${i} (no spaces, line breaks or YAML syntax)`)}for(let[o,s]of zn(e,t))r.has(o)||n.push(`${o}: ${s}`);return n}function Se(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 zn(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))Se(o)&&n.push([t,"a key contains a line break"]);for(;r.length>0;){let[o,s]=r.pop();if(typeof o=="string")Se(o)&&n.push([s,"must not contain line breaks or control characters"]);else if(Array.isArray(o))for(let[i,a]of o.entries())r.push([a,`${s}[${i}]`]);else if(o&&typeof o=="object")for(let[i,a]of Object.entries(o))Se(i)?n.push([s,"a key contains a line break"]):r.push([a,`${s}.${i}`])}return n.sort(([o],[s])=>o.localeCompare(s))}var Jn=["apiPath","basePath"];function xe(e){if(!e||typeof e!="object"||Array.isArray(e))return[];let t=e;return Jn.filter(n=>n in t&&typeof t[n]!="string")}function ye(e,t){if(!e||typeof e!="object"||Array.isArray(e))return{errors:[`${t}: expected a JSON object`],warnings:[]};let n=e,r=[];for(let a of["appName","appType","stack","schemaVersion"])a in n||r.push(`${t}.${a}: required field is missing`);for(let a of["appName","appType","stack"])a in n&&typeof n[a]!="string"&&r.push(`${t}.${a}: expected a string`);"schemaVersion"in n&&n.schemaVersion!==vt&&r.push(`${t}.schemaVersion: unsupported version ${String(n.schemaVersion)} (supported: ${vt})`);for(let a of xe(n))r.push(`${t}.${a}: 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(...H(n,t)),"smoke"in n)for(let a of ge(n.smoke))r.push(`${t}.${a}`);let i=Object.keys(n).flatMap(a=>{let c=Wn[a];return c?[`${t}.${a}: ${c}`]:Kn.has(a)?[]:[`${t}.${a}: unknown field is preserved`]});return s===!0&&n.language!=="go"&&i.push(`${t}.dev.liveReload: only applies to Go services (language "go"); it is ignored here`),{errors:r,warnings:i,manifest:n}}function $s(e,t){if(!Tt(e))return[];try{let n=JSON.parse(bt(e,"utf-8"));return!n||typeof n!="object"||Array.isArray(n)?[]:H(n,t)}catch{return[]}}function ws(e,t){if(!Tt(e))return{errors:[`${t}: file is missing`],warnings:[]};try{let n=JSON.parse(bt(e,"utf-8"));return ye(n,t)}catch(n){let r=n instanceof Error?n.message:String(n);return{errors:[`${t}: invalid JSON (${r})`],warnings:[]}}}function At(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 Qn=Ie;function ve(e,t=5,n=0){let r=[];if(n>t)return r;let o=Rt.readdirSync(e,{withFileTypes:!0});for(let s of o){let i=b(e,s.name);if(s.isDirectory()){if(Zn(s.name))continue;r.push(...ve(i,t,n+1))}else s.isFile()&&s.name===Qn&&r.push(i)}return r}function Ps(e){return ve(e)}function Zn(e){return de(Ne,e)||e.startsWith(".")}function er(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 z=new Set;var T=class extends Error{reason;constructor(t){super(t),this.reason=t,this.name="InvalidServiceJsonError"}};function ke(e){return e instanceof Error?e.message:String(e)}function tr(e){let t;try{t=Rt.readFileSync(e,"utf-8")}catch(c){throw new T(`could not read file: ${ke(c)}`)}let n;try{n=JSON.parse(t)}catch(c){throw new T(`invalid JSON: ${ke(c)}`)}if(!er(n))throw new T("missing required fields (appName, runtime or appType)");let r=xe(n);if(r.length>0)throw new T(r.map(c=>`${c}: expected a string`).join("; "));let o=H(n,e);if(o.length>0)throw new T(o.join("; "));let s=n;for(let c of ye(n,e).warnings)z.has(c)||(z.add(c),console.warn(`\u26A0\uFE0F ${c}`));let i={...s,appType:s.appType||s.type},a=Xn(e);return{name:i.appName,path:a,configPath:e,config:i,stack:i.stack,port:i.port,type:i.appType}}function _t(e){let t=ve(e),n=[],r=[];for(let o of t)try{n.push(tr(o))}catch(s){r.push({path:o,reason:s instanceof T?s.reason:ke(s)})}return{resources:n,problems:r}}function nr(e){for(let t of e){let n=`skipped ${t.path}: ${t.reason}`;z.has(n)||(z.add(n),console.warn(`\u26A0\uFE0F ${n}`))}}function Ot(e){let{resources:t,problems:n}=_t(e);return nr(n),t}function J(){let e=E();if(!e)throw $.notInProject();return Ot(e)}function Fs(e){let t=e;if(!t){let n=E();if(!n)throw $.notInProject();t=_t(n)}if(t.problems.length>0)throw new Error(t.problems.map(n=>`Invalid service.json at ${n.path}: ${n.reason}`).join(`
|
|
19
|
-
`));return t.resources}function Us(e,t){let n=t??Ot(e);return rr(n)}function rr(e){let t=e||J(),n=new Set;for(let r of t)r.stack&&n.add(r.stack);return Array.from(n).sort()}function Ms(e=J()){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:Ye(o.length,"resource"),resources:o,resourceCount:o.length});return n.sort((r,o)=>r.name.localeCompare(o.name))}function Ls(e,t){return(t??J()).filter(r=>r.stack===e)}function Bs(e,t){return(t??J()).some(r=>r.stack===e)}var Te=5e3,$e=new M({ttlMs:Te}),we=new M({ttlMs:Te}),L=ct(Te);function Vs(){$e.clear(),we.clear(),L.reset()}function or(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===je)return"config";if(e==="schema.prisma"||e.includes("migration"))return"prisma";if(t){let n=t.split(`
|
|
20
|
-
`).slice(0,10).join(`
|
|
21
|
-
`);if(n.includes("GENERATED BY Flisk")||n.includes("AUTOGENERATED"))return"generated"}return"unknown"}function sr(e){let t=e.configPath;if(L.isValid()){let d=$e.get(t);if(d)return d}let n=e.path,r=Ee(e.configPath),o=r.mtime.toISOString(),s=r.mtime.toISOString(),i=ir(n),a=I(b(n,"Dockerfile")),c=I(b(n,"Tiltfile")),p=I(b(n,Q))||I(b(n,"docker-compose.yaml")),l=e.config?.appType,u=l||"backend";l||(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:a,hasTiltfile:c,hasDockerCompose:p,autogeneratedFiles:i,status:"unknown"};return $e.set(t,h),L.markUpdated(),h}function ir(e){let t=[];for(let r of Pe){let o=b(e,r);if(I(o)){let s=Ee(o),i=Yn(o,"utf-8");t.push({name:r,path:o,type:or(r,i),size:s.size,lastModified:s.mtime.toISOString()})}}let n=b(e,"prisma");if(I(n)){let r=qn(n);for(let o of r)if(o==="schema.prisma"||o.includes("migration")){let s=b(n,o),i=Ee(s);t.push({name:`prisma/${o}`,path:s,type:"prisma",size:i.size,lastModified:i.mtime.toISOString()})}}return t.sort((r,o)=>r.name.localeCompare(o.name))}function Gs(e){let t=e.name;if(L.isValid()){let c=we.get(t);if(c)return c}let n=e.resources.map(c=>sr(c)),r=n.map(c=>new Date(c.createdAt).getTime()),o=Math.min(...r),s=Math.max(...r),i=At(n.map(c=>c.status)),a={name:e.name,resourceCount:n.length,createdAt:new Date(o).toISOString(),lastModified:new Date(s).toISOString(),resources:n,overallStatus:i};return we.set(t,a),L.markUpdated(),a}var Hs=[De,"proxy"];export{Fe as a,ar as b,_ as c,De as d,cr as e,Ie as f,Q as g,ur as h,Ct as i,Dt as j,B as k,je as l,fr as m,pr as n,lr as o,dr as p,mr as q,hr as r,E as s,wr as t,U as u,Ar as v,Rr as w,G as x,Ir as y,Yt as z,He as A,Xt as B,Wr as C,Kr as D,Je as E,Zr as F,S as G,$ as H,eo as I,Zt as J,to as K,no as L,oe as M,ro as N,Ye as O,io as P,ao as Q,co as R,uo as S,fo as T,po as U,lo as V,mo as W,ho as X,ae as Y,go as Z,So as _,xo as $,yo as aa,Eo as ba,ko as ca,$o as da,wo as ea,C as fa,Xe as ga,Io as ha,O as ia,jo as ja,No as ka,Po as la,me as ma,In as na,pt as oa,ft as pa,Wo as qa,pe as ra,$n as sa,le as ta,Ko as ua,Ho as va,zo as wa,ds as xa,ms as ya,hs as za,gs as Aa,Ss as Ba,vt as Ca,ks as Da,ye as Ea,$s as Fa,ws as Ga,At as Ha,bn as Ia,An as Ja,Yo as Ka,Xo as La,Qo as Ma,Zo as Na,es as Oa,de as Pa,Ps as Qa,_t as Ra,nr as Sa,Ot as Ta,J as Ua,Fs as Va,Us as Wa,rr as Xa,Ms as Ya,Ls as Za,Bs as _a,Vs as $a,sr as ab,Gs as bb,Hs as cb};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
|
|
2
|
-
function x(r,e,t){let n=r.indexOf(e);if(n===-1)return r;let o=e.length,s=0,i="";do i+=r.slice(s,n)+e+t,s=n+o,n=r.indexOf(e,s);while(n!==-1);return i+=r.slice(s),i}function I(r,e,t,n){let o=0,s="";do{let i=r[n-1]==="\r";s+=r.slice(o,i?n-1:n)+e+(i?`\r
|
|
3
|
-
`:`
|
|
4
|
-
`)+t,o=n+1,n=r.indexOf(`
|
|
5
|
-
`,o)}while(n!==-1);return s+=r.slice(o),s}var F=(r=0)=>e=>`\x1B[${e+r}m`,T=(r=0)=>e=>`\x1B[${38+r};5;${e}m`,R=(r=0)=>(e,t,n)=>`\x1B[${38+r};2;${e};${t};${n}m`,$=r=>`\x1B[58;5;${r<90?r-30:r-90+8}m`,l={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],underlineDouble:["4:2",24],underlineCurly:["4:3",24],underlineDotted:["4:4",24],underlineDashed:["4:5",24],overline:[53,55],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],gray:[90,39],grey:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgGray:[100,49],bgGrey:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]},underlineColor:{underlineBlack:["58;5;0",59],underlineRed:["58;5;1",59],underlineGreen:["58;5;2",59],underlineYellow:["58;5;3",59],underlineBlue:["58;5;4",59],underlineMagenta:["58;5;5",59],underlineCyan:["58;5;6",59],underlineWhite:["58;5;7",59],underlineBlackBright:["58;5;8",59],underlineGray:["58;5;8",59],underlineGrey:["58;5;8",59],underlineRedBright:["58;5;9",59],underlineGreenBright:["58;5;10",59],underlineYellowBright:["58;5;11",59],underlineBlueBright:["58;5;12",59],underlineMagentaBright:["58;5;13",59],underlineCyanBright:["58;5;14",59],underlineWhiteBright:["58;5;15",59]}},M=Object.keys(l.modifier),y=Object.keys(l.color),E=Object.keys(l.bgColor),U=Object.keys(l.underlineColor),S=[...y,...E];function V(){let r=new Map;for(let[e,t]of Object.entries(l)){for(let[n,o]of Object.entries(t))l[n]={open:`\x1B[${o[0]}m`,close:`\x1B[${o[1]}m`},t[n]=l[n],r.set(Number.parseInt(o[0],10),o[1]);Object.defineProperty(l,e,{value:t,enumerable:!1})}return Object.defineProperty(l,"codes",{value:r,enumerable:!1}),l.color.close="\x1B[39m",l.bgColor.close="\x1B[49m",l.underlineColor.close="\x1B[59m",l.color.ansi=F(),l.color.ansi256=T(),l.color.ansi16m=R(),l.bgColor.ansi=F(10),l.bgColor.ansi256=T(10),l.bgColor.ansi16m=R(10),l.underlineColor.ansi=$,l.underlineColor.ansi256=T(20),l.underlineColor.ansi16m=R(20),Object.defineProperties(l,{rgbToAnsi256:{value(e,t,n){return e===t&&t===n?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(t/255*5)+Math.round(n/255*5)},enumerable:!1},hexToRgb:{value(e){let t=/[\da-f]{6}|[\da-f]{3}/i.exec(e.toString(16));if(!t)return[0,0,0];let[n]=t;n.length===3&&(n=[...n].map(s=>s+s).join(""));let o=Number.parseInt(n,16);return[o>>16&255,o>>8&255,o&255]},enumerable:!1},hexToAnsi256:{value:e=>l.rgbToAnsi256(...l.hexToRgb(e)),enumerable:!1},ansi256ToAnsi:{value(e){if(e<8)return 30+e;if(e<16)return 90+(e-8);let t,n,o;if(e>=232)t=((e-232)*10+8)/255,n=t,o=t;else{e-=16;let f=e%36;t=Math.floor(e/36)/5,n=Math.floor(f/6)/5,o=f%6/5}let s=Math.max(t,n,o)*2;if(s===0)return 30;let i=30+(Math.round(o)<<2|Math.round(n)<<1|Math.round(t));return s===2&&(i+=60),i},enumerable:!1},rgbToAnsi:{value:(e,t,n)=>l.ansi256ToAnsi(l.rgbToAnsi256(e,t,n)),enumerable:!1},hexToAnsi:{value:e=>l.ansi256ToAnsi(l.hexToAnsi256(e)),enumerable:!1}}),l}var W=V(),c=W;import A from"node:process";import K from"node:os";import v from"node:tty";function a(r,e=globalThis.Deno?globalThis.Deno.args:A.argv){let t=r.startsWith("-")?"":r.length===1?"-":"--",n=e.indexOf(t+r),o=e.indexOf("--");return n!==-1&&(o===-1||n<o)}var{env:u}=A,g;a("no-color")||a("no-colors")||a("color=false")||a("color=never")?g=0:(a("color")||a("colors")||a("color=true")||a("color=always"))&&(g=1);function L(){return/^\d+$/.test(u.FORCE_COLOR)}function z(){if("FORCE_COLOR"in u){if(u.FORCE_COLOR==="false")return 0;if(u.FORCE_COLOR==="true"||u.FORCE_COLOR.length===0)return 1;if(L())return Math.min(Number.parseInt(u.FORCE_COLOR,10),3)}}function H(r){return r===0?!1:{level:r,hasBasic:!0,has256:r>=2,has16m:r>=3}}function q(r,{streamIsTTY:e,sniffFlags:t=!0}={}){let n=z();n!==void 0&&(g=n);let o=t?g:n;if(o===0)return 0;if(t){if(a("color=16m")||a("color=full")||a("color=truecolor"))return 3;if(a("color=256"))return 2}if(o!==void 0&&L())return o;if("TF_BUILD"in u&&"AGENT_NAME"in u)return 1;if(r&&!e&&o===void 0)return 0;let s=o||0;if(u.TERM==="dumb")return s;if(A.platform==="win32"){let i=K.release().split(".");return Number(i[0])>=10&&Number(i[2])>=10586?Number(i[2])>=14931?3:2:1}if("CI"in u)return["GITHUB_ACTIONS","GITEA_ACTIONS","CIRCLECI"].some(i=>i in u)?3:["TRAVIS","APPVEYOR","GITLAB_CI","BUILDKITE","DRONE"].some(i=>i in u)||u.CI_NAME==="codeship"?1:s;if("TEAMCITY_VERSION"in u)return/^(?:9\.0*[1-9]\d*\.|\d{2,}\.)/.test(u.TEAMCITY_VERSION)?1:0;if(u.COLORTERM==="truecolor"||u.TERM==="xterm-kitty"||u.TERM==="xterm-ghostty"||u.TERM==="wezterm")return 3;if("TERM_PROGRAM"in u){let i=Number.parseInt((u.TERM_PROGRAM_VERSION||"").split(".",1)[0],10);switch(u.TERM_PROGRAM){case"iTerm.app":return i>=3?3:2;case"Apple_Terminal":return 2}}return/-256(?:color)?$/i.test(u.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(u.TERM)||"COLORTERM"in u?1:s}function _(r,e={}){let t=q(r,{streamIsTTY:r&&r.isTTY,...e});return H(t)}var J={stdout:_({isTTY:v.isatty(1)}),stderr:_({isTTY:v.isatty(2)})},w=J;var{stdout:j,stderr:G}=w,h=Symbol("GENERATOR"),b=Symbol("STYLER"),O=Symbol("IS_EMPTY"),C=Symbol("LEVEL"),m=Object.create(null),k=r=>{if(!Number.isSafeInteger(r)||r<0||r>3)throw new Error("The `level` should be an integer from 0 to 3")},Q={enumerable:!0,get(){return this[C]},set(r){k(r),this[C]=r}},X=(r,e={})=>{e.level!==void 0&&k(e.level);let t=j?j.level:0;r[C]=e.level===void 0?t:e.level};var Z=r=>{let e=(...t)=>t.join(" ");return X(e,r),Object.setPrototypeOf(e,p.prototype),e};function p(r){return Z(r)}Object.setPrototypeOf(p.prototype,Function.prototype);for(let[r,e]of Object.entries(c))m[r]={get(){let t=B(this,P(e.open,e.close,this[b]),this[O]);return Object.defineProperty(this,r,{value:t}),t}};m.visible={get(){let r=B(this,this[b],!0);return Object.defineProperty(this,"visible",{value:r}),r}};var ee=(r,e)=>{let t=c[e];if(r==="rgb"){let o=(i,f,d)=>t.ansi(c.rgbToAnsi(i,f,d));return[o,o,(i,f,d)=>t.ansi256(c.rgbToAnsi256(i,f,d)),t.ansi16m]}if(r==="hex"){let o=i=>t.ansi(c.hexToAnsi(i));return[o,o,i=>t.ansi256(c.hexToAnsi256(i)),i=>t.ansi16m(...c.hexToRgb(i))]}let n=o=>t.ansi(c.ansi256ToAnsi(o));return[n,n,t.ansi256,t.ansi256]},re=["rgb","hex","ansi256"];for(let r of re){let e=r[0].toUpperCase()+r.slice(1);for(let[t,n]of[[r,"color"],["bg"+e,"bgColor"],["underline"+e,"underlineColor"]]){let{close:o}=c[n],s=ee(r,n);m[t]={get(){let i=function(f,d,D){let Y=s[this.level](f,d,D);return B(this,P(Y,o,this[b]),this[O])};return Object.defineProperty(this,t,{value:i}),i}}}}var te=Object.defineProperties(()=>{},{...m,level:{enumerable:!0,get(){return this[h].level},set(r){this[h].level=r}}}),P=(r,e,t)=>{let n,o;return t===void 0?(n=r,o=e):(n=t.openAll+r,o=e+t.closeAll),{open:r,close:e,openAll:n,closeAll:o,parent:t}},B=(r,e,t)=>{let n=(...o)=>o.length===1?N(n,""+o[0]):o.length===2?N(n,`${o[0]??""} ${o[1]??""}`):N(n,o.join(" "));return Object.setPrototypeOf(n,te),n[h]=r[h]??r,n[b]=e,n[O]=t,n},N=(r,e)=>{if(r[h][C]<=0||!e)return r[O]?"":e;let t=r[b];if(t===void 0)return e;let{openAll:n,closeAll:o}=t;if(e.includes("\x1B"))for(;t!==void 0;)e=x(e,t.close,t.open),t=t.parent;let s=e.indexOf(`
|
|
6
|
-
`);return s!==-1&&(e=I(e,o,n,s)),n+e+o};Object.defineProperties(p.prototype,{...m,level:Q});var ne=p(),he=p({level:G?G.level:0});var be=ne;export{y as a,be as b};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
|
|
2
|
-
import{b as n}from"./chunk-CF46CD6R.js";var o=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"];function w(f){let r=process.stderr,i=r.isTTY===!0,s=0,t=f,a,l=()=>r.write(`\r\x1B[2K${n.cyan(o[s])} ${t}`);i?(l(),a=setInterval(()=>{s=(s+1)%o.length,l()},80)):r.write(`- ${t}
|
|
3
|
-
`);let c=(e,$)=>{a&&clearInterval(a),r.write(`${i?"\r\x1B[2K":""}${e} ${$??t}
|
|
4
|
-
`)};return{get text(){return t},set text(e){t=e,i||r.write(`- ${t}
|
|
5
|
-
`)},succeed:e=>c(n.green("\u2714"),e),fail:e=>c(n.red("\u2716"),e),warn:e=>c(n.yellow("\u26A0"),e)}}export{w as a};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
|
|
2
|
-
import{Ta as _,cb as A,d as u,k as S}from"./chunk-CBFVK3TF.js";import{existsSync as w,readFileSync as h}from"node:fs";import{join as i}from"node:path";var O=["postgres",u],y=["pre_alpha","alpha","beta","out_of_scope"];function D(e){return O.includes(e)}function b(e){try{return JSON.parse(h(i(e,".tdk",S),"utf-8"))}catch{return}}function d(e){try{return w(e)?h(e,"utf-8"):void 0}catch{return}}function k(e,s){let n=r=>{let t=r;for(;t<e.length&&/\s/.test(e[t]);)t+=1;return t},a=0;for(;;){let r=e.indexOf(s,a);if(r===-1)return;let t=n(r+s.length);if(e[t]==="="&&(t=n(t+1),e[t]==="[")){let o=e.indexOf("]",t+1);return o===-1?void 0:[...e.slice(t+1,o).matchAll(/"([^"]+)"|'([^']+)'/g)].map(f=>f[1]??f[2]??"")}a=r+s.length}}function N(e){let s=i(e,".tdk",".tdk-out","Tiltfile"),n=d(s);if(n)return k(n,"ALWAYS_ENABLED_INFRA")}function M(e){let s=i(e,".tdk",".tdk-out","spec.master"),n=d(s);if(n!==void 0)return/"database-management"\s*:\s*True/.test(n)}function x(e){let s=i(e,".tdk",".tdk-out"),n=d(i(s,"Tiltfile")),a=d(i(s,"spec.master")),r=d(i(s,"tdk-cli-ext","discovery","config.star")),t=d(i(s,"tdk-cli-ext","engine","topologies","tilt","config","profiles.star"));if(!n||!a||!r||!t)return!1;let o=a.match(/PRE_ALPHA_RESOURCES\s*=\s*\{([^}]*)\}/)?.[1],f=k(r,"CORE_INFRA");return/FOCUS_MODE\s*,\s*FOCUS_ENABLED_ALL\s*,\s*FOCUS_ENABLED_RESOURCES\s*=\s*Config\.apply_focus\(cfg\)/.test(n)&&/if FOCUS_MODE and FOCUS_ENABLED_ALL\s*:/.test(n)&&/"[^"]+"\s*:\s*True|'[^']+'\s*:\s*True/.test(o??"")&&(f?.includes("postgres")??!1)&&/["']postgres["']\s*:\s*["']database-management["']/.test(r)&&/for infra in CORE_INFRA_EXPORT\s*:/.test(t)&&/needed\[INFRA_STACK_MAP_EXPORT\[infra\]\]\s*=\s*True/.test(t)}function C(e){let s=b(e);if(!s)return!1;let n=s.phases??{};for(let r of y){let t=n[r]?.enabledStacks;if(Array.isArray(t)&&t.includes(u))return!0}let a=s.always_enabled_infra??A;return Array.isArray(a)&&a.includes(u)}function L(e,s){let n=new Set;for(let t of O)n.add(t);for(let t of s)n.add(t.name),t.stack&&n.add(t.stack);let a=b(e);if(a){let t=a.phases??{};for(let f of y){let l=t[f]?.enabledStacks;if(Array.isArray(l))for(let c of l)n.add(c)}let o=a.always_enabled_infra??A;if(Array.isArray(o))for(let f of o)n.add(f)}let r=N(e);if(Array.isArray(r))for(let t of r)n.add(t);return n}function $(e,s=_(e)){let n=C(e),a=N(e),r=Array.isArray(a)&&a.includes(u),t=M(e)===!0,o=n||r||t,f=!n&&x(e),l=L(e,s),c=[],E=[];for(let p of s){let P=p.config?.dependsOn??[],g=!1;for(let m of P){if(D(m)){g=!0;continue}l.has(m)||E.push({resource:p.name,name:m})}g&&c.push(p.name)}let T=o||c.length>0,F=o?"feature":c.length>0?"dependsOn":"none";return{featureOn:o,featureOnFromProjectJson:n,featureOnFromTiltfile:r,featureOnFromSpecMaster:t,focusWouldEnableDatabaseManagement:f,dependsOnUsers:c,willStart:T,reason:F,unknownDependsOnNames:E}}export{O as a,$ as b};
|