@north-light/crouter 0.3.347 → 0.3.348
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
`))!==-1;){const s
|
|
3
|
-
`)){f(),
|
|
1
|
+
var L=Object.defineProperty;var d=(e,t)=>L(e,"name",{value:t,configurable:!0});import{randomUUID as J}from"node:crypto";import{readFileSync as x,statSync as z}from"node:fs";import{resolve as G}from"node:path";import{request as C}from"node:http";import{request as A}from"node:https";import{validateDeclaredResult as H}from"../../../api/command-manifest/result.js";import{CrtrError as S}from"../../errors.js";import{envelopeClaimsStale as K,staleErrorDetails as V}from"../../manifest-stale.js";import{diag as W,recordPreviewError as Y,recordPreviewJsonLine as U,writeStdout as M}from"../../io.js";import{ExitCode as E}from"../../../types.js";import{isRecord as N}from"../../../shared/predicates.js";const P=1e4,Q=3e4,X=6e4,Z=250,ee=2e3,te=new Set(["ECONNREFUSED","ECONNRESET","EPIPE"]);class q extends Error{static{d(this,"ConnectionError")}detail;constructor(t){super(t),this.detail=t}}const ne=/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/,re=new Set(["internal","unknown_path","command_collision","cli_protocol_error"]);class D extends Error{static{d(this,"StreamIdleError")}}async function ve(e,t,n){const r=oe(e,t,n);if(e.rest.streaming===!0){await ue(e,r);return}const{status:a,body:o}=await se(e,r);if(a>=200&&a<300)return de(e,o);j(e,a,o)}d(ve,"invokeHttpLeaf");function oe(e,t,n){const r=new Map;for(const i of e.params)r.set(i.name,i);const a=Object.entries(e.rest.params),o=e.baseUrl??new URL(e.registration.endpoint).origin;let l=e.rest.path;for(const[i,c]of a){if(c.in!=="path")continue;const u=t[$(i)];l=l.split(`{${i}}`).join(ae(u))}const p=new URL(l,o);for(const[i,c]of a){if(c.in!=="query")continue;const u=$(i);R(r.get(i),u,t,n)&&p.searchParams.append(c.as??i,String(t[u]))}const s=ie(e,a,r,t,n),m=Object.keys(s).length>0?JSON.stringify(s):void 0;let y;const f=e.registration.authEnv;if(f!==void 0&&f!==""){const i=process.env[f];if(i===void 0||i==="")throw new S("auth_env_missing",`${T(e)}: environment variable ${f} is not set or empty`,E.USAGE,{field:f,received:f,next:`Export ${f} with the bearer token, then retry.`});y=`Bearer ${i}`}const h=[["Accept","application/json"],["Crtr-Request-Id",J()]];y!==void 0&&h.push(["Authorization",y]);for(const[i,c]of a){if(c.in!=="header")continue;const u=$(i);if(!R(r.get(i),u,t,n))continue;const w=c.as,g=String(t[u]);if(/[\r\n]/.test(g))throw new S("invalid_type",`${T(e)}: header "${w}" value must not contain a newline`,E.USAGE,{field:i,received:"(newline in header value)",next:"Remove newline characters from the value."});h.push([w,g])}return m!==void 0&&h.push(["Content-Type","application/json"]),{url:p,method:e.rest.method,headers:h,...m!==void 0?{body:m}:{}}}d(oe,"buildRequestPlan");function ie(e,t,n,r,a){const o=new Map;for(const[s,m]of t){if(m.in!=="body")continue;const y=m.as??s,f=o.get(y);f!==void 0?f.push(s):o.set(y,[s])}const l={};for(const[s,m]of o){const y=m.map(c=>({name:c,param:n.get(c)})),f=y.find(c=>c.param.kind!=="stdin"),h=y.find(c=>c.param.kind==="stdin");let i;f!==void 0&&R(f.param,$(f.name),r,a)?i={param:f.param,value:r[$(f.name)]}:h!==void 0&&R(h.param,$(h.name),r,a)&&(i={param:h.param,value:r[$(h.name)]}),i!==void 0&&(l[s]=I(e,i.param,i.value))}const p={...e.rest.body};return e.rest.bodyRoot!==void 0?p[e.rest.bodyRoot]=l:Object.assign(p,l),p}d(ie,"assembleBody");function I(e,t,n){if(t.kind==="context-file")return n;if((t.kind==="positional"||t.kind==="flag")&&t.type==="path"){if(Array.isArray(n))return n.map(l=>I(e,t,l));const r=String(n),a=G(process.cwd(),r);let o;try{o=z(a)}catch{throw O(e,t.name,r,"no file exists at that path","an existing local file path")}if(!o.isFile())throw O(e,t.name,r,"the path is not a regular file","a regular local file (not a directory, socket, or device)");try{return t.encoding==="base64"?x(a).toString("base64"):x(a,"utf8")}catch{throw O(e,t.name,r,"the file could not be read","a readable local file path")}}return n}d(I,"materializeBodyValue");function O(e,t,n,r,a){return new S("invalid_type",`${T(e)}: cannot read file for "${t}" \u2014 ${r}: ${n}`,E.USAGE,{field:t,received:n,next:`Pass ${a}, relative to the current directory or absolute.`})}d(O,"fileError");function R(e,t,n,r){return r!==void 0?r.providedParams.has(t):Object.prototype.hasOwnProperty.call(n,t)&&n[t]!==void 0}d(R,"isPresent");function ae(e){const t=String(e);return t==="."||t===".."?t.replace(/\./g,"%2E"):encodeURIComponent(t)}d(ae,"encodePathSegmentValue");function $(e){return e.replace(/-([a-z])/g,(t,n)=>n.toUpperCase())}d($,"paramKey");async function se(e,t){const n=e.timeouts?.requestMs??Q,r=Date.now()+n;let a=Z;for(;;)try{return await ce(e,t,r-Date.now())}catch(o){if(!(o instanceof q))throw o;if(r-Date.now()<=a)throw _(e,t,`${o.detail}; retried with the same request id until the ${n}ms deadline`);await new Promise(p=>setTimeout(p,a)),a=Math.min(a*2,ee)}}d(se,"requestUnary");function ce(e,t,n){const r=Math.min(e.timeouts?.connectMs??P,n),a=t.url.protocol==="https:"?A:C;return new Promise((o,l)=>{let p=!1,s=null,m=null;const y=d(()=>{s!==null&&clearTimeout(s),m!==null&&clearTimeout(m),s=null,m=null},"clearTimers"),f=d(u=>{p||(p=!0,y(),i.destroy(),l(u))},"fail"),h=d(u=>{p||(p=!0,y(),o(u))},"succeed"),i=a(t.url,{method:t.method},u=>{s!==null&&(clearTimeout(s),s=null);const w=[];u.on("data",g=>w.push(g)),u.on("end",()=>h({status:u.statusCode??0,body:Buffer.concat(w).toString("utf8")})),u.on("error",g=>f(F(e,t,g,"connection closed before the full response")))});for(const[u,w]of t.headers)i.setHeader(u,w);s=setTimeout(()=>f(_(e,t,`connection timed out after ${r}ms`)),r),m=setTimeout(()=>f(_(e,t,`request exceeded the ${n}ms timeout`)),n),i.on("socket",u=>{u.connecting?u.once("connect",()=>c()):c()});const c=d(()=>{s!==null&&(clearTimeout(s),s=null)},"clearConnectTimer");i.on("error",u=>f(F(e,t,u,"could not reach the backend"))),t.body!==void 0&&i.write(t.body),i.end()})}d(ce,"requestUnaryOnce");function F(e,t,n,r){const a=k(n),o=`${r} (${a})`;return te.has(a)?new q(o):_(e,t,o)}d(F,"transportFailure");function de(e,t){let n;try{n=JSON.parse(t)}catch{throw v(e,"response body was not valid JSON","a JSON object matching the declared output")}if(!N(n))throw v(e,`response body was not a JSON object (got ${me(n)})`,"a JSON object matching the declared output");const r=H(e.output,n);if(r!==null){const o=e.output.find(l=>l.name===r.field)?.type??"unknown";throw r.receivedType!==void 0?v(e,`output field "${r.field}" has the wrong type`,`${r.field}: ${o}`):v(e,`response is missing required output field "${r.field}"`,`a "${r.field}" field of type ${o}`)}return n}d(de,"mapUnary2xx");async function ue(e,t){const n=e.timeouts?.connectMs??P,r=e.timeouts?.streamIdleMs??X,a=t.url.protocol==="https:"?A:C,o=await new Promise((h,i)=>{let c=!1,u=null;const w=d(()=>{u!==null&&(clearTimeout(u),u=null)},"clearConnect"),g=a(t.url,{method:t.method},b=>{c||(c=!0,w(),h(b))});for(const[b,B]of t.headers)g.setHeader(b,B);u=setTimeout(()=>{c||(c=!0,g.destroy(),i(_(e,t,`connection timed out after ${n}ms`)))},n),g.on("socket",b=>{b.connecting?b.once("connect",w):w()}),g.on("error",b=>{c||(c=!0,w(),i(_(e,t,`could not reach the backend (${k(b)})`)))}),t.body!==void 0&&g.write(t.body),g.end()}),l=o.statusCode??0;if(!(l>=200&&l<300)){const h=await le(o);j(e,l,h)}let p=!1,s="",m=null;const y=d(()=>{m!==null&&clearTimeout(m),m=setTimeout(()=>o.destroy(new D),r)},"armIdle"),f=d(()=>{m!==null&&(clearTimeout(m),m=null)},"clearIdle");try{y();for await(const h of o){y(),s+=h.toString("utf8");let i;for(;(i=s.indexOf(`
|
|
2
|
+
`))!==-1;){const c=s.slice(0,i);if(s=s.slice(i+1),c.trim()==="")continue;if(p=!0,U(c),!await M(c+`
|
|
3
|
+
`)){f(),o.destroy();return}}}f(),s.trim()!==""&&(p=!0,U(s),await M(s));return}catch(h){f();const i=h instanceof D?`stream idle for ${r}ms`:`connection error (${k(h)})`;if(p){const c=`${T(e)}: stream interrupted (${i})`;W(`crtr: ${c}`),Y({error:"stream_interrupted",message:c,next:"Retry the command to begin a fresh stream."}),process.exitCode=E.NETWORK;return}throw _(e,t,i)}}d(ue,"requestStreaming");function j(e,t,n){const r=fe(t);let a;try{a=JSON.parse(n)}catch{a=void 0}if(N(a)){const o=a.error;if(N(o)&&typeof o.code=="string"&&typeof o.message=="string"){const l=o.code,p=o.message,s=typeof o.field=="string"?o.field:void 0,m=typeof o.next=="string"?o.next:"Inspect the backend response, then retry if appropriate.",y=ne.test(l)&&!re.has(l),f=K(o);throw new S(y?l:"cli_protocol_error",p,r,{...o.received!==void 0?{received:o.received}:{},...s!==void 0?{field:s}:{},...f?V(e.registration.name):{},http_status:t,next:m})}}throw new S("cli_http_error",`${T(e)}: request failed with HTTP ${t}`,r,{http_status:t,next:"Inspect the backend response, then retry if appropriate."})}d(j,"throwNon2xx");function fe(e){return e===400||e===401||e===403||e===422?E.USAGE:e===404?E.NOT_FOUND:e===409?E.AMBIGUOUS:E.GENERAL}d(fe,"deriveExit");function v(e,t,n){return new S("cli_protocol_error",`${T(e)}: ${t}. Expected ${n}.`,E.GENERAL,{received:t,next:`Run \`crtr pkg plugin update ${e.registration.name}\` or inspect the backend response.`})}d(v,"protocolError");function _(e,t,n){return new S("cli_unreachable",`${T(e)}: ${n}`,E.NETWORK,{received:t.url.origin,next:`Check connectivity to ${t.url.host} and retry; run \`crtr pkg plugin update ${e.registration.name}\` if the command surface changed.`})}d(_,"unreachable");function T(e){return`HTTP-transport plugin "${e.registration.name}" command \`${e.commandPath.join(" ")}\``}d(T,"label");function k(e){const t=e;return t?.code??t?.message??String(e)}d(k,"errCode");function le(e){return new Promise(t=>{const n=[];e.on("data",r=>n.push(r)),e.on("end",()=>t(Buffer.concat(n).toString("utf8"))),e.on("error",()=>t(Buffer.concat(n).toString("utf8")))})}d(le,"readAll");function me(e){return e===null?"null":Array.isArray(e)?"array":typeof e}d(me,"typeName");export{ve as invokeHttpLeaf};
|
package/package.json
CHANGED
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.348",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@north-light/crouter",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.348",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "GPL-3.0-only",
|
|
12
12
|
"workspaces": [
|
|
@@ -10859,28 +10859,28 @@
|
|
|
10859
10859
|
},
|
|
10860
10860
|
"packages/crouter-api": {
|
|
10861
10861
|
"name": "@north-light/crouter-api",
|
|
10862
|
-
"version": "0.3.
|
|
10862
|
+
"version": "0.3.348",
|
|
10863
10863
|
"license": "GPL-3.0-only"
|
|
10864
10864
|
},
|
|
10865
10865
|
"packages/crouter-env-docker": {
|
|
10866
10866
|
"name": "@north-light/crouter-env-docker",
|
|
10867
|
-
"version": "0.3.
|
|
10867
|
+
"version": "0.3.348",
|
|
10868
10868
|
"license": "GPL-3.0-only"
|
|
10869
10869
|
},
|
|
10870
10870
|
"packages/crouter-plugin": {
|
|
10871
10871
|
"name": "@north-light/crouter-plugin",
|
|
10872
|
-
"version": "0.3.
|
|
10872
|
+
"version": "0.3.348",
|
|
10873
10873
|
"license": "GPL-3.0-only",
|
|
10874
10874
|
"dependencies": {
|
|
10875
|
-
"@north-light/crouter-api": "^0.3.
|
|
10875
|
+
"@north-light/crouter-api": "^0.3.348"
|
|
10876
10876
|
}
|
|
10877
10877
|
},
|
|
10878
10878
|
"packages/crouter-sdk": {
|
|
10879
10879
|
"name": "@north-light/crouter-sdk",
|
|
10880
|
-
"version": "0.3.
|
|
10880
|
+
"version": "0.3.348",
|
|
10881
10881
|
"license": "GPL-3.0-only",
|
|
10882
10882
|
"dependencies": {
|
|
10883
|
-
"@north-light/crouter-api": "^0.3.
|
|
10883
|
+
"@north-light/crouter-api": "^0.3.348"
|
|
10884
10884
|
}
|
|
10885
10885
|
}
|
|
10886
10886
|
}
|