@codions/portta 0.0.0-develop.20261103044138.sha-3a0ea08 → 0.0.0-develop.20261103045401.sha-960d1fd

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/dist/cli.js CHANGED
@@ -773,9 +773,9 @@ t.push(` - hostname: ${jn(n.hostname)}`,` service: ${jn(n.service)}`)}return
773
773
  s=="string"?o.s:"";if(!s||!a||!c)throw new In("the token is missing the account, tunnel or secret field");if(!Qm.test(a))throw new In("the tunnel id inside the token is not a UUID");return{AccountTag:s,TunnelID:a,TunnelSecret:c}}i(YE,"parseTunnelToken");function XE(e){return`${JSON.stringify(e)}
774
774
  `}i(XE,"renderTunnelCredentials");var l2=/(Unauthorized|failed to authenticate|invalid tunnel secret|token is invalid|401)/i,u2=/(Couldn't start tunnel|validation failed|error parsing YAML|unable to parse config)/i,p2=/Registered tunnel connection/i;function QE(e){return!e.tokenConfigured||!e.zoneConfigured?{state:"not-configured",detail:e.tokenConfigured?"no domain has been set":"no tunnel token has been set",hint:"Settings -> Cloudflare Tunnel"}:e.enabled?l2.test(e.logTail)?{state:"auth-error",detail:"Cloudflare rejected the t\
775
775
  unnel token",hint:"the tunnel may have been deleted, or the token belongs to another account. Replace the token."}:u2.test(e.logTail)?{state:"config-error",detail:"the connector refused its configuration",hint:"portta tunnel status --logs"}:e.containerState!=="running"?{state:"disconnected",detail:e.containerState?`the connector container is ${e.containerState}`:"the connector container does not exist",hint:"portta up"}:p2.test(e.logTail)?{state:"connected",detail:"holding registered connections\
776
- to the Cloudflare edge",hint:null}:e.containerHealth==="starting"||!e.logTail?{state:"starting",detail:"the connector is establishing its connections",hint:null}:{state:"disconnected",detail:"the connector is running but has registered no connection",hint:"check outbound network access; the connector dials Cloudflare on 7844/udp and 443/tcp"}:{state:"configured",detail:"set up, and not enabled",hint:"enable it to start the connector"}}i(QE,"tunnelStatusFrom");import{stderr as d2,stdin as eA}from"node:process";import{createInterface as f2}from"node:readline/promises";var Fe={success:0,failure:1,usage:2,precondition:3,refused:4},_e=class extends Error{static{i(this,"CliError")}exitCode;hint;constructor(t,n=Fe.failure,r){super(t),this.name="CliError",this.exitCode=n,this.hint=r}},L=class extends _e{static{i(this,"PreconditionError")}constructor(t,n){super(t,Fe.precondition,n)}},U=class extends _e{static{i(this,"RefusedError")}constructor(t,n){super(t,Fe.refused,n)}},C=class extends _e{static{i(this,"UsageError")}constructor(t,n){super(t,Fe.usage,n)}};async function et(e,t){if(t)return;if(!eA.isTTY)throw new U(`${e}; confirmation is unavailable without a TTY`,"pass --yes to confirm non-interactively");let n=f2({input:eA,output:d2});try{let r=await n.question(`${e} [y/N] `);if(!/^y(es)?$/i.test(r.trim()))throw new U("operation cancelled")}finally{n.close()}}i(et,"confirm");import{existsSync as pr,readFileSync as nA}from"node:fs";import{dirname as h2,join as Et,resolve as vo}from"node:path";var tA={name:"@codions/portta",version:"0.0.0-develop.20261103044138.sha-3a0ea08",description:"Machine-first CLI for a shared Docker development gateway",keywords:["docker","docker-compose","traefik","development","gateway","devcontainer","reverse-proxy"],license:"MIT",type:"module",bin:{portta:"dist/cli.js"},files:["dist"],publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},scripts:{build:"node --import tsx scripts/build.mjs",typecheck:"tsc -p tsconfig.json --noEmit",test:"vi\
776
+ to the Cloudflare edge",hint:null}:e.containerHealth==="starting"||!e.logTail?{state:"starting",detail:"the connector is establishing its connections",hint:null}:{state:"disconnected",detail:"the connector is running but has registered no connection",hint:"check outbound network access; the connector dials Cloudflare on 7844/udp and 443/tcp"}:{state:"configured",detail:"set up, and not enabled",hint:"enable it to start the connector"}}i(QE,"tunnelStatusFrom");import{stderr as d2,stdin as eA}from"node:process";import{createInterface as f2}from"node:readline/promises";var Fe={success:0,failure:1,usage:2,precondition:3,refused:4},_e=class extends Error{static{i(this,"CliError")}exitCode;hint;constructor(t,n=Fe.failure,r){super(t),this.name="CliError",this.exitCode=n,this.hint=r}},L=class extends _e{static{i(this,"PreconditionError")}constructor(t,n){super(t,Fe.precondition,n)}},U=class extends _e{static{i(this,"RefusedError")}constructor(t,n){super(t,Fe.refused,n)}},C=class extends _e{static{i(this,"UsageError")}constructor(t,n){super(t,Fe.usage,n)}};async function et(e,t){if(t)return;if(!eA.isTTY)throw new U(`${e}; confirmation is unavailable without a TTY`,"pass --yes to confirm non-interactively");let n=f2({input:eA,output:d2});try{let r=await n.question(`${e} [y/N] `);if(!/^y(es)?$/i.test(r.trim()))throw new U("operation cancelled")}finally{n.close()}}i(et,"confirm");import{existsSync as pr,readFileSync as nA}from"node:fs";import{dirname as h2,join as Et,resolve as vo}from"node:path";var tA={name:"@codions/portta",version:"0.0.0-develop.20261103045401.sha-960d1fd",description:"Machine-first CLI for a shared Docker development gateway",keywords:["docker","docker-compose","traefik","development","gateway","devcontainer","reverse-proxy"],license:"MIT",type:"module",bin:{portta:"dist/cli.js"},files:["dist"],publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},scripts:{build:"node --import tsx scripts/build.mjs",typecheck:"tsc -p tsconfig.json --noEmit",test:"vi\
777
777
  test run",prepack:"npm run build",prepublishOnly:"npm run typecheck && npm test"},engines:{node:">=24"},repository:{type:"git",url:"git+https://github.com/codions-labs/portta.git",directory:"packages/cli"},homepage:"https://github.com/codions-labs/portta#readme",bugs:"https://github.com/codions-labs/portta/issues",dependencies:{"@clack/prompts":"^1.1.0",commander:"14.0.2",execa:"9.6.1",systeminformation:"^5.33.8",yaml:"^2.8.2",zod:"4.6.7"},devDependencies:{"@types/node":"24.13.3",esbuild:"0.28.2",
778
- "portta-contracts":"0.1.0","portta-core":"0.1.0",typescript:"7.0.2",vitest:"5.0.5",tsx:"4.23.15"}};var ur=tA.version,Gc="2026-11-03T04:43:18Z";function ai(){return`portta ${ur}${Gc?` (built ${Gc})`:""}`}i(ai,"cliVersionLine");var g2="0.0.0-local";function nh(e){return pr(Et(e,"docker","compose","compose.yaml"))?pr(Et(e,"VERSION"))||pr(Et(e,"packages","cli","package.json")):!1}i(nh,"isGatewayRoot");function rh(e){let t=Et(e,"VERSION");if(pr(t))return nA(t,"utf8").trim();let n=Et(e,"packages","cli","package.json");if(pr(n))return g2;throw new L(`missing generated VERSION in ${e}`,"reinstall the @codions/portta npm package")}i(rh,"versionForRoot");function b2(){let e=process.env.HOME;return[process.env.PORTTA_HOME,e?Et(
778
+ "portta-contracts":"0.1.0","portta-core":"0.1.0",typescript:"7.0.2",vitest:"5.0.5",tsx:"4.23.15"}};var ur=tA.version,Gc="2026-11-03T04:55:37Z";function ai(){return`portta ${ur}${Gc?` (built ${Gc})`:""}`}i(ai,"cliVersionLine");var g2="0.0.0-local";function nh(e){return pr(Et(e,"docker","compose","compose.yaml"))?pr(Et(e,"VERSION"))||pr(Et(e,"packages","cli","package.json")):!1}i(nh,"isGatewayRoot");function rh(e){let t=Et(e,"VERSION");if(pr(t))return nA(t,"utf8").trim();let n=Et(e,"packages","cli","package.json");if(pr(n))return g2;throw new L(`missing generated VERSION in ${e}`,"reinstall the @codions/portta npm package")}i(rh,"versionForRoot");function b2(){let e=process.env.HOME;return[process.env.PORTTA_HOME,e?Et(
779
779
  e,"portta"):void 0,"/opt/portta",e?Et(e,".portta"):void 0,"/var/lib/portta"].filter(t=>!!t)}i(b2,"wellKnownRoots");function oh(e=process.cwd()){let t=process.env.PORTTA_ROOT;if(t&&nh(vo(t)))return vo(t);let n=vo(e);for(;;){if(nh(n))return n;let r=h2(n);if(r===n)break;n=r}for(let r of b2())if(nh(vo(r)))return vo(r);return null}i(oh,"findGatewayRoot");function O(e={}){let t=e.root?vo(e.root):oh();if(!t){if(e.required===!1){let c={...process.env,PORTTA_PROFILE:e.profile??process.env.PORTTA_PROFILE},
780
780
  u=nr(c);return{root:process.cwd(),env:c,config:u,composeFiles:[],version:ur}}throw new L("no Portta installation found","run `portta setup`, set PORTTA_HOME, or run this inside the gateway directory")}let n=pr(Et(t,".env"))?me(nA(Et(t,".env"),"utf8")):new Map,r=Xr(n,process.env);for(let[c,u]of Object.entries(e.overrides??{}))r[c]=u;e.profile&&(r.PORTTA_PROFILE=e.profile),r.PORTTA_ROOT=t,Zv(r);let o=nr(r);r.PORTTA_DOMAIN=o.domain,r.PORTTA_BIND_ADDRESS=o.bindAddress;let s=qv(o);for(let c of s)if(!pr(
781
781
  Et(t,c)))throw new L(`missing compose file: ${c}`);let a=rh(t);return r.PORTTA_VERSION=a,{root:t,env:r,config:o,composeFiles:s,version:a}}i(O,"gatewayContext");function we(e){return["--project-directory",e.root,...e.composeFiles.flatMap(t=>["-f",Et(e.root,t)])]}i(we,"composeArguments");import{spawn as q4}from"node:child_process";import{closeSync as H4,openSync as Z4}from"node:fs";function xe(e){if(typeof e!="object"||e===null)return!1;let t=Object.getPrototypeOf(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Symbol.toStringTag in e)&&!(Symbol.iterator in e)}i(xe,"isPlainObject");import{fileURLToPath as y2}from"node:url";var So=i((e,t)=>{let n=ih(w2(e));if(typeof n!="string")throw new TypeError(`${t} must be a string or a file URL: ${n}.`);return n},"safeNormalizeFileUrl"),w2=i(e=>sh(e)?e.toString():e,"normalizeDenoExecPath"),sh=i(e=>typeof e!="string"&&e&&Object.getPrototypeOf(e)===String.prototype,"isDenoExecPath"),ih=i(e=>e instanceof URL?y2(e):e,"normalizeFileUrl");var Wc=i((e,t=[],n={})=>{let r=So(e,"First argument"),[o,s]=xe(t)?[[],t]:[t,n];if(!Array.isArray(o))throw new TypeError(`Second argument must be either an array of arguments or an options object: ${o}`);if(o.some(u=>typeof u=="object"&&u!==null))throw new TypeError(`Second argument must be an array of strings: ${o}`);let a=o.map(String),c=a.find(u=>u.includes("\0"));if(c!==void 0)throw new TypeError(`Arguments cannot contain null bytes ("\\0"): ${c}`);if(!xe(s))throw new TypeError(`Last argument\
@@ -1256,7 +1256,7 @@ Nothing in this project was modified. See docs/product/guides/adopting-projects.
1256
1256
  some(d=>d.labels["com.docker.compose.project"]===c))throw new U(`Compose project ${c} is already running`,"pass --no-check only when sharing it is intentional");let u=new T(as(t));u.json?u.data({namespace:c,base:Vr(s),suffix:a}):u.data(c)}i(pN,"namespaceCommand");var m7="this project's containers are gone; start them with the runner (PORTTA_RUNNER=true) or docker compose up in the working directory";async function Up(e,t,n){let r=(await J()).filter(m=>m.labels["com.docker.compose.project"]===e);
1257
1257
  if(r.length===0)throw new C(`no project '${e}' is running`,m7);let o=r.find(m=>m.labels["portta.managed"]==="true");if(o)throw new U(`refusing to ${t} ${o.name}: it is a Portta component`,"gateway components are restarted with portta restart");let s=r.map(m=>({service:m.labels["com.docker.compose.service"]??m.name,name:m.name,dependsOn:UE(m.labels[BE]),id:m.id,state:m.state})),a=Ym(s,"stop"),c=Ym(s,"start"),u=t==="restart"?[...a.map(m=>({...m,verb:"stop"})),...c.map(m=>({...m,verb:"start"}))]:(t===
1258
1258
  "stop"?a:c).map(m=>({...m,verb:t})),p=new T(as(n)),d=new Map(s.map(m=>[m.id,m.state])),f=0;for(let m of u){let h=d.get(m.id)??m.state;if(m.verb==="start"&&h==="running"||m.verb==="stop"&&h!=="running"&&h!=="restarting"){p.progress(`skip ${m.service} already ${m.verb==="start"?"running":"stopped"}`);continue}let g=await _("docker",[m.verb,m.id],{reject:!1});if(g.failed){f+=1,p.warning(`${m.verb} ${m.service}: ${g.stderr.trim()||g.stdout.trim()||"failed"}`);continue}d.set(m.id,m.verb==="start"?
1259
- "running":"exited"),p.progress(`ok ${m.verb} ${m.service}`)}if(f>0)throw new U(`${f} service(s) failed to ${t}`,"the rest of the project was still acted on")}i(Up,"projectAction");var v7=["compose.yaml","compose.yml","docker-compose.yaml","docker-compose.yml"],S7=new Set(["node_modules","lost+found","vendor","dist","build"]),x7=8,k7=5*6e4,_7=["/etc","/proc","/sys","/dev","/boot","/var/lib/docker","/var/run","/run"],P7=["/root","/home","/Users"];function E7(e){let t=e.split("/").filter(Boolean);return t.length<2||t.some(n=>n.startsWith("."))||P7.includes(e.replace(/\/+$/,""))?!1:!_7.some(n=>e===n||e.startsWith(`${n}/`))}i(E7,"isWalkableHome");function A7(e){return/(oci:\/\/|git\+[a-z]+:\/\/|git@[\w.-]+:|\b(?:file|path|extends):\s*['"]?https?:\/\/|^\s*-\s*['"]?https?:\/\/)/im.
1259
+ "running":"exited"),p.progress(`ok ${m.verb} ${m.service}`)}if(f>0)throw new U(`${f} service(s) failed to ${t}`,"the rest of the project was still acted on")}i(Up,"projectAction");var v7=["compose.yaml","compose.yml","docker-compose.yaml","docker-compose.yml"],S7=new Set(["node_modules","lost+found","vendor","dist","build"]),x7=8,k7=5*6e4,_7=["/etc","/proc","/sys","/dev","/boot","/var/lib/docker","/var/run","/run"],P7=/^\/(?:root|home|Users|home\/[^/]+|Users\/[^/]+)\/*$/;function E7(e){let t=e.split("/").filter(Boolean);return t.length<2||t.some(n=>n.startsWith("."))||P7.test(e)?!1:!_7.some(n=>e===n||e.startsWith(`${n}/`))}i(E7,"isWalkableHome");function A7(e){return/(oci:\/\/|git\+[a-z]+:\/\/|git@[\w.-]+:|\b(?:file|path|extends):\s*['"]?https?:\/\/|^\s*-\s*['"]?https?:\/\/)/im.
1260
1260
  test(e)}i(A7,"reachesOut");function O7(e){return lt(e,"state/discovery")}i(O7,"discoveryDir");function T7(e){try{let n=(hN(lt(e,".env"))?me(bN(lt(e,".env"),"utf8")):new Map).get("PORTTA_PROJECTS_HOME")?.trim(),r=n&&n!==""?n:qc(mN(),process.getuid?.()===0),o=Hc(r,e,mN());return E7(o)?o:null}catch{return null}}i(T7,"projectsHomeOf");function $7(e){let t=[],n=i((r,o)=>{if(t.length>=200||o>3)return;let s;try{s=gN(r)}catch{return}let a=v7.find(c=>s.includes(c));if(a&&o>0){let c=lt(r,a),u=dN(c,{throwIfNoEntry:!1}),
1261
1261
  p=w7(e,r).split(/[\\/]/).join("/");if(u?.isFile()&&DE(p)){t.push({path:p,composeFile:a,modifiedAt:Math.floor(u.mtimeMs/1e3)});return}}for(let c of s.sort()){if(c.startsWith(".")||S7.has(c))continue;let u=dN(lt(r,c),{throwIfNoEntry:!1});u?.isDirectory()&&!u.isSymbolicLink()&&n(lt(r,c),o+1)}},"walk");return n(e,0),t}i($7,"findComposeFolders");var ka=new Map;async function C7(e,t,n){let r="";try{r=bN(lt(e,t.path,t.composeFile),"utf8")}catch{return null}if(A7(r))return null;let o=await ow(lt(e,t.path)).
1262
1262
  catch(()=>null);return o?{version:1,path:t.path,composeFile:o.compose_file,project:o.project,domain:o.domain,adopted:o.gateway_overlay!==null,services:o.services.map(s=>({name:s.name,image:s.image,kind:s.kind,port:s.kind==="http"?s.container_ports[0]??s.expose[0]??null:null,publishedPorts:s.published_ports.map(a=>({host:String(a.host),container:String(a.container)})),containerName:s.container_name})),findings:{publishedHostPorts:o.findings.published_host_ports,fixedContainerNames:o.findings.fixed_container_names,
Binary file
@@ -1 +1 @@
1
- 0.0.0-develop.20261103044138.sha-3a0ea08
1
+ 0.0.0-develop.20261103045401.sha-960d1fd
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codions/portta",
3
- "version": "0.0.0-develop.20261103044138.sha-3a0ea08",
3
+ "version": "0.0.0-develop.20261103045401.sha-960d1fd",
4
4
  "description": "Machine-first CLI for a shared Docker development gateway",
5
5
  "keywords": [
6
6
  "docker",