@lensmcp/cluster 1.25.8 → 1.25.9
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/basic-ssl.js +1 -1
- package/build-host.js +1 -1
- package/build-scope-patterns.js +1 -1
- package/bundle-parent.js +1 -1
- package/checkout-cache.js +1 -1
- package/create-webpack-dev.js +1 -1
- package/create-webpack-prod.js +1 -1
- package/dev-devtool.js +1 -1
- package/devserver-notifier.js +1 -1
- package/devserver-transport.js +1 -1
- package/error-stack-release.js +1 -1
- package/executors/build/build.impl.js +1 -1
- package/executors/gateway/body-stall.js +1 -1
- package/executors/gateway/canonical-path.js +1 -1
- package/executors/gateway/client-ip.js +1 -1
- package/executors/gateway/gateway-errors.js +1 -1
- package/executors/gateway/gateway.impl.js +1 -1
- package/executors/gateway/gateway.lib.js +1 -1
- package/executors/gateway/health-check.js +1 -1
- package/executors/gateway/jwks-verify.js +1 -1
- package/executors/gateway/jwt-claims.js +1 -1
- package/executors/gateway/main.prod-gateway.js +2 -2
- package/executors/gateway/main.rollout.js +4 -4
- package/executors/gateway/manifest.js +1 -1
- package/executors/gateway/metrics.js +1 -1
- package/executors/gateway/otel-tracing.js +1 -1
- package/executors/gateway/prod-config.js +1 -1
- package/executors/gateway/prod-gateway.lib.js +1 -1
- package/executors/gateway/prod-runtime/access-log.js +1 -1
- package/executors/gateway/prod-runtime/app.js +1 -1
- package/executors/gateway/prod-runtime/auth.js +1 -1
- package/executors/gateway/prod-runtime/body-stall.js +1 -1
- package/executors/gateway/prod-runtime/cors.js +1 -1
- package/executors/gateway/prod-runtime/edge.js +1 -1
- package/executors/gateway/prod-runtime/handler.js +1 -1
- package/executors/gateway/prod-runtime/hooks.js +1 -1
- package/executors/gateway/prod-runtime/observability.js +1 -1
- package/executors/gateway/prod-runtime/rollout.js +1 -1
- package/executors/gateway/prod-runtime/routing.js +1 -1
- package/executors/gateway/prod-runtime/server.js +1 -1
- package/executors/gateway/prod-runtime/trust.js +1 -1
- package/executors/gateway/prod-runtime/upgrade.js +7 -7
- package/executors/gateway/prod-runtime/upstream.js +1 -1
- package/executors/gateway/providers-prod.js +1 -1
- package/executors/gateway/rate-limit.js +2 -2
- package/executors/gateway/registry-source.js +1 -1
- package/executors/gateway/rollout-ops.js +2 -2
- package/executors/gateway/runtime/act.js +1 -1
- package/executors/gateway/runtime/auth.js +1 -1
- package/executors/gateway/runtime/chooser.js +12 -12
- package/executors/gateway/runtime/control.js +2 -2
- package/executors/gateway/runtime/dev-auth.js +1 -1
- package/executors/gateway/runtime/discovery.js +1 -1
- package/executors/gateway/runtime/edge.js +1 -1
- package/executors/gateway/runtime/guest-graph.js +2 -2
- package/executors/gateway/runtime/guest-replay.js +2 -2
- package/executors/gateway/runtime/handler.js +1 -1
- package/executors/gateway/runtime/hmr-reload.js +1 -1
- package/executors/gateway/runtime/hooks.js +1 -1
- package/executors/gateway/runtime/instance.js +2 -2
- package/executors/gateway/runtime/lens-children.js +1 -1
- package/executors/gateway/runtime/lifecycle.js +3 -3
- package/executors/gateway/runtime/observability.js +2 -2
- package/executors/gateway/runtime/own-log.js +3 -3
- package/executors/gateway/runtime/pod-env.js +2 -2
- package/executors/gateway/runtime/pod-output.js +1 -1
- package/executors/gateway/runtime/pod-probe.js +1 -1
- package/executors/gateway/runtime/process-names.js +1 -1
- package/executors/gateway/runtime/project-graph-store.js +1 -1
- package/executors/gateway/runtime/proxy.js +1 -1
- package/executors/gateway/runtime/registration-guards.js +1 -1
- package/executors/gateway/runtime/route-registry.js +1 -1
- package/executors/gateway/runtime/scope.js +1 -1
- package/executors/gateway/runtime/serve-launch.js +3 -3
- package/executors/gateway/runtime/server.js +2 -2
- package/executors/gateway/runtime/service-keys.js +1 -1
- package/executors/gateway/runtime/shared-build.js +4 -4
- package/executors/gateway/runtime/source-poller.js +1 -1
- package/executors/gateway/runtime/types.js +1 -1
- package/executors/gateway/runtime/upgrade.js +1 -1
- package/executors/gateway/runtime/workspace-log.js +1 -1
- package/executors/gateway/runtime/workspace-middleware.js +1 -1
- package/executors/gateway/runtime/workspace-registry.js +1 -1
- package/executors/gateway/ssrf-guard.js +1 -1
- package/executors/serve/serve.impl.js +1 -1
- package/executors/trust/hostname.js +1 -1
- package/executors/trust/trust.impl.js +3 -3
- package/exit-reason.js +2 -2
- package/fork-ts-check-reporter.js +1 -1
- package/gateway.js +1 -1
- package/gc-notice.js +1 -1
- package/graph-snapshot.js +1 -1
- package/handoff-retire.js +1 -1
- package/heap-snapshot.js +1 -1
- package/hot-swap-registries.js +1 -1
- package/index.js +1 -1
- package/inspector-secret.js +1 -1
- package/main.devserver.js +11 -11
- package/notice-generation.js +1 -1
- package/package.json +4 -4
- package/perf/heavy-barrel-import.js +1 -1
- package/perf/perf-config.js +1 -1
- package/perf/perf-rule-events.js +2 -2
- package/perf/perf-rules-analysis.js +1 -1
- package/perf/perf-rules-plugin.js +1 -1
- package/perf/source-scan.js +5 -5
- package/perf/workspace-libraries.js +2 -2
- package/pod-memory-events.js +2 -2
- package/pod-memory.js +1 -1
- package/pod-sock.js +1 -1
- package/process-name.js +1 -1
- package/redis-disconnect-fix.js +1 -1
- package/schema-first-instance.js +1 -1
- package/serve-runner.js +1 -1
- package/service-build-events.js +1 -1
- package/shared-build/attach.js +2 -2
- package/shared-build/host.js +3 -3
- package/shared-build/protocol.js +1 -1
- package/shared-build/shared-compilation.js +3 -3
- package/shared-build/signature.js +1 -1
- package/stdio-guard.js +1 -1
- package/swap-mode.js +1 -1
- package/swap-recycle.js +1 -1
- package/tsgo-check-plugin.js +4 -4
- package/typecheck-bus.js +3 -3
- package/typecheck-queue.js +1 -1
- package/worker-supervisor.js +2 -2
- package/workspace-paths.js +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)[0]})`}return helpersByRoot.set(e,s),s}u(loadNxHelpers,"loadNxHelpers"),i(loadNxHelpers,"loadNxHelpers");const ROOT_DOTENV_LOAD=[".local.env",".env.local",".env"],ROOT_DOTENV_UNLOAD=[".env",".local.env",".env.local"];function nxExecutorEnv(e,r,s,o,_){const t={...s};t.FORCE_COLOR==="0"&&(t.NO_COLOR="1",delete t.FORCE_COLOR),e.loadAndExpandDotEnvFile(ROOT_DOTENV_LOAD.map(a=>path.join(r,a)),t),t.NX_CLI_SET="true",t.NX_VERBOSE_LOGGING=String(t.NX_VERBOSE_LOGGING==="true"),t.NX_TUI="false",t.NX_LOAD_DOT_ENV_FILES!=="false"&&(t.NX_LOAD_DOT_ENV_FILES="true");const n={...t};for(const a of ROOT_DOTENV_UNLOAD)e.unloadDotEnvFile(path.join(r,a),n);t.NX_LOAD_DOT_ENV_FILES==="true"&&e.loadAndExpandDotEnvFile(e.getEnvFilesForTask(o,_).map(a=>path.join(r,a)),n),n.FORCE_COLOR=t.FORCE_COLOR===void 0?"true":t.FORCE_COLOR,n.NX_WORKSPACE_ROOT=r,n.NX_TASK_TARGET_PROJECT=o.target.project,n.NX_TASK_TARGET_TARGET=o.target.target,o.target.configuration?n.NX_TASK_TARGET_CONFIGURATION=o.target.configuration:delete n.NX_TASK_TARGET_CONFIGURATION,n.LERNA_PACKAGE_NAME=o.target.project,n.NX_TUI="false",o.target.target==="test"&&(n.NX_TERMINAL_CAPTURE_STDERR="true");for(const a of["NX_TASK_HASH","NX_SKIP_NX_CACHE","NX_TERMINAL_OUTPUT_PATH","NX_STREAM_OUTPUT","NX_PREFIX_OUTPUT","NX_SET_CLI"])delete n[a];return(t.NX_SKIP_NX_CACHE==="true"||t.NX_DISABLE_NX_CACHE==="true")&&(n.NX_SKIP_NX_CACHE="true"),n.NX_FORKED_TASK_EXECUTOR="true",{env:n,isVerbose:t.NX_VERBOSE_LOGGING==="true"}}u(nxExecutorEnv,"nxExecutorEnv"),i(nxExecutorEnv,"nxExecutorEnv");function inferredBy(e,r,s){const o=e.sourceMaps?.[r],_=new Set([path.posix.join(r,"project.json"),path.posix.join(r,"package.json"),"nx.json"]),t=`targets.${s}`;let n=!1;for(const[a,[
|
|
3
|
-
`)[0]})`)}const
|
|
1
|
+
"use strict";var A=Object.defineProperty;var E=(e,r)=>A(e,"name",{value:r,configurable:!0});var T=Object.defineProperty,u=E((e,r)=>T(e,"name",{value:r,configurable:!0}),"u"),h=Object.defineProperty,i=u((e,r)=>h(e,"name",{value:r,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.RUNNER_ROOT_FLAG=exports.SERVE_RUNNER_ROLE=exports.SERVE_RUNNER_EXECUTOR=void 0,exports.serveRunnerEnabled=serveRunnerEnabled,exports.serveRunnerScript=serveRunnerScript,exports.serveRunnerArgs=serveRunnerArgs,exports.isServeRunnerCommand=isServeRunnerCommand,exports.isServeRunnerCommandOf=isServeRunnerCommandOf,exports.loadNxHelpers=loadNxHelpers,exports.nxExecutorEnv=nxExecutorEnv,exports.planServeLaunch=planServeLaunch;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),node_module_1=require("node:module"),path=tslib_1.__importStar(require("node:path"));exports.SERVE_RUNNER_EXECUTOR="@lensmcp/cluster:serve",exports.SERVE_RUNNER_ROLE="serve",exports.RUNNER_ROOT_FLAG="--workspace-root=";function serveRunnerEnabled(e=process.env){const r=(e.LENSMCP_SERVE_RUNNER??"").trim().toLowerCase();return!["0","off","false","no","nx"].includes(r)}E(serveRunnerEnabled,"serveRunnerEnabled"),u(serveRunnerEnabled,"serveRunnerEnabled"),i(serveRunnerEnabled,"serveRunnerEnabled");function serveRunnerScript(e=path.join(__dirname,"../../..")){const r=path.join(e,"serve-runner.js");if(fs.existsSync(r))return{path:r,execArgv:[]};const s=path.join(e,"serve-runner.ts");if(fs.existsSync(s))try{return{path:s,execArgv:["--require",require.resolve("@swc-node/register")]}}catch{return}}E(serveRunnerScript,"serveRunnerScript"),u(serveRunnerScript,"serveRunnerScript"),i(serveRunnerScript,"serveRunnerScript");function serveRunnerArgs(e,r,s){return["run",e,`--childCount=${r}`,`${exports.RUNNER_ROOT_FLAG}${s}`]}E(serveRunnerArgs,"serveRunnerArgs"),u(serveRunnerArgs,"serveRunnerArgs"),i(serveRunnerArgs,"serveRunnerArgs");function isServeRunnerCommand(e){return/\bserve-runner\.(js|ts)\b/.test(e)&&e.includes(` ${exports.RUNNER_ROOT_FLAG}`)}E(isServeRunnerCommand,"isServeRunnerCommand"),u(isServeRunnerCommand,"isServeRunnerCommand"),i(isServeRunnerCommand,"isServeRunnerCommand");function isServeRunnerCommandOf(e,r){return isServeRunnerCommand(e)&&e.trimEnd().endsWith(` ${exports.RUNNER_ROOT_FLAG}${r.replace(/\/+$/,"")}`)}E(isServeRunnerCommandOf,"isServeRunnerCommandOf"),u(isServeRunnerCommandOf,"isServeRunnerCommandOf"),i(isServeRunnerCommandOf,"isServeRunnerCommandOf");const helpersByRoot=new Map;function loadNxHelpers(e){const r=helpersByRoot.get(e);if(r)return r;let s;try{const o=(0,node_module_1.createRequire)(path.join(e,"package.json")),_=o("nx/package.json").version,t=o("nx/src/tasks-runner/task-env"),n=o("nx/src/tasks-runner/create-task-graph"),a=o("nx/src/config/nx-json"),l=o("nx/src/utils/cache-directory"),c=o.resolve("nx/src/command-line/run/run"),R=[["getEnvFilesForTask",t.getEnvFilesForTask],["loadAndExpandDotEnvFile",t.loadAndExpandDotEnvFile],["unloadDotEnvFile",t.unloadDotEnvFile],["createTaskGraph",n.createTaskGraph],["readNxJson",a.readNxJson],["workspaceDataDirectoryForWorkspace",l.workspaceDataDirectoryForWorkspace]].filter(([,N])=>typeof N!="function").map(([N])=>N);s=R.length>0?`nx ${_} has no ${R.join(", ")}`:{version:_,runModule:c,createTaskGraph:n.createTaskGraph,getEnvFilesForTask:t.getEnvFilesForTask,loadAndExpandDotEnvFile:t.loadAndExpandDotEnvFile,unloadDotEnvFile:t.unloadDotEnvFile,readNxJson:a.readNxJson,workspaceDataDirectoryForWorkspace:l.workspaceDataDirectoryForWorkspace}}catch(o){s=`cannot load the workspace's nx (${o.message.split(`
|
|
2
|
+
`)[0]})`}return helpersByRoot.set(e,s),s}E(loadNxHelpers,"loadNxHelpers"),u(loadNxHelpers,"loadNxHelpers"),i(loadNxHelpers,"loadNxHelpers");const ROOT_DOTENV_LOAD=[".local.env",".env.local",".env"],ROOT_DOTENV_UNLOAD=[".env",".local.env",".env.local"];function nxExecutorEnv(e,r,s,o,_){const t={...s};t.FORCE_COLOR==="0"&&(t.NO_COLOR="1",delete t.FORCE_COLOR),e.loadAndExpandDotEnvFile(ROOT_DOTENV_LOAD.map(a=>path.join(r,a)),t),t.NX_CLI_SET="true",t.NX_VERBOSE_LOGGING=String(t.NX_VERBOSE_LOGGING==="true"),t.NX_TUI="false",t.NX_LOAD_DOT_ENV_FILES!=="false"&&(t.NX_LOAD_DOT_ENV_FILES="true");const n={...t};for(const a of ROOT_DOTENV_UNLOAD)e.unloadDotEnvFile(path.join(r,a),n);t.NX_LOAD_DOT_ENV_FILES==="true"&&e.loadAndExpandDotEnvFile(e.getEnvFilesForTask(o,_).map(a=>path.join(r,a)),n),n.FORCE_COLOR=t.FORCE_COLOR===void 0?"true":t.FORCE_COLOR,n.NX_WORKSPACE_ROOT=r,n.NX_TASK_TARGET_PROJECT=o.target.project,n.NX_TASK_TARGET_TARGET=o.target.target,o.target.configuration?n.NX_TASK_TARGET_CONFIGURATION=o.target.configuration:delete n.NX_TASK_TARGET_CONFIGURATION,n.LERNA_PACKAGE_NAME=o.target.project,n.NX_TUI="false",o.target.target==="test"&&(n.NX_TERMINAL_CAPTURE_STDERR="true");for(const a of["NX_TASK_HASH","NX_SKIP_NX_CACHE","NX_TERMINAL_OUTPUT_PATH","NX_STREAM_OUTPUT","NX_PREFIX_OUTPUT","NX_SET_CLI"])delete n[a];return(t.NX_SKIP_NX_CACHE==="true"||t.NX_DISABLE_NX_CACHE==="true")&&(n.NX_SKIP_NX_CACHE="true"),n.NX_FORKED_TASK_EXECUTOR="true",{env:n,isVerbose:t.NX_VERBOSE_LOGGING==="true"}}E(nxExecutorEnv,"nxExecutorEnv"),u(nxExecutorEnv,"nxExecutorEnv"),i(nxExecutorEnv,"nxExecutorEnv");function inferredBy(e,r,s){const o=e.sourceMaps?.[r],_=new Set([path.posix.join(r,"project.json"),path.posix.join(r,"package.json"),"nx.json"]),t=`targets.${s}`;let n=!1;for(const[a,[l,c]]of Object.entries(o??{}))if(!(a!==t&&!a.startsWith(`${t}.`))&&(n=!0,!l||!_.has(l)))return`${c}${l?` (from ${l})`:""}`;return n?void 0:"a source the project graph does not record"}E(inferredBy,"inferredBy"),u(inferredBy,"inferredBy"),i(inferredBy,"inferredBy");function planServeLaunch(e){const r=i(p=>({kind:"nx",reason:p}),"nx");if(!serveRunnerEnabled(e.gatewayEnv??process.env))return r("LENSMCP_SERVE_RUNNER is off");if(!e.stores)return r("the gateway was started without an Nx project graph");const s=e.stores.get(e.root);if(!s)return r("a workspace registered into this gateway that it holds no project graph for");const o=s.current();if(!o)return s.refreshIfStale(),r(`no project graph${s.lastError()?` (${s.lastError()})`:""}`);const _=s.staleReason();if(_)return s.refreshIfStale(),r(_);const t=o.projectGraph.nodes[e.project],n=t?.data.targets?.[e.target];if(!t||!n)return r(`${e.project}:${e.target} is not in the project graph`);if(n.executor!==exports.SERVE_RUNNER_EXECUTOR)return r(`its executor is ${n.executor??"(none)"}, not ${exports.SERVE_RUNNER_EXECUTOR}`);if(!o.sourceMaps)return r("this nx reports no source maps, so the gateway cannot tell a declared target from an inferred one");const a=inferredBy(o,t.data.root,e.target);if(a)return r(`part of the target is inferred by ${a}`);const l=e.gatewayEnv??process.env;if(e.baseEnv.NX_CACHE_PROJECT_GRAPH==="false"||l.NX_CACHE_PROJECT_GRAPH==="false")return r("NX_CACHE_PROJECT_GRAPH=false \u2014 the executor reads nx's graph cache");const c=loadNxHelpers(e.root);if(typeof c=="string")return r(c);const R=e.script??serveRunnerScript();if(!R)return r("serve-runner.js is missing from @lensmcp/cluster");if(!fs.existsSync(path.join(c.workspaceDataDirectoryForWorkspace(e.root),"project-graph.json")))return r("nx has no project-graph cache on disk for the executor to read");const N={childCount:e.childCount,__overrides_unparsed__:[`--childCount=${e.childCount}`]};let v;try{v=c.createTaskGraph(o.projectGraph,{},[e.project],[e.target],void 0,N)}catch(p){return r(`nx could not build its task graph (${p.message.split(`
|
|
3
|
+
`)[0]})`)}const d=Object.values(v.tasks).find(p=>p.target.project===e.project&&p.target.target===e.target);if(!d)return r(`nx's task graph has no ${e.project}:${e.target}`);const f=Object.keys(v.tasks).filter(p=>p!==d.id);if(f.length>0)return r(`dependsOn: nx would run ${f.join(", ")} first`);const x=new Set(c.readNxJson(e.root).sync?.disabledTaskSyncGenerators??[]),O=(n.syncGenerators??[]).filter(p=>!x.has(p));if(O.length>0)return r(`sync generators nx would run first: ${O.join(", ")}`);d.startTime=Date.now();const{env:g,isVerbose:S}=nxExecutorEnv(c,e.root,e.baseEnv,d,o.projectGraph);return{kind:"runner",taskId:d.id,env:g,script:R,message:{nxRunModule:c.runModule,targetDescription:d.target,overrides:d.overrides,isVerbose:S,taskGraph:v}}}E(planServeLaunch,"planServeLaunch"),u(planServeLaunch,"planServeLaunch"),i(planServeLaunch,"planServeLaunch");
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var ge=Object.defineProperty;var A=(s,r)=>ge(s,"name",{value:r,configurable:!0});var he=Object.defineProperty,n=A((s,r)=>he(s,"name",{value:r,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.GATEWAY_H2_IDLE_SESSION_MS_DEFAULT=exports.GATEWAY_MAX_H2_STREAMS_DEFAULT=exports.GATEWAY_MAX_H2_SESSIONS_DEFAULT=exports.GATEWAY_MAX_CONNECTIONS_DEFAULT=exports.BENIGN_SOCKET_ERRNOS=void 0,exports.buildEdgeVerifierPool=buildEdgeVerifierPool,exports.classifyClientError=classifyClientError,exports.createClientErrorLogGate=createClientErrorLogGate,exports.retirePreviousWorkspace=retirePreviousWorkspace,exports.resolveMaxConnections=resolveMaxConnections,exports.h2BudgetFromEnv=h2BudgetFromEnv,exports.createH2Governor=createH2Governor,exports.startGateway=startGateway;const tslib_1=require("tslib"),http=tslib_1.__importStar(require("node:http")),path=tslib_1.__importStar(require("node:path")),discovery_1=require("./discovery"),scope_1=require("./scope"),route_registry_1=require("./route-registry"),act_1=require("./act"),control_1=require("./control"),workspace_middleware_1=require("./workspace-middleware"),workspace_registry_1=require("./workspace-registry"),service_keys_1=require("./service-keys"),source_poller_1=require("./source-poller"),client_ip_1=require("../client-ip"),workspace_log_1=require("./workspace-log"),own_log_1=require("./own-log"),observability_1=require("./observability"),lifecycle_1=require("./lifecycle"),process_names_1=require("./process-names"),project_graph_store_1=require("./project-graph-store"),serve_launch_1=require("./serve-launch"),process_name_1=require("../../../process-name"),protocol_1=require("../../../shared-build/protocol"),lens_children_1=require("./lens-children"),proxy_1=require("./proxy"),auth_1=require("./auth"),hooks_1=require("./hooks"),handler_1=require("./handler"),upgrade_1=require("./upgrade"),jwks_verify_1=require("../jwks-verify"),types_1=require("./types");function insecureLocalFetch(s,r){return new Promise((u,m)=>{const a=(s.startsWith("https:")?require("node:https"):require("node:http")).request(s,{method:"GET",headers:r?.headers,rejectUnauthorized:!1},w=>{const _=[];w.on("data",g=>_.push(g)),w.on("end",()=>{const g=w.statusCode??0,l=Buffer.concat(_).toString("utf8");u({ok:g>=200&&g<300,status:g,json:n(async()=>JSON.parse(l),"json")})})});a.on("error",m),a.end()})}A(insecureLocalFetch,"insecureLocalFetch"),n(insecureLocalFetch,"insecureLocalFetch");function buildEdgeVerifierPool(s){const r=process.env.LENSMCP_GW_JWKS_URL,u=process.env.LENSMCP_GW_JWT_ISS,m=new Map;let a;const w=n((_,g)=>{console.log(`[gateway] edge JWT: verifying via JWKS ${_}${g}`);const l=(0,jwks_verify_1.createJwksVerifier)({jwksUrl:_,...u?{issuer:u}:{},fetchImpl:insecureLocalFetch});return l.refresh().catch(o=>console.warn("[gateway] edge JWKS warm failed (will retry):",o.message)),l},"make");return{for(_){if(r)return a??=w(r,"");const g=_.split(":")[0].toLowerCase();let l;for(const d of s()){const S=d.host;if(typeof S!="string"||!/^auth\./.test(S)||S.startsWith("internal."))continue;const T=S.slice(5);(g===T||g.endsWith(`.${T}`))&&(!l||T.length>l.length)&&(l=T)}if(!l)return;let o=m.get(l);return o||(o=w(`https://auth.${l}/jwks.json`,` (auto-derived for apex ${l})`),m.set(l,o)),o},stop(){a?.stop();for(const _ of m.values())_.stop()}}}A(buildEdgeVerifierPool,"buildEdgeVerifierPool"),n(buildEdgeVerifierPool,"buildEdgeVerifierPool"),exports.BENIGN_SOCKET_ERRNOS=new Set(["ECONNRESET","EPIPE","ETIMEDOUT","ECONNABORTED","ECANCELED"]);function classifyClientError(s,r){return s&&exports.BENIGN_SOCKET_ERRNOS.has(s)?{status:null,report:!1,cause:"client-abort"}:s==="HPE_INVALID_EOF_STATE"?{status:null,report:!1,cause:"truncated-at-eof"}:s==="ERR_HTTP_REQUEST_TIMEOUT"?{status:408,report:!0,cause:"request-timeout"}:s==="HPE_HEADER_OVERFLOW"?{status:431,report:!0,cause:"header-overflow"}:s?.startsWith("HPE_")?{status:400,report:!0,cause:"parse-error"}:{status:400,report:!0,cause:s??r??"unknown"}}A(classifyClientError,"classifyClientError"),n(classifyClientError,"classifyClientError");const CLIENT_ERROR_REASON={400:"Bad Request",408:"Request Timeout",431:"Request Header Fields Too Large"};function createClientErrorLogGate(s=1e4){const r=new Map;return u=>{const m=Date.now(),a=r.get(u)??0;return m-a<s?!1:(r.set(u,m),!0)}}A(createClientErrorLogGate,"createClientErrorLogGate"),n(createClientErrorLogGate,"createClientErrorLogGate");function guardInboundSocket(s){s.on("error",r=>{exports.BENIGN_SOCKET_ERRNOS.has(r.code??"")||console.warn(`[gateway] inbound socket error (${r.code??r.message}) \u2014 dropping this connection only`),s.destroy()})}A(guardInboundSocket,"guardInboundSocket"),n(guardInboundSocket,"guardInboundSocket");function retirePreviousWorkspace(s,r,u){const m=s.get(r);if(!m)return!1;s.delete(r),u==="re-registered"&&console.log(`[gateway] workspace '${r}' re-registered \u2014 retiring the children of its previous registration first.`);try{m()}catch(a){console.warn(`[gateway] could not fully retire the previous registration of '${r}' (${u}): ${a.message}`)}return!0}A(retirePreviousWorkspace,"retirePreviousWorkspace"),n(retirePreviousWorkspace,"retirePreviousWorkspace"),exports.GATEWAY_MAX_CONNECTIONS_DEFAULT=512,exports.GATEWAY_MAX_H2_SESSIONS_DEFAULT=64,exports.GATEWAY_MAX_H2_STREAMS_DEFAULT=4096,exports.GATEWAY_H2_IDLE_SESSION_MS_DEFAULT=3e5;function parseBudget(s,r){if(s===void 0||s.trim()==="")return r;const u=Number(s);return!Number.isFinite(u)||u<0?r:Math.floor(u)}A(parseBudget,"parseBudget"),n(parseBudget,"parseBudget");function resolveMaxConnections(s){return parseBudget(s,exports.GATEWAY_MAX_CONNECTIONS_DEFAULT)}A(resolveMaxConnections,"resolveMaxConnections"),n(resolveMaxConnections,"resolveMaxConnections");function h2BudgetFromEnv(s=process.env){return{maxSessions:parseBudget(s.LENSMCP_MAX_H2_SESSIONS,exports.GATEWAY_MAX_H2_SESSIONS_DEFAULT),maxStreams:parseBudget(s.LENSMCP_MAX_H2_STREAMS,exports.GATEWAY_MAX_H2_STREAMS_DEFAULT),idleSessionMs:parseBudget(s.LENSMCP_H2_IDLE_MS,exports.GATEWAY_H2_IDLE_SESSION_MS_DEFAULT)}}A(h2BudgetFromEnv,"h2BudgetFromEnv"),n(h2BudgetFromEnv,"h2BudgetFromEnv");function createH2Governor(s,r){const{NGHTTP2_ENHANCE_YOUR_CALM:u,NGHTTP2_REFUSED_STREAM:m}=require("node:http2").constants,a=new Map;let w=0;const _=n(o=>{o.idle&&(clearTimeout(o.idle),o.idle=void 0)},"disarm"),g=n((o,d)=>{_(d),!(s.idleSessionMs<=0||d.open>0)&&(d.idle=setTimeout(()=>{o.destroyed||o.closed||(r("session-reclaimed",{idleMs:s.idleSessionMs,sessions:a.size}),a.delete(o),o.close())},s.idleSessionMs),d.idle.unref?.())},"arm"),l=n(()=>{for(const[o,d]of a)if(!(d.open>0||o.destroyed))return _(d),a.delete(o),r("session-reclaimed",{reason:"cap",sessions:a.size+1,maxSessions:s.maxSessions}),o.close(),!0;return!1},"reclaimOldestIdle");return{admitSession(o){if(s.maxSessions>0&&a.size>=s.maxSessions&&!l()){r("session-refused",{sessions:a.size,maxSessions:s.maxSessions,streams:w});try{o.goaway(u)}catch{}try{o.close()}catch{}return!1}const d={open:0};return a.set(o,d),g(o,d),o.once("close",()=>{_(d),a.delete(o)}),!0},admitStream(o,d){const S=a.get(o);if(!S)return!0;if(s.maxStreams>0&&w>=s.maxStreams){r("stream-refused",{streams:w,maxStreams:s.maxStreams,sessions:a.size});try{d.close(m)}catch{}return!1}return w+=1,S.open+=1,_(S),d.once("close",()=>{w=Math.max(0,w-1),S.open=Math.max(0,S.open-1),S.open===0&&a.has(o)&&g(o,S)}),!0},dispose(){for(const o of a.values())_(o);a.clear()}}}A(createH2Governor,"createH2Governor"),n(createH2Governor,"createH2Governor");async function startGateway(s,r){const u=s.https!==!1,m=s.ports?.length?s.ports:[443],a=s.scanTtlMs??1500,w=s.startupTimeoutMs??12e4,_=s.sweepMs??1e4,g=s.trafficFlushMs??5e3;let l=!1;const o=process.env.LENSMCP_EVENT_FILE??path.join(r.root,".lensmcp","events.jsonl"),d=(0,own_log_1.startOwnLogRotation)(r.root),S=(0,scope_1.readLensScope)(r.root),T=S.key,x=S.sockNs!==T?S.sockNs:void 0,X=r.projectsConfigurations?.projects??{},J=(0,discovery_1.projectSourceRoots)(r.root,X,r.projectDependencies),{routes:G,services:N,instance:V}=(0,discovery_1.discoverRoutes)(r.root,X,void 0,T,J,x,S.instance);if(G.length===0)throw new Error("[gateway] no project declares a `cluster` field \u2014 nothing to route.");const j=new route_registry_1.RouteRegistry;j.register({wsKey:T,...x?{sockNs:x}:{},root:r.root,routes:G,services:N,...V?{instance:V}:{}});const R=[];let z=n(()=>{},"refreshCert");const Q=n(()=>{(0,route_registry_1.rebuildRoutesInPlace)(R,j),z()},"rebuildRoutes");Q();const{serviceKeys:ae,keyToProject:ie,keyToWorkspace:ce}=(0,service_keys_1.loadServiceKeys)(r.root,N,T),le=(0,client_ip_1.createClientIpResolver)({...(0,client_ip_1.clientIpOptionsFromEnv)(),...s.trustProxyHops!==void 0?{trustProxyHops:s.trustProxyHops}:{},...s.clientIpHeader?{clientIpHeader:s.clientIpHeader}:{},...s.clientIpTrustedProxies?{clientIpTrustedProxies:s.clientIpTrustedProxies}:{}}),E={root:r.root,wsKey:T,...x?{sockNs:x}:{},eventFile:o,routes:R,registry:j,rebuildRoutes:Q,services:N,serviceKeys:ae,keyToProject:ie,keyToWorkspace:ce,clientIp:le,bodyStallMs:s.bodyStallMs??types_1.BODY_STALL_MS,scanTtlMs:a,startupTimeoutMs:w,sweepMs:_,trafficFlushMs:g,https:u,projectRoots:Object.fromEntries(Object.entries(r.projectsConfigurations?.projects??{}).map(([e,t])=>[e,path.resolve(r.root,t.root)])),projectSourceRoots:J,...r.projectGraphStore?{graphStores:(0,project_graph_store_1.createProjectGraphStores)(r.projectGraphStore)}:{},...s.sharedCompiler!==void 0?{sharedCompiler:s.sharedCompiler}:{},stopped:n(()=>l,"stopped")};(0,process_name_1.prelinkProcessNames)((0,process_names_1.gatewayProcessNames)(N,{runner:(0,serve_launch_1.serveRunnerEnabled)()&&!!r.projectGraphStore,sharedBuild:(0,protocol_1.sharedCompilerEnabled)(process.env,s.sharedCompiler),label:T||path.basename(r.root),lens:{key:T,dashboard:s.dashboard!==!1,mcp:s.mcp!==!1&&G.some(e=>!!e.lens)}}));const f=(0,observability_1.createObservability)(o,{trafficFlushMs:g}),ue=createClientErrorLogGate(),k=h2BudgetFromEnv(),de=createClientErrorLogGate(3e4),q=createH2Governor(k,(e,t)=>{de(e)&&console.warn(`[gateway] h2 aggregate budget: ${e} (${JSON.stringify(t)}). These are the FRONT DOOR's ceilings, not an upstream's \u2014 raise/disable with LENSMCP_MAX_H2_SESSIONS / LENSMCP_MAX_H2_STREAMS / LENSMCP_H2_IDLE_MS / LENSMCP_MAX_CONNECTIONS (0 = unbounded).`),f.emit(e==="session-reclaimed"?"info":"warning",`h2 aggregate budget: ${e}`,`gateway-h2-budget:${e}`,{kind:"h2-aggregate-budget",event:e,project:"gateway",...t})}),v=(0,lifecycle_1.createServiceLayer)(E,f),L=(0,lens_children_1.createLensChildren)(E,f,s),W=new Map;let D;if(s.middleware){const e=require(path.resolve(r.root,s.middleware));D=e.default??e}const K=(0,workspace_middleware_1.createWorkspaceMiddleware)({ownerKey:T,...D?{owner:D}:{},policy:(0,workspace_middleware_1.guestMiddlewarePolicy)()}),O=process.env.LENSMCP_GW_ACT==="0"?void 0:(0,act_1.createActStore)({dir:path.join(path.dirname((0,control_1.controlSocketPath)()),"identities")});let b;try{b=(0,control_1.startControlServer)({rt:E,killService:n((e,t)=>v.killSpawned(e,t),"killService"),restartService:n((e,t)=>v.restartService(e,t),"restartService"),...O?{act:O}:{},onRegister:n(async e=>{retirePreviousWorkspace(W,e.wsKey,"re-registered"),K.set(e.wsKey,e.root,e.middleware);const t=await L.hostWorkspaceDashboard(e),h=await L.hostWorkspaceApps(e);W.set(e.wsKey,()=>{try{t?.()}finally{h()}})},"onRegister"),onUnregister:n(e=>{retirePreviousWorkspace(W,e.wsKey,"unregistered"),K.drop(e.wsKey),v.stopBuildHost(e.root)},"onUnregister")})}catch(e){console.warn("[gateway] control plane failed to start (multi-workspace register disabled):",e.message)}const I=(0,proxy_1.createProxy)(E,f,v),Z=buildEdgeVerifierPool(()=>E.routes),ee=(0,auth_1.createEdgeAuth)(E,f,Z,O),pe=n(e=>{const t=e.route?.wsKey,h=K.for(t);if(h)try{const i=t?E.registry.get(t):void 0;h(e.req,{...t?{wsKey:t}:{},...i?{root:i.root}:{},env:i?.instance?.env??{}})}catch(i){f.traceStep(e.trace,"auth",{mode:"middleware",ok:!1,reason:i.message}),e.route&&f.finishTrace(e.trace,e.route.project,401),e.sendError(401,"unauthorized",`Gateway middleware rejected the request: ${i.message}`)}},"builtinMiddleware"),se=s.hooks??{},re=(0,hooks_1.createHooks)({...se,afterAuth:[pe,...se.afterAuth??[]]}),te=(0,handler_1.createHandler)({rt:E,obs:f,auth:ee,proxy:I,hooks:re}),oe=(0,upgrade_1.createUpgrade)({rt:E,auth:ee,proxy:I,hooks:re,obs:f}),_e=f.startEdgeFlusher(),Se=v.startSweeper(),ne=(0,source_poller_1.createSourcePoller)({services:n(()=>E.registry.allServices(),"services"),serviceKey:n(e=>E.serviceKeys[(0,service_keys_1.serviceKeyId)(e.wsKey,e.project)],"serviceKey"),emit:n((e,t,h,i,p)=>f.emit(t,h,i,{wsKey:e.wsKey,...p},void 0,e.wsKey===E.wsKey?void 0:path.join(e.root,".lensmcp","events.jsonl")),"emit"),scanTtlMs:a,stopped:n(()=>l,"stopped")});(0,source_poller_1.sourcesEnabled)()&&ne.start(),await L.bootSingletonsAndApps();for(const e of N)e.decl.eager&&v.ensureUp(e);let P,F,H;if(u){const e=require("../../../basic-ssl"),t=(0,service_keys_1.gatewayCacheDir)(r.root);H=n(()=>e.getCertificateSync(t,"gateway",E.routes.map(h=>h.host).filter(h=>!!h)),"mintCert"),P=H(),F=e.caCertPath()}const U=[],$=[],Y=s.maxConnections??resolveMaxConnections(process.env.LENSMCP_MAX_CONNECTIONS);for(const e of m){const t=P?require("node:http2").createSecureServer({key:P,cert:P,allowHTTP1:!0,maxSessionMemory:512,settings:{maxConcurrentStreams:512},peerMaxConcurrentStreams:512,streamResetBurst:s.h2ResetBurst??types_1.GATEWAY_H2_RESET_BURST,streamResetRate:s.h2ResetRate??types_1.GATEWAY_H2_RESET_RATE},(i,p)=>te(i,p)):http.createServer(te);t.on("upgrade",oe),t.on("error",i=>console.error(`[gateway] port ${e}: ${i.code}`)),t.on("connection",guardInboundSocket),t.on("secureConnection",guardInboundSocket),t.on("tlsClientError",(i,p)=>p.destroy()),t.on("clientError",(i,p)=>{const c=i,y=classifyClientError(c.code,c.message);if(y.report&&ue(y.cause)){const C=p.remoteAddress??"unknown",M=y.status===null?"dropped":String(y.status);console.warn(`[gateway] inbound H1 clientError from ${C}: ${y.cause} (${c.code??c.message}${c.bytesParsed!==void 0?`, bytesParsed=${c.bytesParsed}`:""}) \u2192 ${M}. This status is the GATEWAY's, not the upstream service's.`),f.emit("warning",`inbound clientError: ${y.cause} \u2192 ${M}`,`gateway-client-error:${y.cause}`,{kind:"gateway-client-error",cause:y.cause,code:c.code??null,status:y.status,peer:C,bytesParsed:c.bytesParsed??null})}y.status!==null&&p.writable&&p.end(`HTTP/1.1 ${y.status} ${CLIENT_ERROR_REASON[y.status]}\r
|
|
1
|
+
"use strict";var me=Object.defineProperty;var v=(r,t)=>me(r,"name",{value:t,configurable:!0});var ge=Object.defineProperty,A=v((r,t)=>ge(r,"name",{value:t,configurable:!0}),"A"),he=Object.defineProperty,n=A((r,t)=>he(r,"name",{value:t,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.GATEWAY_H2_IDLE_SESSION_MS_DEFAULT=exports.GATEWAY_MAX_H2_STREAMS_DEFAULT=exports.GATEWAY_MAX_H2_SESSIONS_DEFAULT=exports.GATEWAY_MAX_CONNECTIONS_DEFAULT=exports.BENIGN_SOCKET_ERRNOS=void 0,exports.buildEdgeVerifierPool=buildEdgeVerifierPool,exports.classifyClientError=classifyClientError,exports.createClientErrorLogGate=createClientErrorLogGate,exports.retirePreviousWorkspace=retirePreviousWorkspace,exports.resolveMaxConnections=resolveMaxConnections,exports.h2BudgetFromEnv=h2BudgetFromEnv,exports.createH2Governor=createH2Governor,exports.startGateway=startGateway;const tslib_1=require("tslib"),http=tslib_1.__importStar(require("node:http")),path=tslib_1.__importStar(require("node:path")),discovery_1=require("./discovery"),scope_1=require("./scope"),route_registry_1=require("./route-registry"),act_1=require("./act"),control_1=require("./control"),workspace_middleware_1=require("./workspace-middleware"),workspace_registry_1=require("./workspace-registry"),service_keys_1=require("./service-keys"),source_poller_1=require("./source-poller"),client_ip_1=require("../client-ip"),workspace_log_1=require("./workspace-log"),own_log_1=require("./own-log"),observability_1=require("./observability"),lifecycle_1=require("./lifecycle"),process_names_1=require("./process-names"),project_graph_store_1=require("./project-graph-store"),serve_launch_1=require("./serve-launch"),process_name_1=require("../../../process-name"),protocol_1=require("../../../shared-build/protocol"),lens_children_1=require("./lens-children"),proxy_1=require("./proxy"),auth_1=require("./auth"),hooks_1=require("./hooks"),handler_1=require("./handler"),upgrade_1=require("./upgrade"),jwks_verify_1=require("../jwks-verify"),types_1=require("./types");function insecureLocalFetch(r,t){return new Promise((u,m)=>{const a=(r.startsWith("https:")?require("node:https"):require("node:http")).request(r,{method:"GET",headers:t?.headers,rejectUnauthorized:!1},w=>{const _=[];w.on("data",g=>_.push(g)),w.on("end",()=>{const g=w.statusCode??0,l=Buffer.concat(_).toString("utf8");u({ok:g>=200&&g<300,status:g,json:n(async()=>JSON.parse(l),"json")})})});a.on("error",m),a.end()})}v(insecureLocalFetch,"insecureLocalFetch"),A(insecureLocalFetch,"insecureLocalFetch"),n(insecureLocalFetch,"insecureLocalFetch");function buildEdgeVerifierPool(r){const t=process.env.LENSMCP_GW_JWKS_URL,u=process.env.LENSMCP_GW_JWT_ISS,m=new Map;let a;const w=n((_,g)=>{console.log(`[gateway] edge JWT: verifying via JWKS ${_}${g}`);const l=(0,jwks_verify_1.createJwksVerifier)({jwksUrl:_,...u?{issuer:u}:{},fetchImpl:insecureLocalFetch});return l.refresh().catch(s=>console.warn("[gateway] edge JWKS warm failed (will retry):",s.message)),l},"make");return{for(_){if(t)return a??=w(t,"");const g=_.split(":")[0].toLowerCase();let l;for(const d of r()){const S=d.host;if(typeof S!="string"||!/^auth\./.test(S)||S.startsWith("internal."))continue;const T=S.slice(5);(g===T||g.endsWith(`.${T}`))&&(!l||T.length>l.length)&&(l=T)}if(!l)return;let s=m.get(l);return s||(s=w(`https://auth.${l}/jwks.json`,` (auto-derived for apex ${l})`),m.set(l,s)),s},stop(){a?.stop();for(const _ of m.values())_.stop()}}}v(buildEdgeVerifierPool,"buildEdgeVerifierPool"),A(buildEdgeVerifierPool,"buildEdgeVerifierPool"),n(buildEdgeVerifierPool,"buildEdgeVerifierPool"),exports.BENIGN_SOCKET_ERRNOS=new Set(["ECONNRESET","EPIPE","ETIMEDOUT","ECONNABORTED","ECANCELED"]);function classifyClientError(r,t){return r&&exports.BENIGN_SOCKET_ERRNOS.has(r)?{status:null,report:!1,cause:"client-abort"}:r==="HPE_INVALID_EOF_STATE"?{status:null,report:!1,cause:"truncated-at-eof"}:r==="ERR_HTTP_REQUEST_TIMEOUT"?{status:408,report:!0,cause:"request-timeout"}:r==="HPE_HEADER_OVERFLOW"?{status:431,report:!0,cause:"header-overflow"}:r?.startsWith("HPE_")?{status:400,report:!0,cause:"parse-error"}:{status:400,report:!0,cause:r??t??"unknown"}}v(classifyClientError,"classifyClientError"),A(classifyClientError,"classifyClientError"),n(classifyClientError,"classifyClientError");const CLIENT_ERROR_REASON={400:"Bad Request",408:"Request Timeout",431:"Request Header Fields Too Large"};function createClientErrorLogGate(r=1e4){const t=new Map;return u=>{const m=Date.now(),a=t.get(u)??0;return m-a<r?!1:(t.set(u,m),!0)}}v(createClientErrorLogGate,"createClientErrorLogGate"),A(createClientErrorLogGate,"createClientErrorLogGate"),n(createClientErrorLogGate,"createClientErrorLogGate");function guardInboundSocket(r){r.on("error",t=>{exports.BENIGN_SOCKET_ERRNOS.has(t.code??"")||console.warn(`[gateway] inbound socket error (${t.code??t.message}) \u2014 dropping this connection only`),r.destroy()})}v(guardInboundSocket,"guardInboundSocket"),A(guardInboundSocket,"guardInboundSocket"),n(guardInboundSocket,"guardInboundSocket");function retirePreviousWorkspace(r,t,u){const m=r.get(t);if(!m)return!1;r.delete(t),u==="re-registered"&&console.log(`[gateway] workspace '${t}' re-registered \u2014 retiring the children of its previous registration first.`);try{m()}catch(a){console.warn(`[gateway] could not fully retire the previous registration of '${t}' (${u}): ${a.message}`)}return!0}v(retirePreviousWorkspace,"retirePreviousWorkspace"),A(retirePreviousWorkspace,"retirePreviousWorkspace"),n(retirePreviousWorkspace,"retirePreviousWorkspace"),exports.GATEWAY_MAX_CONNECTIONS_DEFAULT=512,exports.GATEWAY_MAX_H2_SESSIONS_DEFAULT=64,exports.GATEWAY_MAX_H2_STREAMS_DEFAULT=4096,exports.GATEWAY_H2_IDLE_SESSION_MS_DEFAULT=3e5;function parseBudget(r,t){if(r===void 0||r.trim()==="")return t;const u=Number(r);return!Number.isFinite(u)||u<0?t:Math.floor(u)}v(parseBudget,"parseBudget"),A(parseBudget,"parseBudget"),n(parseBudget,"parseBudget");function resolveMaxConnections(r){return parseBudget(r,exports.GATEWAY_MAX_CONNECTIONS_DEFAULT)}v(resolveMaxConnections,"resolveMaxConnections"),A(resolveMaxConnections,"resolveMaxConnections"),n(resolveMaxConnections,"resolveMaxConnections");function h2BudgetFromEnv(r=process.env){return{maxSessions:parseBudget(r.LENSMCP_MAX_H2_SESSIONS,exports.GATEWAY_MAX_H2_SESSIONS_DEFAULT),maxStreams:parseBudget(r.LENSMCP_MAX_H2_STREAMS,exports.GATEWAY_MAX_H2_STREAMS_DEFAULT),idleSessionMs:parseBudget(r.LENSMCP_H2_IDLE_MS,exports.GATEWAY_H2_IDLE_SESSION_MS_DEFAULT)}}v(h2BudgetFromEnv,"h2BudgetFromEnv"),A(h2BudgetFromEnv,"h2BudgetFromEnv"),n(h2BudgetFromEnv,"h2BudgetFromEnv");function createH2Governor(r,t){const{NGHTTP2_ENHANCE_YOUR_CALM:u,NGHTTP2_REFUSED_STREAM:m}=require("node:http2").constants,a=new Map;let w=0;const _=n(s=>{s.idle&&(clearTimeout(s.idle),s.idle=void 0)},"disarm"),g=n((s,d)=>{_(d),!(r.idleSessionMs<=0||d.open>0)&&(d.idle=setTimeout(()=>{s.destroyed||s.closed||(t("session-reclaimed",{idleMs:r.idleSessionMs,sessions:a.size}),a.delete(s),s.close())},r.idleSessionMs),d.idle.unref?.())},"arm"),l=n(()=>{for(const[s,d]of a)if(!(d.open>0||s.destroyed))return _(d),a.delete(s),t("session-reclaimed",{reason:"cap",sessions:a.size+1,maxSessions:r.maxSessions}),s.close(),!0;return!1},"reclaimOldestIdle");return{admitSession(s){if(r.maxSessions>0&&a.size>=r.maxSessions&&!l()){t("session-refused",{sessions:a.size,maxSessions:r.maxSessions,streams:w});try{s.goaway(u)}catch{}try{s.close()}catch{}return!1}const d={open:0};return a.set(s,d),g(s,d),s.once("close",()=>{_(d),a.delete(s)}),!0},admitStream(s,d){const S=a.get(s);if(!S)return!0;if(r.maxStreams>0&&w>=r.maxStreams){t("stream-refused",{streams:w,maxStreams:r.maxStreams,sessions:a.size});try{d.close(m)}catch{}return!1}return w+=1,S.open+=1,_(S),d.once("close",()=>{w=Math.max(0,w-1),S.open=Math.max(0,S.open-1),S.open===0&&a.has(s)&&g(s,S)}),!0},dispose(){for(const s of a.values())_(s);a.clear()}}}v(createH2Governor,"createH2Governor"),A(createH2Governor,"createH2Governor"),n(createH2Governor,"createH2Governor");async function startGateway(r,t){const u=r.https!==!1,m=r.ports?.length?r.ports:[443],a=r.scanTtlMs??1500,w=r.startupTimeoutMs??12e4,_=r.sweepMs??1e4,g=r.trafficFlushMs??5e3;let l=!1;const s=process.env.LENSMCP_EVENT_FILE??path.join(t.root,".lensmcp","events.jsonl"),d=(0,own_log_1.startOwnLogRotation)(t.root),S=(0,scope_1.readLensScope)(t.root),T=S.key,k=S.sockNs!==T?S.sockNs:void 0,V=t.projectsConfigurations?.projects??{},J=(0,discovery_1.projectSourceRoots)(t.root,V,t.projectDependencies),{routes:j,services:P,instance:z}=(0,discovery_1.discoverRoutes)(t.root,V,void 0,T,J,k,S.instance);if(j.length===0)throw new Error("[gateway] no project declares a `cluster` field \u2014 nothing to route.");const q=new route_registry_1.RouteRegistry;q.register({wsKey:T,...k?{sockNs:k}:{},root:t.root,routes:j,services:P,...z?{instance:z}:{}});const R=[];let Q=n(()=>{},"refreshCert");const Z=n(()=>{(0,route_registry_1.rebuildRoutesInPlace)(R,q),Q()},"rebuildRoutes");Z();const{serviceKeys:ie,keyToProject:ce,keyToWorkspace:le}=(0,service_keys_1.loadServiceKeys)(t.root,P,T),ue=(0,client_ip_1.createClientIpResolver)({...(0,client_ip_1.clientIpOptionsFromEnv)(),...r.trustProxyHops!==void 0?{trustProxyHops:r.trustProxyHops}:{},...r.clientIpHeader?{clientIpHeader:r.clientIpHeader}:{},...r.clientIpTrustedProxies?{clientIpTrustedProxies:r.clientIpTrustedProxies}:{}}),E={root:t.root,wsKey:T,...k?{sockNs:k}:{},eventFile:s,routes:R,registry:q,rebuildRoutes:Z,services:P,serviceKeys:ie,keyToProject:ce,keyToWorkspace:le,clientIp:ue,bodyStallMs:r.bodyStallMs??types_1.BODY_STALL_MS,scanTtlMs:a,startupTimeoutMs:w,sweepMs:_,trafficFlushMs:g,https:u,projectRoots:Object.fromEntries(Object.entries(t.projectsConfigurations?.projects??{}).map(([e,o])=>[e,path.resolve(t.root,o.root)])),projectSourceRoots:J,...t.projectGraphStore?{graphStores:(0,project_graph_store_1.createProjectGraphStores)(t.projectGraphStore)}:{},...r.sharedCompiler!==void 0?{sharedCompiler:r.sharedCompiler}:{},stopped:n(()=>l,"stopped")};(0,process_name_1.prelinkProcessNames)((0,process_names_1.gatewayProcessNames)(P,{runner:(0,serve_launch_1.serveRunnerEnabled)()&&!!t.projectGraphStore,sharedBuild:(0,protocol_1.sharedCompilerEnabled)(process.env,r.sharedCompiler),label:T||path.basename(t.root),lens:{key:T,dashboard:r.dashboard!==!1,mcp:r.mcp!==!1&&j.some(e=>!!e.lens)}}));const f=(0,observability_1.createObservability)(s,{trafficFlushMs:g}),de=createClientErrorLogGate(),b=h2BudgetFromEnv(),pe=createClientErrorLogGate(3e4),W=createH2Governor(b,(e,o)=>{pe(e)&&console.warn(`[gateway] h2 aggregate budget: ${e} (${JSON.stringify(o)}). These are the FRONT DOOR's ceilings, not an upstream's \u2014 raise/disable with LENSMCP_MAX_H2_SESSIONS / LENSMCP_MAX_H2_STREAMS / LENSMCP_H2_IDLE_MS / LENSMCP_MAX_CONNECTIONS (0 = unbounded).`),f.emit(e==="session-reclaimed"?"info":"warning",`h2 aggregate budget: ${e}`,`gateway-h2-budget:${e}`,{kind:"h2-aggregate-budget",event:e,project:"gateway",...o})}),M=(0,lifecycle_1.createServiceLayer)(E,f),L=(0,lens_children_1.createLensChildren)(E,f,r),F=new Map;let D;if(r.middleware){const e=require(path.resolve(t.root,r.middleware));D=e.default??e}const K=(0,workspace_middleware_1.createWorkspaceMiddleware)({ownerKey:T,...D?{owner:D}:{},policy:(0,workspace_middleware_1.guestMiddlewarePolicy)()}),O=process.env.LENSMCP_GW_ACT==="0"?void 0:(0,act_1.createActStore)({dir:path.join(path.dirname((0,control_1.controlSocketPath)()),"identities")});let I;try{I=(0,control_1.startControlServer)({rt:E,killService:n((e,o)=>M.killSpawned(e,o),"killService"),restartService:n((e,o)=>M.restartService(e,o),"restartService"),...O?{act:O}:{},onRegister:n(async e=>{retirePreviousWorkspace(F,e.wsKey,"re-registered"),K.set(e.wsKey,e.root,e.middleware);const o=await L.hostWorkspaceDashboard(e),h=await L.hostWorkspaceApps(e);F.set(e.wsKey,()=>{try{o?.()}finally{h()}})},"onRegister"),onUnregister:n(e=>{retirePreviousWorkspace(F,e.wsKey,"unregistered"),K.drop(e.wsKey),M.stopBuildHost(e.root)},"onUnregister")})}catch(e){console.warn("[gateway] control plane failed to start (multi-workspace register disabled):",e.message)}const H=(0,proxy_1.createProxy)(E,f,M),ee=buildEdgeVerifierPool(()=>E.routes),re=(0,auth_1.createEdgeAuth)(E,f,ee,O),_e=n(e=>{const o=e.route?.wsKey,h=K.for(o);if(h)try{const i=o?E.registry.get(o):void 0;h(e.req,{...o?{wsKey:o}:{},...i?{root:i.root}:{},env:i?.instance?.env??{}})}catch(i){f.traceStep(e.trace,"auth",{mode:"middleware",ok:!1,reason:i.message}),e.route&&f.finishTrace(e.trace,e.route.project,401),e.sendError(401,"unauthorized",`Gateway middleware rejected the request: ${i.message}`)}},"builtinMiddleware"),te=r.hooks??{},oe=(0,hooks_1.createHooks)({...te,afterAuth:[_e,...te.afterAuth??[]]}),se=(0,handler_1.createHandler)({rt:E,obs:f,auth:re,proxy:H,hooks:oe}),ne=(0,upgrade_1.createUpgrade)({rt:E,auth:re,proxy:H,hooks:oe,obs:f}),Se=f.startEdgeFlusher(),Ee=M.startSweeper(),ae=(0,source_poller_1.createSourcePoller)({services:n(()=>E.registry.allServices(),"services"),serviceKey:n(e=>E.serviceKeys[(0,service_keys_1.serviceKeyId)(e.wsKey,e.project)],"serviceKey"),emit:n((e,o,h,i,p)=>f.emit(o,h,i,{wsKey:e.wsKey,...p},void 0,e.wsKey===E.wsKey?void 0:path.join(e.root,".lensmcp","events.jsonl")),"emit"),scanTtlMs:a,stopped:n(()=>l,"stopped")});(0,source_poller_1.sourcesEnabled)()&&ae.start(),await L.bootSingletonsAndApps();for(const e of P)e.decl.eager&&M.ensureUp(e);let x,U,$;if(u){const e=require("../../../basic-ssl"),o=(0,service_keys_1.gatewayCacheDir)(t.root);$=n(()=>e.getCertificateSync(o,"gateway",E.routes.map(h=>h.host).filter(h=>!!h)),"mintCert"),x=$(),U=e.caCertPath()}const B=[],G=[],Y=r.maxConnections??resolveMaxConnections(process.env.LENSMCP_MAX_CONNECTIONS);for(const e of m){const o=x?require("node:http2").createSecureServer({key:x,cert:x,allowHTTP1:!0,maxSessionMemory:512,settings:{maxConcurrentStreams:512},peerMaxConcurrentStreams:512,streamResetBurst:r.h2ResetBurst??types_1.GATEWAY_H2_RESET_BURST,streamResetRate:r.h2ResetRate??types_1.GATEWAY_H2_RESET_RATE},(i,p)=>se(i,p)):http.createServer(se);o.on("upgrade",ne),o.on("error",i=>console.error(`[gateway] port ${e}: ${i.code}`)),o.on("connection",guardInboundSocket),o.on("secureConnection",guardInboundSocket),o.on("tlsClientError",(i,p)=>p.destroy()),o.on("clientError",(i,p)=>{const c=i,y=classifyClientError(c.code,c.message);if(y.report&&de(y.cause)){const N=p.remoteAddress??"unknown",C=y.status===null?"dropped":String(y.status);console.warn(`[gateway] inbound H1 clientError from ${N}: ${y.cause} (${c.code??c.message}${c.bytesParsed!==void 0?`, bytesParsed=${c.bytesParsed}`:""}) \u2192 ${C}. This status is the GATEWAY's, not the upstream service's.`),f.emit("warning",`inbound clientError: ${y.cause} \u2192 ${C}`,`gateway-client-error:${y.cause}`,{kind:"gateway-client-error",cause:y.cause,code:c.code??null,status:y.status,peer:N,bytesParsed:c.bytesParsed??null})}y.status!==null&&p.writable&&p.end(`HTTP/1.1 ${y.status} ${CLIENT_ERROR_REASON[y.status]}\r
|
|
2
2
|
\r
|
|
3
|
-
`),p.destroy()}),
|
|
3
|
+
`),p.destroy()}),o.keepAliveTimeout=types_1.GATEWAY_KEEPALIVE_TIMEOUT_MS,o.headersTimeout=r.headersTimeoutMs??types_1.GATEWAY_HEADERS_TIMEOUT_MS,Y>0&&(o.maxConnections=Y);const h=r.connectionsCheckingIntervalMs??types_1.GATEWAY_CONN_CHECK_MS;if(h>0&&(o.connectionsCheckingInterval=h),x!=null){const i=o,{NGHTTP2_CANCEL:p}=require("node:http2").constants;i.on("session",c=>{if(!W.admitSession(c)){c.on("error",()=>{});return}let y=0,N=0;c.on("stream",C=>{W.admitStream(c,C)&&C.once("close",()=>{c.destroyed?N+=1:C.rstCode===p&&(y+=1)})}),c.once("close",()=>{N!==0&&(console.warn(`[gateway] h2 session closed with ${N} stream(s) in flight after ${y} client reset(s) \u2014 every in-flight fetch on that connection failed at once (ERR_HTTP2_PROTOCOL_ERROR in the browser). Reset budget: LENSMCP_H2_RESET_BURST/LENSMCP_H2_RESET_RATE (issues/closed/foodguard-14).`),f.emit("warning",`h2 session lost with ${N} stream(s) in flight`,"gateway-h2-session-lost",{kind:"h2-session-lost",project:"gateway",inflight:N,clientResets:y}))}),c.on("error",C=>{const ye=C.code??C.message;console.warn(`[gateway] h2 session error (${ye}) \u2014 dropping this session only`),c.destroyed||c.destroy()})}),i.on("sessionError",c=>{console.warn(`[gateway] h2 sessionError: ${c.code??c.message}`)})}await new Promise(i=>{o.listen(e,()=>{const p=o.address()?.port??e;G.push(p),console.log(`[gateway] Listening on ${x?"https":"http"}://localhost:${p}`),i()})}),B.push(o)}$&&(Q=n(()=>{const e=$();for(const o of B)o.setSecureContext?.({key:e,cert:e})},"refreshCert")),console.log("[gateway] Routes:");for(const e of R){const o=e.pool?`pods@${e.pool.dir}`:e.target;console.log(`[gateway] ${e.host??"(default)"} \u2192 ${o}${e.prependPrefix?` (+${e.prependPrefix})`:""}${e.internal?" [internal: no middleware]":""} [${e.project}]`)}U&&console.log(`[gateway] CA: ${U} \u2014 one-time setup via the trust executor.`);const X=n(e=>e>0?String(e):"unbounded","unbounded");return console.log(`[gateway] front-door budget: \u2264${X(Y)} connections, \u2264${X(b.maxSessions)} h2 sessions (each \u2264512 MB session memory, \u2264512 streams), \u2264${X(b.maxStreams)} open streams in total, idle h2 session reclaimed after ${b.idleSessionMs>0?`${Math.round(b.idleSessionMs/1e3)}s`:"never"}. Override: LENSMCP_MAX_CONNECTIONS / LENSMCP_MAX_H2_SESSIONS / LENSMCP_MAX_H2_STREAMS / LENSMCP_H2_IDLE_MS (0 = unbounded).`),f.emit("info",`gateway up: ${R.length} routes on ${G.join("/")}`,"cluster-gateway",{kind:"gateway-up",project:"gateway",ports:G,routes:R.map(e=>({host:e.host??"(default)",project:e.project,mode:e.pool?"pods":"tcp",internal:!!e.internal,prependPrefix:e.prependPrefix}))}),I&&process.env.LENSMCP_GUEST_REPLAY!=="0"&&I.replay().catch(e=>console.warn("[gateway] guest replay failed:",e.message)),{ports:G,routes:R,services:P,stop:n(async()=>{if(!l){l=!0,clearInterval(Se),clearInterval(Ee),ae.stop(),f.emit("info","gateway down","cluster-gateway",{kind:"gateway-down",project:"gateway"}),ee.stop(),I?.close(),O?.flush(),(0,workspace_registry_1.unregisterWorkspace)(T);for(const e of P)M.killSpawned(e,"gateway shutdown");M.stopRetiringTrees(),await M.stopBuildHost(),await L.reapAll(),ne.closeTunnels(),await Promise.all(B.map(e=>new Promise(o=>{let h=!1;const i=n(()=>{h||(h=!0,o())},"done"),p=e;e.close(()=>i());try{p.closeIdleConnections?.()}catch{}setTimeout(()=>{try{p.closeAllConnections?.()}catch{}i()},types_1.GATEWAY_STOP_GRACE_MS).unref?.()}))),H.closeProxy(),H.destroyAgents(),W.dispose(),(0,workspace_log_1.closeWorkspaceLogs)(),d()}},"stop"),...E.lensSupervisor?{lensSupervisor:E.lensSupervisor}:{},...E.graphStores?{graphStores:E.graphStores}:{}}}v(startGateway,"startGateway"),A(startGateway,"startGateway"),n(startGateway,"startGateway");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var k=Object.defineProperty;var d=(e,r)=>k(e,"name",{value:r,configurable:!0});var l=Object.defineProperty,a=d((e,r)=>l(e,"name",{value:r,configurable:!0}),"a"),h=Object.defineProperty,y=a((e,r)=>h(e,"name",{value:r,configurable:!0}),"y");Object.defineProperty(exports,"__esModule",{value:!0}),exports.gatewayCacheDir=gatewayCacheDir,exports.serviceKeyId=serviceKeyId,exports.loadServiceKeys=loadServiceKeys,exports.adoptServiceKeys=adoptServiceKeys;const tslib_1=require("tslib"),node_crypto_1=require("node:crypto"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path")),checkout_cache_1=require("../../../checkout-cache");function gatewayCacheDir(e){return(0,checkout_cache_1.checkoutCacheDir)(e,"davnx-webpack")}d(gatewayCacheDir,"gatewayCacheDir"),a(gatewayCacheDir,"gatewayCacheDir"),y(gatewayCacheDir,"gatewayCacheDir");function serviceKeyId(e,r){return`${e??""} ${r}`}d(serviceKeyId,"serviceKeyId"),a(serviceKeyId,"serviceKeyId"),y(serviceKeyId,"serviceKeyId");function loadServiceKeys(e,r,p,S){const n=gatewayCacheDir(e),j=path.join(n,"service-keys.json");let t={};try{t=JSON.parse(fs.readFileSync(j,"utf8"))}catch{}let u=!1;const v=[];for(const[c,f]of Object.entries(t))S?.(f)&&(t[c]=(0,node_crypto_1.randomBytes)(16).toString("hex"),u=!0,v.push(c));for(const c of r)t[c.project]||(t[c.project]=(0,node_crypto_1.randomBytes)(16).toString("hex"),u=!0);if(u)try{fs.mkdirSync(n,{recursive:!0}),fs.writeFileSync(j,JSON.stringify(t,null,2))}catch{}const o=p??r[0]?.wsKey,s={};for(const[c,f]of Object.entries(t))s[serviceKeyId(o,c)]=f;const i=new Map(Object.entries(t).map(([c,f])=>[f,c])),K=new Map(o?Object.values(t).map(c=>[c,o]):[]);return{serviceKeys:s,keyToProject:i,keyToWorkspace:K,byProject:t,regenerated:v}}d(loadServiceKeys,"loadServiceKeys"),a(loadServiceKeys,"loadServiceKeys"),y(loadServiceKeys,"loadServiceKeys");function adoptServiceKeys(e,r,p,S){const n=S??p[0]?.wsKey,j=y(o=>{const s=e.keyToWorkspace?.get(o);return s!==void 0&&s!==n},"taken"),{byProject:t,regenerated:u}=loadServiceKeys(r,p,n,j),v=[];for(const o of p){const s=serviceKeyId(o.wsKey??n,o.project),i=t[o.project];if(!i||e.serviceKeys[s]===i)continue;e.serviceKeys[s]=i,e.keyToProject.set(i,o.project);const K=o.wsKey??n;K&&e.keyToWorkspace?.set(i,K),v.push(o.project)}return{added:v,regenerated:u}}d(adoptServiceKeys,"adoptServiceKeys"),a(adoptServiceKeys,"adoptServiceKeys"),y(adoptServiceKeys,"adoptServiceKeys");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)){const
|
|
3
|
-
`))
|
|
4
|
-
`)},"relayOut");return
|
|
1
|
+
"use strict";var L=Object.defineProperty;var v=(o,t)=>L(o,"name",{value:t,configurable:!0});var A=Object.defineProperty,y=v((o,t)=>A(o,"name",{value:t,configurable:!0}),"y"),j=Object.defineProperty,i=y((o,t)=>j(o,"name",{value:t,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.HOST_MAX_RESTARTS=void 0,exports.buildHostScript=buildHostScript,exports.workspaceBuildHostScript=workspaceBuildHostScript,exports.createSharedBuildRelay=createSharedBuildRelay;const tslib_1=require("tslib"),node_child_process_1=require("node:child_process"),fs=tslib_1.__importStar(require("node:fs")),node_module_1=require("node:module"),path=tslib_1.__importStar(require("node:path")),process_name_1=require("../../../process-name"),protocol_1=require("../../../shared-build/protocol"),pod_env_1=require("./pod-env"),registration_guards_1=require("./registration-guards");exports.HOST_MAX_RESTARTS=3;const CRASH_WINDOW_MS=6e4;function buildHostScript(o=path.join(__dirname,"../../..")){const t=path.join(o,"build-host.js");if(fs.existsSync(t))return{path:t,execArgv:[]};const u=path.join(o,"build-host.ts");if(fs.existsSync(u))try{return{path:u,execArgv:["--require",require.resolve("@swc-node/register")]}}catch{return}}v(buildHostScript,"buildHostScript"),y(buildHostScript,"buildHostScript"),i(buildHostScript,"buildHostScript");function workspaceBuildHostScript(o){try{return{path:(0,node_module_1.createRequire)(path.join(o,"package.json")).resolve("@lensmcp/cluster/build-host.js"),execArgv:[]}}catch{return}}v(workspaceBuildHostScript,"workspaceBuildHostScript"),y(workspaceBuildHostScript,"workspaceBuildHostScript"),i(workspaceBuildHostScript,"workspaceBuildHostScript");function createSharedBuildRelay(o,t={}){const u=t.script===void 0?buildHostScript():t.script??void 0,_=t.scriptFor??workspaceBuildHostScript,h=new Map,f=new WeakMap,d=(0,registration_guards_1.canonicalRoot)(o.root),g=i(e=>{const a=(0,registration_guards_1.canonicalRoot)(e.root);let c=h.get(a);return c||(c=a===d?createWorkspaceRelay(o,{root:o.root,...o.wsKey?{wsKey:o.wsKey}:{},...o.sockNs?{sockNs:o.sockNs}:{},eventFile:o.eventFile},u,t):createWorkspaceRelay(o,{root:e.root,...e.wsKey?{wsKey:e.wsKey}:{},...e.sockNs?{sockNs:e.sockNs}:{},eventFile:path.join(e.root,".lensmcp","events.jsonl")},_(e.root),t),h.set(a,c)),c},"relayFor");return{offeredTo:i(e=>(0,protocol_1.sharedCompilerEnabled)(t.gatewayEnv??process.env,o.sharedCompiler)&&g(e).offered(),"offeredTo"),attach(e,a,c){const m=g(e);f.set(c,m),m.attach(`${e.project}#g${a}`,c)},detach:i(e=>f.get(e)?.detach(e),"detach"),hostPid:i((e=o.root)=>h.get((0,registration_guards_1.canonicalRoot)(e))?.hostPid(),"hostPid"),release(e){const a=(0,registration_guards_1.canonicalRoot)(e),c=h.get(a);return h.delete(a),c?.stop()??Promise.resolve()},async stop(){const e=[...h.values()];h.clear(),await Promise.all(e.map(a=>a.stop()))}}}v(createSharedBuildRelay,"createSharedBuildRelay"),y(createSharedBuildRelay,"createSharedBuildRelay"),i(createSharedBuildRelay,"createSharedBuildRelay");function createWorkspaceRelay(o,t,u,_){const h=_.spawnProcess??node_child_process_1.spawn,f=_.log??(r=>console.log(r)),d=new Map,g=new WeakMap;let e,a=[],c,m=!1;const N=(0,registration_guards_1.canonicalRoot)(t.root)===(0,registration_guards_1.canonicalRoot)(o.root)?"this workspace":`'${t.wsKey??path.basename(t.root)}'`,R=i((r,s)=>{if(!r.connected)return;const n={channel:protocol_1.SHARED_BUILD_CHANNEL,event:s};try{r.send(n,void 0,void 0,()=>{})}catch{}},"toRunner"),E=i(r=>{if(e?.connected)try{e.send(r,void 0,void 0,()=>{})}catch{}},"toHost"),P=i(()=>{if(_.reapStale===!1)return;let r;try{r=(0,node_child_process_1.execFileSync)("ps",["ax","-ww","-o","pid=,pgid=,command="],{encoding:"utf8",timeout:5e3})}catch{return}for(const s of r.split(`
|
|
2
|
+
`)){const n=s.match(/^\s*(\d+)\s+(\d+)\s+(.*)$/);if(!n||!(0,protocol_1.isBuildHostCommandOf)(n[3],t.root))continue;const l=Number(n[1]),p=Number(n[2]);if(!(l===e?.pid||l===process.pid)){try{process.kill(-p,"SIGKILL")}catch{try{process.kill(l,"SIGKILL")}catch{}}f(`[gateway] reaped a stale build host (pid ${l}) of ${N}`)}}},"reapStaleHosts"),k=i(()=>{if(e||m||c||!u)return e;P();const r=t.wsKey||path.basename(t.root),s={...(0,pod_env_1.podBaseEnv)(process.env,o.root,t.root),NX_DAEMON:"false",NODE_ENV:"development",NX_WORKSPACE_ROOT:t.root,...t.wsKey?{LENSMCP_WS_KEY:t.wsKey}:{},...t.sockNs?{LENSMCP_SOCK_NS:t.sockNs}:{},LENSMCP_EVENT_FILE:t.eventFile,LENSMCP_GATEWAY_PID:String(process.pid)},n=h((0,process_name_1.namedExecPath)((0,process_name_1.processName)(r,protocol_1.BUILD_HOST_ROLE)),[...u.execArgv,u.path,...(0,protocol_1.buildHostArgs)(t.root)],{cwd:t.root,detached:!0,env:s,stdio:["ignore","pipe","pipe","ipc"]});e=n,f(`[gateway] build host starting (one compilation for the services of ${N} \u2014 LENSMCP_SHARED_COMPILER)`);const l=i(p=>S=>{if(!o.stopped())for(const w of S.toString().split(`
|
|
3
|
+
`))w.trim()&&p.write(`[build] ${w}
|
|
4
|
+
`)},"relayOut");return n.stdout?.on("data",l(process.stdout)),n.stderr?.on("data",l(process.stderr)),n.on("message",p=>{if(p?.type==="member"){const S=d.get(p.member);S&&R(S.proc,p.event)}}),n.on("exit",(p,S)=>{if(e===n&&(e=void 0),m||o.stopped())return;const w=Date.now();if(a=[...a.filter(b=>w-b<CRASH_WINDOW_MS),w],a.length>=exports.HOST_MAX_RESTARTS){c=`the build host exited ${a.length} times in a minute (last: ${p??S})`,f(`[gateway] ${c} \u2014 every service compiles on its own from now on`);for(const b of d.values())R(b.proc,{type:"refused",reason:c});d.clear();return}if(d.size!==0&&(f(`[gateway] build host exited (${p??S}) \u2014 restarting it for ${d.size} service tree(s)`),k()))for(const[b,{join:H}]of d)E({type:"join",member:b,join:H})}),n},"start"),x=i(r=>{const s=g.get(r);!s||d.get(s)?.proc!==r||(d.delete(s),E({type:"leave",member:s}))},"detach");return{offered:i(()=>!!u&&!c,"offered"),attach:i((r,s)=>{g.set(s,r),s.on("message",n=>{if((0,protocol_1.isRunnerJoinMessage)(n)){if(c||!k()){R(s,{type:"refused",reason:c??"the build host could not be started"});return}d.set(r,{proc:s,join:n.join}),E({type:"join",member:r,join:n.join})}}),s.once("exit",()=>x(s))},"attach"),detach:x,hostPid:i(()=>e?.pid,"hostPid"),stop(){m=!0,d.clear();const r=e;return e=void 0,!r||r.exitCode!==null||r.signalCode!==null?Promise.resolve():new Promise(s=>{const n=i(()=>{clearTimeout(l),s()},"done");r.once("exit",n);try{process.kill(-r.pid,"SIGTERM")}catch{try{r.kill("SIGTERM")}catch{}}const l=setTimeout(()=>{try{process.kill(-r.pid,"SIGKILL")}catch{try{r.kill("SIGKILL")}catch{}}s()},6e3);l.unref?.()})}}}v(createWorkspaceRelay,"createWorkspaceRelay"),y(createWorkspaceRelay,"createWorkspaceRelay"),i(createWorkspaceRelay,"createWorkspaceRelay");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var U=Object.defineProperty;var v=(e,o)=>U(e,"name",{value:o,configurable:!0});var b=Object.defineProperty,l=v((e,o)=>b(e,"name",{value:o,configurable:!0}),"l");Object.defineProperty(exports,"__esModule",{value:!0}),exports.sourceStaleAfterMs=exports.SOURCE_BACKOFF_MAX_MS=exports.SOURCE_DECLARATION_REPORT_MS=exports.SOURCE_NOT_RUNNING_REPORT_MS=exports.SOURCE_MAX_PER_SERVICE=exports.SOURCE_MAX_GROUPS=exports.SOURCE_MAX_BYTES=exports.QUEUE_DEFAULT_OLDEST_WAIT_MIN=exports.SOURCE_MIN_INTERVAL_SEC=exports.SOURCE_DEFAULT_INTERVAL_SEC=exports.QUEUE_WIRE_SCHEMA=exports.SOURCE_KINDS_READ=exports.SOURCE_KINDS=exports.sourcesConcurrency=exports.sourcesTimeoutMs=exports.sourcesEnabled=void 0,exports.sourceBackoffMs=sourceBackoffMs,exports.parseSourceDecls=parseSourceDecls,exports.parseQueueSnapshot=parseQueueSnapshot,exports.keepQueueSnapshot=keepQueueSnapshot,exports.buildSourcePollRaw=buildSourcePollRaw,exports.buildSourceDeclarationRaw=buildSourceDeclarationRaw,exports.sourcePollTitle=sourcePollTitle,exports.requestOverSocket=requestOverSocket,exports.createSourcePoller=createSourcePoller;const tslib_1=require("tslib"),http=tslib_1.__importStar(require("node:http")),discovery_1=require("./discovery"),readEnv=l(e=>process.env[e],"readEnv"),envInt=l((e,o,n)=>{const u=Number(readEnv(e));return Number.isInteger(u)&&u>=n?u:o},"envInt"),sourcesEnabled=l(()=>readEnv("LENSMCP_SOURCES")!=="0","sourcesEnabled");exports.sourcesEnabled=sourcesEnabled;const sourcesTimeoutMs=l(()=>envInt("LENSMCP_SOURCES_TIMEOUT_MS",3e3,100),"sourcesTimeoutMs");exports.sourcesTimeoutMs=sourcesTimeoutMs;const sourcesConcurrency=l(()=>envInt("LENSMCP_SOURCES_CONCURRENCY",4,1),"sourcesConcurrency");exports.sourcesConcurrency=sourcesConcurrency,exports.SOURCE_KINDS=["queue","loop","store","traffic"],exports.SOURCE_KINDS_READ=["queue"],exports.QUEUE_WIRE_SCHEMA="lensmcp.queue/v1",exports.SOURCE_DEFAULT_INTERVAL_SEC=10,exports.SOURCE_MIN_INTERVAL_SEC=2,exports.QUEUE_DEFAULT_OLDEST_WAIT_MIN=10,exports.SOURCE_MAX_BYTES=256*1024,exports.SOURCE_MAX_GROUPS=500,exports.SOURCE_MAX_PER_SERVICE=16,exports.SOURCE_NOT_RUNNING_REPORT_MS=6e4,exports.SOURCE_DECLARATION_REPORT_MS=5*6e4,exports.SOURCE_BACKOFF_MAX_MS=6e4;const sourceStaleAfterMs=l(e=>Math.max(3e4,3*Math.max(0,e)),"sourceStaleAfterMs");exports.sourceStaleAfterMs=sourceStaleAfterMs;function sourceBackoffMs(e,o){return o<=1?e:Math.min(e*2**Math.min(o-1,10),Math.max(e,exports.SOURCE_BACKOFF_MAX_MS))}v(sourceBackoffMs,"sourceBackoffMs"),l(sourceBackoffMs,"sourceBackoffMs");const ENTRY_KEYS=["kind","name","path","intervalSec","thresholds"],THRESHOLD_KEYS={queue:["oldestWaitMin","stalledMin"]},PATH_RE=/^\/(?!\/)[^\s#\u0000-\u001f\u007f]{0,511}$/,NAME_RE=/^[^\u0000-\u001f\u007f]{1,100}$/,isObj=l(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),minutes=l(e=>typeof e=="number"&&Number.isFinite(e)&&e>0&&e<=10080,"minutes");function parseSourceDecls(e){const o=[],n=[];return e===void 0?{sources:o,problems:n}:Array.isArray(e)?(e.forEach((u,p)=>{const E=`sources[${p}]`;if(!isObj(u)){n.push(`${E} is not an object \u2014 not read`);return}const f=typeof u.name=="string"&&u.name.trim()?`${E} "${u.name}"`:E,i=u.kind;if(typeof i!="string"||!exports.SOURCE_KINDS.includes(i)){n.push(`${f}: kind ${JSON.stringify(i??null)} is not a source kind (${exports.SOURCE_KINDS.join(", ")}) \u2014 not read`);return}if(!exports.SOURCE_KINDS_READ.includes(i)){n.push(`${f}: kind "${i}" is not read by this release (it reads ${exports.SOURCE_KINDS_READ.join(", ")}) \u2014 not read`);return}const r=i,h=Object.keys(u).filter(s=>!ENTRY_KEYS.includes(s));if(h.length){n.push(`${f}: unknown key${h.length===1?"":"s"} ${h.map(s=>JSON.stringify(s)).join(", ")} for a ${r} source (known: ${ENTRY_KEYS.join(", ")}) \u2014 not read`);return}const a=u.name;if(typeof a!="string"||!a.trim()||!NAME_RE.test(a)){n.push(`${E}: name ${JSON.stringify(a??null)} must be 1\u2013100 characters, not blank \u2014 not read`);return}if(o.some(s=>s.name===a)){n.push(`${f}: the name is declared twice on this service \u2014 read once`);return}const _=u.path;if(typeof _!="string"||!PATH_RE.test(_)||_.split("?")[0].split("/").includes("..")){n.push(`${f}: path ${JSON.stringify(_??null)} must be a route on the service, starting with "/" (e.g. "/api/dev/lens/backlog") \u2014 not read`);return}const m=u.intervalSec;if(m!==void 0&&!(typeof m=="number"&&Number.isInteger(m)&&m>=exports.SOURCE_MIN_INTERVAL_SEC&&m<=3600)){n.push(`${f}: intervalSec ${JSON.stringify(m)} must be a whole number of seconds from ${exports.SOURCE_MIN_INTERVAL_SEC} to 3600 \u2014 not read`);return}const S=u.thresholds;if(S!==void 0&&!isObj(S)){n.push(`${f}: thresholds must be an object \u2014 not read`);return}const O=isObj(S)?S:{},x=Object.keys(O).filter(s=>!THRESHOLD_KEYS[r].includes(s));if(x.length){n.push(`${f}: unknown threshold${x.length===1?"":"s"} ${x.map(s=>JSON.stringify(s)).join(", ")} for a ${r} source (known: ${THRESHOLD_KEYS[r].join(", ")}) \u2014 not read`);return}const t=THRESHOLD_KEYS[r].find(s=>O[s]!==void 0&&!minutes(O[s]));if(t){n.push(`${f}: thresholds.${t} ${JSON.stringify(O[t])} must be minutes, more than 0 and at most 10080 \u2014 not read`);return}if(o.length>=exports.SOURCE_MAX_PER_SERVICE){n.push(`${f}: more than ${exports.SOURCE_MAX_PER_SERVICE} sources on one service \u2014 not read`);return}o.push({kind:r,name:a,path:_,intervalSec:m??exports.SOURCE_DEFAULT_INTERVAL_SEC,thresholds:{oldestWaitMin:O.oldestWaitMin??exports.QUEUE_DEFAULT_OLDEST_WAIT_MIN,...O.stalledMin!==void 0?{stalledMin:O.stalledMin}:{}}})}),{sources:o,problems:n}):{sources:o,problems:["`sources` is not a list of { kind, name, path } entries \u2014 no source is read"]}}v(parseSourceDecls,"parseSourceDecls"),l(parseSourceDecls,"parseSourceDecls");const ISO_RE=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$/,isIso=l(e=>typeof e=="string"&&ISO_RE.test(e)&&!Number.isNaN(Date.parse(e)),"isIso"),isCount=l(e=>typeof e=="number"&&Number.isSafeInteger(e)&&e>=0,"isCount");function parseQueueSnapshot(e){const o=l(i=>({ok:!1,reason:i}),"fail");if(!isObj(e))return o("the snapshot is not a JSON object");if(e.schema!==exports.QUEUE_WIRE_SCHEMA)return o(`schema is ${e.schema===void 0?"absent":JSON.stringify(e.schema).slice(0,60)}, not "${exports.QUEUE_WIRE_SCHEMA}"`);const n=e.at;if(!isIso(n))return o("`at` is not an ISO time");const u=e.truncated;if(u!==void 0&&!(isObj(u)&&isCount(u.groups)))return o("`truncated` must be { groups: <how many were dropped> }, or absent");const p=e.groups;if(!Array.isArray(p))return o("`groups` is not a list");if(p.length>exports.SOURCE_MAX_GROUPS)return o(`${p.length} groups \u2014 at most ${exports.SOURCE_MAX_GROUPS}; cap them and say \`truncated: { groups: <dropped> }\``);const E=new Set,f=[];for(let i=0;i<p.length;i++){const r=p[i],h=`groups[${i}]`;if(!isObj(r))return o(`${h} is not an object`);const a=r.key;if(typeof a!="string"||a.length===0||a.length>200)return o(`${h}.key must be a string of 1\u2013200 characters`);if(E.has(a))return o(`${h}.key ${JSON.stringify(a)} appears twice`);if(E.add(a),!isCount(r.pending))return o(`${h}.pending must be a whole number \u2265 0`);for(const S of["inFlight","failed","completedInWindow"])if(r[S]!==void 0&&!isCount(r[S]))return o(`${h}.${S} must be a whole number \u2265 0, or absent`);const _=r.oldestPendingAt;if(_!=null&&!isIso(_))return o(`${h}.oldestPendingAt must be an ISO time, null, or absent`);const m=r.labels;if(m!==void 0){if(!isObj(m))return o(`${h}.labels must be an object of strings`);const S=Object.entries(m);if(S.length>16)return o(`${h}.labels has more than 16 entries`);for(const[O,x]of S)if(O.length===0||O.length>64||typeof x!="string"||x.length>200)return o(`${h}.labels.${O.slice(0,64)} must be a string of at most 200 characters`)}f.push({key:a,...m!==void 0?{labels:m}:{},pending:r.pending,...r.inFlight!==void 0?{inFlight:r.inFlight}:{},...r.failed!==void 0?{failed:r.failed}:{},..._!==void 0?{oldestPendingAt:_}:{},...r.completedInWindow!==void 0?{completedInWindow:r.completedInWindow}:{}})}return{ok:!0,at:n,groups:f,...u!==void 0?{truncated:{groups:u.groups}}:{}}}v(parseQueueSnapshot,"parseQueueSnapshot"),l(parseQueueSnapshot,"parseQueueSnapshot");const declRaw=l(e=>({sourceKind:e.kind,name:e.name,path:e.path,intervalSec:e.intervalSec,thresholds:{...e.thresholds}}),"declRaw"),oldestOf=l(e=>e.pending>0&&e.oldestPendingAt?Date.parse(e.oldestPendingAt):Number.POSITIVE_INFINITY,"oldestOf");function keepQueueSnapshot(e,o,n,u){const p={groups:o.length,pending:0,inFlight:0,failed:0};let E;for(const i of o)p.pending+=i.pending,p.inFlight+=i.inFlight??0,p.failed+=i.failed??0,i.completedInWindow!==void 0&&(E=(E??0)+i.completedInWindow);E!==void 0&&(p.completedInWindow=E);const f=[...o].sort((i,r)=>oldestOf(i)-oldestOf(r)||r.pending-i.pending||(i.key<r.key?-1:i.key>r.key?1:0));return{at:e,receivedAt:n,totals:p,groups:f.map(({key:i,...r})=>({group:i,...r})),...u?{truncated:{groups:u.groups}}:{}}}v(keepQueueSnapshot,"keepQueueSnapshot"),l(keepQueueSnapshot,"keepQueueSnapshot");function buildSourcePollRaw(e,o,n,u,p,E){return{kind:"source-poll",provenance:"reported",project:e,...declRaw(o),state:n.state,...n.detail!==void 0?{detail:n.detail}:{},...n.status!==void 0?{status:n.status}:{},polledAt:n.polledAt,...n.durationMs!==void 0?{durationMs:n.durationMs}:{},reportEveryMs:u,...p>0?{failures:p}:{},...E?{snapshot:E}:{}}}v(buildSourcePollRaw,"buildSourcePollRaw"),l(buildSourcePollRaw,"buildSourcePollRaw");function buildSourceDeclarationRaw(e,o){return{kind:"source-declaration",project:e,sources:o.sources.map(declRaw),problems:[...o.problems]}}v(buildSourceDeclarationRaw,"buildSourceDeclarationRaw"),l(buildSourceDeclarationRaw,"buildSourceDeclarationRaw");const span=l(e=>{const o=Math.round(e/6e4);return e<6e4?`${Math.max(0,Math.round(e/1e3))}s`:o<120?`${o}m`:`${Math.floor(o/60)}h${o%60?` ${o%60}m`:""}`},"span");function sourcePollTitle(e){const o=`${e.sourceKind} ${e.project}/${e.name} (reported)`;if(e.state!=="current"||!e.snapshot)return`${o}: ${e.state}${e.detail?` \u2014 ${e.detail}`:""}`;const n=e.snapshot,u=n.groups.find(E=>E.pending>0&&E.oldestPendingAt),p=u?.oldestPendingAt?Date.parse(n.at)-Date.parse(u.oldestPendingAt):void 0;return`${o}: ${n.totals.pending} pending in ${n.totals.groups} group${n.totals.groups===1?"":"s"}${p!==void 0?`, oldest waiting ${span(Math.max(0,p))}`:""}`}v(sourcePollTitle,"sourcePollTitle"),l(sourcePollTitle,"sourcePollTitle");function requestOverSocket(e,o,n,u,p=exports.SOURCE_MAX_BYTES){return new Promise(E=>{let f=!1,i;const r=l(a=>{f||(f=!0,clearTimeout(h),E(a))},"finish"),h=setTimeout(()=>{r({ok:!1,code:"ETIMEDOUT",message:`no answer within ${u} ms`}),i?.destroy()},u);h.unref?.();try{i=http.request({socketPath:e,path:o,method:"GET",agent:!1,headers:n},a=>{const _=[];let m=0;a.on("data",S=>{if(!f){if(m+=S.length,m>p){r({ok:!0,status:a.statusCode??0,body:"",truncated:!0}),a.destroy();return}_.push(S)}}),a.on("end",()=>r({ok:!0,status:a.statusCode??0,body:Buffer.concat(_).toString("utf8"),truncated:!1})),a.on("error",S=>r({ok:!1,code:S.code??"ERESPONSE",message:S.message}))}),i.on("error",a=>r({ok:!1,code:a.code??"EREQUEST",message:a.message})),i.end()}catch(a){r({ok:!1,code:a.code??"EREQUEST",message:a.message})}})}v(requestOverSocket,"requestOverSocket"),l(requestOverSocket,"requestOverSocket");const snippet=l(e=>e.replace(/\s+/g," ").trim().slice(0,160),"snippet");function createSourcePoller(e){const o=e.now??Date.now,n=e.timeoutMs??(0,exports.sourcesTimeoutMs)(),u=Math.max(1,e.maxConcurrent??(0,exports.sourcesConcurrency)()),p=e.socketOf??(t=>(0,discovery_1.pickSock)(t.pool,e.scanTtlMs??1500)),E=e.request??requestOverSocket,f=e.log??(t=>console.warn(t)),i=new WeakMap,r=new Map;let h=0,a;const _=l(t=>{const s=t.decl;let d=i.get(s);if(!d){d=parseSourceDecls(t.decl.sources),i.set(s,d);for(const c of d.problems)f(`[gateway] ${t.project}: cluster.sources \u2014 ${c}`)}const $=o();return(d.reportedAt===void 0||$-d.reportedAt>=exports.SOURCE_DECLARATION_REPORT_MS)&&(d.reportedAt=$,e.emit(t,d.problems.length?"warning":"info",d.problems.length?`sources ${t.project}: ${d.problems.length} cluster.sources entr${d.problems.length===1?"y":"ies"} not read \u2014 ${d.problems[0]}`:`sources ${t.project}: reads ${d.sources.map(c=>`${c.kind} "${c.name}"`).join(", ")}`,`source-declaration:${t.wsKey}:${t.project}`,buildSourceDeclarationRaw(t.project,d))),d},"declarationOf"),m=l(t=>{if(t.state==="starting")return{notRunning:"it is starting \u2014 read once it is up"};const s=p(t);return s?{socket:s}:{notRunning:t.state==="up"?"it has no live pod socket \u2014 no pod runs it now":"it is scaled to zero \u2014 the lens does not start a service to read a source"}},"reach"),S=l((t,s)=>{const d=t.last;if(!d)return;const $=o();if(!s&&t.reportedAt!==void 0&&$-t.reportedAt<t.reportEveryMs)return;t.reportedAt=$;const c=buildSourcePollRaw(t.svc.project,t.decl,d,t.reportEveryMs,t.failures,t.good),R=d.state==="unreachable"||d.state==="refused"||d.state==="malformed";e.emit(t.svc,R?"warning":"info",sourcePollTitle(c),`source:${t.svc.wsKey}:${t.svc.project}:${t.decl.name}`,c)},"report"),O=l(async t=>{const s=o(),d=t.decl.intervalSec*1e3;t.inFlight=!0,h+=1;const $=t.last?.state;try{const c=m(t.svc);if("notRunning"in c){t.last={state:"not-running",detail:c.notRunning,polledAt:s},t.failures=0,t.nextAt=s+d,t.reportEveryMs=exports.SOURCE_NOT_RUNNING_REPORT_MS,S(t,$!=="not-running");return}const R=e.serviceKey(t.svc),g=await E(c.socket,t.decl.path,{accept:"application/json","x-lensmcp-probe":`source:${t.decl.kind}`,...R?{"x-internal-token":R}:{}},n,exports.SOURCE_MAX_BYTES),M=Math.max(0,o()-s);if(g.ok===!1){const A=g.code==="ECONNREFUSED"||g.code==="ENOENT";t.last=A&&t.svc.state!=="up"?{state:"not-running",detail:`nothing listens on its pod socket \u2014 the service is ${t.svc.state}`,polledAt:s,durationMs:M}:{state:"unreachable",detail:g.code==="ETIMEDOUT"?g.message:`${g.code}: ${snippet(g.message)}`,polledAt:s,durationMs:M}}else if(g.status<200||g.status>299){const A=snippet(g.body);t.last={state:"refused",status:g.status,detail:`HTTP ${g.status}${A?`: ${A}`:""}`,polledAt:s,durationMs:M}}else if(g.truncated)t.last={state:"malformed",detail:`the snapshot is larger than ${exports.SOURCE_MAX_BYTES/1024} KiB`,polledAt:s,durationMs:M};else{let A;try{A=parseQueueSnapshot(JSON.parse(g.body))}catch{A={ok:!1,reason:`not JSON: ${snippet(g.body)||"(an empty body)"}`}}A.ok===!0?(t.good=keepQueueSnapshot(A.at,A.groups,o(),A.truncated),t.last={state:"current",polledAt:s,durationMs:M}):t.last={state:"malformed",detail:A.reason,polledAt:s,durationMs:M}}const y=t.last.state==="unreachable"||t.last.state==="refused"||t.last.state==="malformed";t.failures=y?t.failures+1:0;const C=y?sourceBackoffMs(d,t.failures):d;t.nextAt=s+C,t.reportEveryMs=t.last.state==="not-running"?exports.SOURCE_NOT_RUNNING_REPORT_MS:C,S(t,t.last.state!=="not-running"||$!=="not-running")}catch(c){t.last={state:"unreachable",detail:`the poll failed: ${snippet(c?.message??String(c))}`,polledAt:s},t.failures+=1,t.nextAt=s+sourceBackoffMs(d,t.failures),t.reportEveryMs=t.nextAt-s,S(t,!0)}finally{t.inFlight=!1,h-=1}},"pollOne"),x=l(async()=>{if(e.stopped?.())return;const t=new Set;for(const c of e.services())if(c.decl.sources!==void 0)for(const R of _(c).sources){const g=`${c.wsKey} ${c.project} ${R.name}`;t.add(g);const M=r.get(g);M?(M.svc!==c||M.decl!==R)&&(M.svc=c,M.decl=R):r.set(g,{svc:c,decl:R,nextAt:0,inFlight:!1,failures:0,reportEveryMs:R.intervalSec*1e3})}for(const[c,R]of[...r.entries()])!t.has(c)&&!R.inFlight&&r.delete(c);const s=o(),d=[...r.values()].filter(c=>!c.inFlight&&s>=c.nextAt).sort((c,R)=>c.nextAt-R.nextAt),$=[];for(const c of d){if(h>=u)break;$.push(O(c))}await Promise.all($)},"tick");return{tick:x,start(t=1e3){return a&&clearInterval(a),a=setInterval(()=>{x().catch(s=>console.error("[gateway] source poll error:",s))},t),a.unref(),a},stop(){a&&clearInterval(a),a=void 0},snapshot(){const t=o();return[...r.values()].map(s=>{const d=s.last!==void 0&&t-s.last.polledAt>(0,exports.sourceStaleAfterMs)(s.reportEveryMs);return{wsKey:s.svc.wsKey,project:s.svc.project,name:s.decl.name,kind:s.decl.kind,path:s.decl.path,state:s.last?d?"stale":s.last.state:"never-polled",...s.last?.detail!==void 0?{detail:s.last.detail}:{},...s.last?.status!==void 0?{status:s.last.status}:{},...s.last?{polledAt:s.last.polledAt}:{},failures:s.failures,nextAt:s.nextAt,...s.good?{snapshot:s.good,ageMs:Math.max(0,t-s.good.receivedAt)}:{}}})}}}v(createSourcePoller,"createSourcePoller"),l(createSourcePoller,"createSourcePoller");
|
|
1
|
+
"use strict";var k=Object.defineProperty;var x=(e,s)=>k(e,"name",{value:s,configurable:!0});var U=Object.defineProperty,v=x((e,s)=>U(e,"name",{value:s,configurable:!0}),"v"),b=Object.defineProperty,l=v((e,s)=>b(e,"name",{value:s,configurable:!0}),"l");Object.defineProperty(exports,"__esModule",{value:!0}),exports.sourceStaleAfterMs=exports.SOURCE_BACKOFF_MAX_MS=exports.SOURCE_DECLARATION_REPORT_MS=exports.SOURCE_NOT_RUNNING_REPORT_MS=exports.SOURCE_MAX_PER_SERVICE=exports.SOURCE_MAX_GROUPS=exports.SOURCE_MAX_BYTES=exports.QUEUE_DEFAULT_OLDEST_WAIT_MIN=exports.SOURCE_MIN_INTERVAL_SEC=exports.SOURCE_DEFAULT_INTERVAL_SEC=exports.QUEUE_WIRE_SCHEMA=exports.SOURCE_KINDS_READ=exports.SOURCE_KINDS=exports.sourcesConcurrency=exports.sourcesTimeoutMs=exports.sourcesEnabled=void 0,exports.sourceBackoffMs=sourceBackoffMs,exports.parseSourceDecls=parseSourceDecls,exports.parseQueueSnapshot=parseQueueSnapshot,exports.keepQueueSnapshot=keepQueueSnapshot,exports.buildSourcePollRaw=buildSourcePollRaw,exports.buildSourceDeclarationRaw=buildSourceDeclarationRaw,exports.sourcePollTitle=sourcePollTitle,exports.requestOverSocket=requestOverSocket,exports.createSourcePoller=createSourcePoller;const tslib_1=require("tslib"),http=tslib_1.__importStar(require("node:http")),discovery_1=require("./discovery"),readEnv=l(e=>process.env[e],"readEnv"),envInt=l((e,s,n)=>{const u=Number(readEnv(e));return Number.isInteger(u)&&u>=n?u:s},"envInt"),sourcesEnabled=l(()=>readEnv("LENSMCP_SOURCES")!=="0","sourcesEnabled");exports.sourcesEnabled=sourcesEnabled;const sourcesTimeoutMs=l(()=>envInt("LENSMCP_SOURCES_TIMEOUT_MS",3e3,100),"sourcesTimeoutMs");exports.sourcesTimeoutMs=sourcesTimeoutMs;const sourcesConcurrency=l(()=>envInt("LENSMCP_SOURCES_CONCURRENCY",4,1),"sourcesConcurrency");exports.sourcesConcurrency=sourcesConcurrency,exports.SOURCE_KINDS=["queue","loop","store","traffic"],exports.SOURCE_KINDS_READ=["queue"],exports.QUEUE_WIRE_SCHEMA="lensmcp.queue/v1",exports.SOURCE_DEFAULT_INTERVAL_SEC=10,exports.SOURCE_MIN_INTERVAL_SEC=2,exports.QUEUE_DEFAULT_OLDEST_WAIT_MIN=10,exports.SOURCE_MAX_BYTES=256*1024,exports.SOURCE_MAX_GROUPS=500,exports.SOURCE_MAX_PER_SERVICE=16,exports.SOURCE_NOT_RUNNING_REPORT_MS=6e4,exports.SOURCE_DECLARATION_REPORT_MS=5*6e4,exports.SOURCE_BACKOFF_MAX_MS=6e4;const sourceStaleAfterMs=l(e=>Math.max(3e4,3*Math.max(0,e)),"sourceStaleAfterMs");exports.sourceStaleAfterMs=sourceStaleAfterMs;function sourceBackoffMs(e,s){return s<=1?e:Math.min(e*2**Math.min(s-1,10),Math.max(e,exports.SOURCE_BACKOFF_MAX_MS))}x(sourceBackoffMs,"sourceBackoffMs"),v(sourceBackoffMs,"sourceBackoffMs"),l(sourceBackoffMs,"sourceBackoffMs");const ENTRY_KEYS=["kind","name","path","intervalSec","thresholds"],THRESHOLD_KEYS={queue:["oldestWaitMin","stalledMin"]},PATH_RE=/^\/(?!\/)[^\s#\u0000-\u001f\u007f]{0,511}$/,NAME_RE=/^[^\u0000-\u001f\u007f]{1,100}$/,isObj=l(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),minutes=l(e=>typeof e=="number"&&Number.isFinite(e)&&e>0&&e<=10080,"minutes");function parseSourceDecls(e){const s=[],n=[];return e===void 0?{sources:s,problems:n}:Array.isArray(e)?(e.forEach((u,p)=>{const f=`sources[${p}]`;if(!isObj(u)){n.push(`${f} is not an object \u2014 not read`);return}const E=typeof u.name=="string"&&u.name.trim()?`${f} "${u.name}"`:f,i=u.kind;if(typeof i!="string"||!exports.SOURCE_KINDS.includes(i)){n.push(`${E}: kind ${JSON.stringify(i??null)} is not a source kind (${exports.SOURCE_KINDS.join(", ")}) \u2014 not read`);return}if(!exports.SOURCE_KINDS_READ.includes(i)){n.push(`${E}: kind "${i}" is not read by this release (it reads ${exports.SOURCE_KINDS_READ.join(", ")}) \u2014 not read`);return}const r=i,h=Object.keys(u).filter(o=>!ENTRY_KEYS.includes(o));if(h.length){n.push(`${E}: unknown key${h.length===1?"":"s"} ${h.map(o=>JSON.stringify(o)).join(", ")} for a ${r} source (known: ${ENTRY_KEYS.join(", ")}) \u2014 not read`);return}const a=u.name;if(typeof a!="string"||!a.trim()||!NAME_RE.test(a)){n.push(`${f}: name ${JSON.stringify(a??null)} must be 1\u2013100 characters, not blank \u2014 not read`);return}if(s.some(o=>o.name===a)){n.push(`${E}: the name is declared twice on this service \u2014 read once`);return}const _=u.path;if(typeof _!="string"||!PATH_RE.test(_)||_.split("?")[0].split("/").includes("..")){n.push(`${E}: path ${JSON.stringify(_??null)} must be a route on the service, starting with "/" (e.g. "/api/dev/lens/backlog") \u2014 not read`);return}const m=u.intervalSec;if(m!==void 0&&!(typeof m=="number"&&Number.isInteger(m)&&m>=exports.SOURCE_MIN_INTERVAL_SEC&&m<=3600)){n.push(`${E}: intervalSec ${JSON.stringify(m)} must be a whole number of seconds from ${exports.SOURCE_MIN_INTERVAL_SEC} to 3600 \u2014 not read`);return}const S=u.thresholds;if(S!==void 0&&!isObj(S)){n.push(`${E}: thresholds must be an object \u2014 not read`);return}const O=isObj(S)?S:{},y=Object.keys(O).filter(o=>!THRESHOLD_KEYS[r].includes(o));if(y.length){n.push(`${E}: unknown threshold${y.length===1?"":"s"} ${y.map(o=>JSON.stringify(o)).join(", ")} for a ${r} source (known: ${THRESHOLD_KEYS[r].join(", ")}) \u2014 not read`);return}const t=THRESHOLD_KEYS[r].find(o=>O[o]!==void 0&&!minutes(O[o]));if(t){n.push(`${E}: thresholds.${t} ${JSON.stringify(O[t])} must be minutes, more than 0 and at most 10080 \u2014 not read`);return}if(s.length>=exports.SOURCE_MAX_PER_SERVICE){n.push(`${E}: more than ${exports.SOURCE_MAX_PER_SERVICE} sources on one service \u2014 not read`);return}s.push({kind:r,name:a,path:_,intervalSec:m??exports.SOURCE_DEFAULT_INTERVAL_SEC,thresholds:{oldestWaitMin:O.oldestWaitMin??exports.QUEUE_DEFAULT_OLDEST_WAIT_MIN,...O.stalledMin!==void 0?{stalledMin:O.stalledMin}:{}}})}),{sources:s,problems:n}):{sources:s,problems:["`sources` is not a list of { kind, name, path } entries \u2014 no source is read"]}}x(parseSourceDecls,"parseSourceDecls"),v(parseSourceDecls,"parseSourceDecls"),l(parseSourceDecls,"parseSourceDecls");const ISO_RE=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$/,isIso=l(e=>typeof e=="string"&&ISO_RE.test(e)&&!Number.isNaN(Date.parse(e)),"isIso"),isCount=l(e=>typeof e=="number"&&Number.isSafeInteger(e)&&e>=0,"isCount");function parseQueueSnapshot(e){const s=l(i=>({ok:!1,reason:i}),"fail");if(!isObj(e))return s("the snapshot is not a JSON object");if(e.schema!==exports.QUEUE_WIRE_SCHEMA)return s(`schema is ${e.schema===void 0?"absent":JSON.stringify(e.schema).slice(0,60)}, not "${exports.QUEUE_WIRE_SCHEMA}"`);const n=e.at;if(!isIso(n))return s("`at` is not an ISO time");const u=e.truncated;if(u!==void 0&&!(isObj(u)&&isCount(u.groups)))return s("`truncated` must be { groups: <how many were dropped> }, or absent");const p=e.groups;if(!Array.isArray(p))return s("`groups` is not a list");if(p.length>exports.SOURCE_MAX_GROUPS)return s(`${p.length} groups \u2014 at most ${exports.SOURCE_MAX_GROUPS}; cap them and say \`truncated: { groups: <dropped> }\``);const f=new Set,E=[];for(let i=0;i<p.length;i++){const r=p[i],h=`groups[${i}]`;if(!isObj(r))return s(`${h} is not an object`);const a=r.key;if(typeof a!="string"||a.length===0||a.length>200)return s(`${h}.key must be a string of 1\u2013200 characters`);if(f.has(a))return s(`${h}.key ${JSON.stringify(a)} appears twice`);if(f.add(a),!isCount(r.pending))return s(`${h}.pending must be a whole number \u2265 0`);for(const S of["inFlight","failed","completedInWindow"])if(r[S]!==void 0&&!isCount(r[S]))return s(`${h}.${S} must be a whole number \u2265 0, or absent`);const _=r.oldestPendingAt;if(_!=null&&!isIso(_))return s(`${h}.oldestPendingAt must be an ISO time, null, or absent`);const m=r.labels;if(m!==void 0){if(!isObj(m))return s(`${h}.labels must be an object of strings`);const S=Object.entries(m);if(S.length>16)return s(`${h}.labels has more than 16 entries`);for(const[O,y]of S)if(O.length===0||O.length>64||typeof y!="string"||y.length>200)return s(`${h}.labels.${O.slice(0,64)} must be a string of at most 200 characters`)}E.push({key:a,...m!==void 0?{labels:m}:{},pending:r.pending,...r.inFlight!==void 0?{inFlight:r.inFlight}:{},...r.failed!==void 0?{failed:r.failed}:{},..._!==void 0?{oldestPendingAt:_}:{},...r.completedInWindow!==void 0?{completedInWindow:r.completedInWindow}:{}})}return{ok:!0,at:n,groups:E,...u!==void 0?{truncated:{groups:u.groups}}:{}}}x(parseQueueSnapshot,"parseQueueSnapshot"),v(parseQueueSnapshot,"parseQueueSnapshot"),l(parseQueueSnapshot,"parseQueueSnapshot");const declRaw=l(e=>({sourceKind:e.kind,name:e.name,path:e.path,intervalSec:e.intervalSec,thresholds:{...e.thresholds}}),"declRaw"),oldestOf=l(e=>e.pending>0&&e.oldestPendingAt?Date.parse(e.oldestPendingAt):Number.POSITIVE_INFINITY,"oldestOf");function keepQueueSnapshot(e,s,n,u){const p={groups:s.length,pending:0,inFlight:0,failed:0};let f;for(const i of s)p.pending+=i.pending,p.inFlight+=i.inFlight??0,p.failed+=i.failed??0,i.completedInWindow!==void 0&&(f=(f??0)+i.completedInWindow);f!==void 0&&(p.completedInWindow=f);const E=[...s].sort((i,r)=>oldestOf(i)-oldestOf(r)||r.pending-i.pending||(i.key<r.key?-1:i.key>r.key?1:0));return{at:e,receivedAt:n,totals:p,groups:E.map(({key:i,...r})=>({group:i,...r})),...u?{truncated:{groups:u.groups}}:{}}}x(keepQueueSnapshot,"keepQueueSnapshot"),v(keepQueueSnapshot,"keepQueueSnapshot"),l(keepQueueSnapshot,"keepQueueSnapshot");function buildSourcePollRaw(e,s,n,u,p,f){return{kind:"source-poll",provenance:"reported",project:e,...declRaw(s),state:n.state,...n.detail!==void 0?{detail:n.detail}:{},...n.status!==void 0?{status:n.status}:{},polledAt:n.polledAt,...n.durationMs!==void 0?{durationMs:n.durationMs}:{},reportEveryMs:u,...p>0?{failures:p}:{},...f?{snapshot:f}:{}}}x(buildSourcePollRaw,"buildSourcePollRaw"),v(buildSourcePollRaw,"buildSourcePollRaw"),l(buildSourcePollRaw,"buildSourcePollRaw");function buildSourceDeclarationRaw(e,s){return{kind:"source-declaration",project:e,sources:s.sources.map(declRaw),problems:[...s.problems]}}x(buildSourceDeclarationRaw,"buildSourceDeclarationRaw"),v(buildSourceDeclarationRaw,"buildSourceDeclarationRaw"),l(buildSourceDeclarationRaw,"buildSourceDeclarationRaw");const span=l(e=>{const s=Math.round(e/6e4);return e<6e4?`${Math.max(0,Math.round(e/1e3))}s`:s<120?`${s}m`:`${Math.floor(s/60)}h${s%60?` ${s%60}m`:""}`},"span");function sourcePollTitle(e){const s=`${e.sourceKind} ${e.project}/${e.name} (reported)`;if(e.state!=="current"||!e.snapshot)return`${s}: ${e.state}${e.detail?` \u2014 ${e.detail}`:""}`;const n=e.snapshot,u=n.groups.find(f=>f.pending>0&&f.oldestPendingAt),p=u?.oldestPendingAt?Date.parse(n.at)-Date.parse(u.oldestPendingAt):void 0;return`${s}: ${n.totals.pending} pending in ${n.totals.groups} group${n.totals.groups===1?"":"s"}${p!==void 0?`, oldest waiting ${span(Math.max(0,p))}`:""}`}x(sourcePollTitle,"sourcePollTitle"),v(sourcePollTitle,"sourcePollTitle"),l(sourcePollTitle,"sourcePollTitle");function requestOverSocket(e,s,n,u,p=exports.SOURCE_MAX_BYTES){return new Promise(f=>{let E=!1,i;const r=l(a=>{E||(E=!0,clearTimeout(h),f(a))},"finish"),h=setTimeout(()=>{r({ok:!1,code:"ETIMEDOUT",message:`no answer within ${u} ms`}),i?.destroy()},u);h.unref?.();try{i=http.request({socketPath:e,path:s,method:"GET",agent:!1,headers:n},a=>{const _=[];let m=0;a.on("data",S=>{if(!E){if(m+=S.length,m>p){r({ok:!0,status:a.statusCode??0,body:"",truncated:!0}),a.destroy();return}_.push(S)}}),a.on("end",()=>r({ok:!0,status:a.statusCode??0,body:Buffer.concat(_).toString("utf8"),truncated:!1})),a.on("error",S=>r({ok:!1,code:S.code??"ERESPONSE",message:S.message}))}),i.on("error",a=>r({ok:!1,code:a.code??"EREQUEST",message:a.message})),i.end()}catch(a){r({ok:!1,code:a.code??"EREQUEST",message:a.message})}})}x(requestOverSocket,"requestOverSocket"),v(requestOverSocket,"requestOverSocket"),l(requestOverSocket,"requestOverSocket");const snippet=l(e=>e.replace(/\s+/g," ").trim().slice(0,160),"snippet");function createSourcePoller(e){const s=e.now??Date.now,n=e.timeoutMs??(0,exports.sourcesTimeoutMs)(),u=Math.max(1,e.maxConcurrent??(0,exports.sourcesConcurrency)()),p=e.socketOf??(t=>(0,discovery_1.pickSock)(t.pool,e.scanTtlMs??1500)),f=e.request??requestOverSocket,E=e.log??(t=>console.warn(t)),i=new WeakMap,r=new Map;let h=0,a;const _=l(t=>{const o=t.decl;let d=i.get(o);if(!d){d=parseSourceDecls(t.decl.sources),i.set(o,d);for(const c of d.problems)E(`[gateway] ${t.project}: cluster.sources \u2014 ${c}`)}const M=s();return(d.reportedAt===void 0||M-d.reportedAt>=exports.SOURCE_DECLARATION_REPORT_MS)&&(d.reportedAt=M,e.emit(t,d.problems.length?"warning":"info",d.problems.length?`sources ${t.project}: ${d.problems.length} cluster.sources entr${d.problems.length===1?"y":"ies"} not read \u2014 ${d.problems[0]}`:`sources ${t.project}: reads ${d.sources.map(c=>`${c.kind} "${c.name}"`).join(", ")}`,`source-declaration:${t.wsKey}:${t.project}`,buildSourceDeclarationRaw(t.project,d))),d},"declarationOf"),m=l(t=>{if(t.state==="starting")return{notRunning:"it is starting \u2014 read once it is up"};const o=p(t);return o?{socket:o}:{notRunning:t.state==="up"?"it has no live pod socket \u2014 no pod runs it now":"it is scaled to zero \u2014 the lens does not start a service to read a source"}},"reach"),S=l((t,o)=>{const d=t.last;if(!d)return;const M=s();if(!o&&t.reportedAt!==void 0&&M-t.reportedAt<t.reportEveryMs)return;t.reportedAt=M;const c=buildSourcePollRaw(t.svc.project,t.decl,d,t.reportEveryMs,t.failures,t.good),R=d.state==="unreachable"||d.state==="refused"||d.state==="malformed";e.emit(t.svc,R?"warning":"info",sourcePollTitle(c),`source:${t.svc.wsKey}:${t.svc.project}:${t.decl.name}`,c)},"report"),O=l(async t=>{const o=s(),d=t.decl.intervalSec*1e3;t.inFlight=!0,h+=1;const M=t.last?.state;try{const c=m(t.svc);if("notRunning"in c){t.last={state:"not-running",detail:c.notRunning,polledAt:o},t.failures=0,t.nextAt=o+d,t.reportEveryMs=exports.SOURCE_NOT_RUNNING_REPORT_MS,S(t,M!=="not-running");return}const R=e.serviceKey(t.svc),g=await f(c.socket,t.decl.path,{accept:"application/json","x-lensmcp-probe":`source:${t.decl.kind}`,...R?{"x-internal-token":R}:{}},n,exports.SOURCE_MAX_BYTES),$=Math.max(0,s()-o);if(g.ok===!1){const A=g.code==="ECONNREFUSED"||g.code==="ENOENT";t.last=A&&t.svc.state!=="up"?{state:"not-running",detail:`nothing listens on its pod socket \u2014 the service is ${t.svc.state}`,polledAt:o,durationMs:$}:{state:"unreachable",detail:g.code==="ETIMEDOUT"?g.message:`${g.code}: ${snippet(g.message)}`,polledAt:o,durationMs:$}}else if(g.status<200||g.status>299){const A=snippet(g.body);t.last={state:"refused",status:g.status,detail:`HTTP ${g.status}${A?`: ${A}`:""}`,polledAt:o,durationMs:$}}else if(g.truncated)t.last={state:"malformed",detail:`the snapshot is larger than ${exports.SOURCE_MAX_BYTES/1024} KiB`,polledAt:o,durationMs:$};else{let A;try{A=parseQueueSnapshot(JSON.parse(g.body))}catch{A={ok:!1,reason:`not JSON: ${snippet(g.body)||"(an empty body)"}`}}A.ok===!0?(t.good=keepQueueSnapshot(A.at,A.groups,s(),A.truncated),t.last={state:"current",polledAt:o,durationMs:$}):t.last={state:"malformed",detail:A.reason,polledAt:o,durationMs:$}}const C=t.last.state==="unreachable"||t.last.state==="refused"||t.last.state==="malformed";t.failures=C?t.failures+1:0;const N=C?sourceBackoffMs(d,t.failures):d;t.nextAt=o+N,t.reportEveryMs=t.last.state==="not-running"?exports.SOURCE_NOT_RUNNING_REPORT_MS:N,S(t,t.last.state!=="not-running"||M!=="not-running")}catch(c){t.last={state:"unreachable",detail:`the poll failed: ${snippet(c?.message??String(c))}`,polledAt:o},t.failures+=1,t.nextAt=o+sourceBackoffMs(d,t.failures),t.reportEveryMs=t.nextAt-o,S(t,!0)}finally{t.inFlight=!1,h-=1}},"pollOne"),y=l(async()=>{if(e.stopped?.())return;const t=new Set;for(const c of e.services())if(c.decl.sources!==void 0)for(const R of _(c).sources){const g=`${c.wsKey} ${c.project} ${R.name}`;t.add(g);const $=r.get(g);$?($.svc!==c||$.decl!==R)&&($.svc=c,$.decl=R):r.set(g,{svc:c,decl:R,nextAt:0,inFlight:!1,failures:0,reportEveryMs:R.intervalSec*1e3})}for(const[c,R]of[...r.entries()])!t.has(c)&&!R.inFlight&&r.delete(c);const o=s(),d=[...r.values()].filter(c=>!c.inFlight&&o>=c.nextAt).sort((c,R)=>c.nextAt-R.nextAt),M=[];for(const c of d){if(h>=u)break;M.push(O(c))}await Promise.all(M)},"tick");return{tick:y,start(t=1e3){return a&&clearInterval(a),a=setInterval(()=>{y().catch(o=>console.error("[gateway] source poll error:",o))},t),a.unref(),a},stop(){a&&clearInterval(a),a=void 0},snapshot(){const t=s();return[...r.values()].map(o=>{const d=o.last!==void 0&&t-o.last.polledAt>(0,exports.sourceStaleAfterMs)(o.reportEveryMs);return{wsKey:o.svc.wsKey,project:o.svc.project,name:o.decl.name,kind:o.decl.kind,path:o.decl.path,state:o.last?d?"stale":o.last.state:"never-polled",...o.last?.detail!==void 0?{detail:o.last.detail}:{},...o.last?.status!==void 0?{status:o.last.status}:{},...o.last?{polledAt:o.last.polledAt}:{},failures:o.failures,nextAt:o.nextAt,...o.good?{snapshot:o.good,ageMs:Math.max(0,t-o.good.receivedAt)}:{}}})}}}x(createSourcePoller,"createSourcePoller"),v(createSourcePoller,"createSourcePoller"),l(createSourcePoller,"createSourcePoller");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var C=Object.defineProperty;var L=(_,E)=>C(_,"name",{value:E,configurable:!0});var O=Object.defineProperty,e=L((_,E)=>O(_,"name",{value:E,configurable:!0}),"e"),M=Object.defineProperty,R=e((_,E)=>M(_,"name",{value:E,configurable:!0}),"R");Object.defineProperty(exports,"__esModule",{value:!0}),exports.GATEWAY_H2_RESET_RATE=exports.GATEWAY_H2_RESET_BURST=exports.BODY_STALL_MS=exports.GATEWAY_CONN_CHECK_MS=exports.GATEWAY_MAX_CONNECTIONS=exports.GATEWAY_STOP_GRACE_MS=exports.GATEWAY_HEADERS_TIMEOUT_MS=exports.GATEWAY_KEEPALIVE_TIMEOUT_MS=exports.LENS_REQUEST_RECOVERY_WAIT_MS=exports.LENS_REPLACEMENT_DRAIN_MS=exports.LENS_REPLACEMENT_READY_MS=exports.LENS_RESTART_MODE=exports.LENS_RECYCLE_KILL_GRACE_MS=exports.LENS_PARKED_PORT_REPROBE_MS=exports.MAX_PORT_CONFLICT_RETRIES=exports.CHILD_START_FAIL_MS=exports.PORT_FREE_POLL_MS=exports.PORT_FREE_WAIT_MS=exports.LENS_PROBE_BOOT_GRACE_MS=exports.LENS_PROBE_COOLDOWN_MS=exports.LENS_PROBE_TIMEOUT_MS=exports.LENS_PROBE_FAILS=exports.LENS_PROBE_GRACE_MS=exports.MAX_COLD_STARTS=exports.POD_MAX_CONCURRENT_ROLLS=exports.POD_ROLL_READY_MS=exports.POD_RECYCLE_MODE=exports.POD_WATCHER_SILENT=exports.POD_WATCHER_UNVERIFIED=exports.LENS_WATCH_SCOPE_ENABLED=exports.LENS_WATCHER_UNVERIFIED=exports.LENS_WATCHER_PROBE_ENABLED=exports.LENS_PROBE_ENABLED=exports.POD_STALE_RECYCLE_COOLDOWN_MS=exports.POD_STALE_SCAN_MS=exports.POD_RECYCLE_SETTLE_MS=exports.POD_STALE_GRACE_MS=exports.POD_MAX_AGE_MS=exports.POD_RECYCLE_ENABLED=exports.WEDGE_RECYCLE_GRACE_MS=exports.POD_ALIVE_PATH=exports.POD_WEDGE_CONFIRM_MS=exports.POD_ALIVE_PROBE_TIMEOUT_MS=exports.POD_SLOW_FIRST_BYTE_MS=exports.POD_RESPONSE_TIMEOUT_MS=exports.UPSTREAM_HEAL_STEP_MS=exports.UPSTREAM_HEAL_WINDOW_MS=exports.SERVICE_RESTART_WINDOW_MS=exports.SERVICE_MAX_RESTARTS=exports.SERVICE_ERROR_THROTTLE_MS=void 0;const tslib_1=require("tslib"),os=tslib_1.__importStar(require("node:os"));function envInt(_,E,T=!1){const S=Number(process.env[_]);return!Number.isFinite(S)||S<0?E:S===0?T?0:E:S}L(envInt,"envInt"),e(envInt,"envInt"),R(envInt,"envInt"),exports.SERVICE_ERROR_THROTTLE_MS=5e3,exports.SERVICE_MAX_RESTARTS=5,exports.SERVICE_RESTART_WINDOW_MS=6e4,exports.UPSTREAM_HEAL_WINDOW_MS=8e3,exports.UPSTREAM_HEAL_STEP_MS=300,exports.POD_RESPONSE_TIMEOUT_MS=(()=>{const _=Number(process.env.LENSMCP_POD_RESPONSE_TIMEOUT_MS);return Number.isFinite(_)&&_>0?_:3e4})(),exports.POD_SLOW_FIRST_BYTE_MS=envInt("LENSMCP_POD_SLOW_FIRST_BYTE_MS",10*6e4,!0),exports.POD_ALIVE_PROBE_TIMEOUT_MS=envInt("LENSMCP_POD_ALIVE_PROBE_TIMEOUT_MS",1e3),exports.POD_WEDGE_CONFIRM_MS=envInt("LENSMCP_POD_WEDGE_CONFIRM_MS",1e4,!0),exports.POD_ALIVE_PATH="/__lensmcp/alive",exports.WEDGE_RECYCLE_GRACE_MS=(()=>{const _=Number(process.env.LENSMCP_WEDGE_RECYCLE_GRACE_MS);return Number.isFinite(_)&&_>0?_:15e3})(),exports.POD_RECYCLE_ENABLED=process.env.LENSMCP_POD_RECYCLE!=="0",exports.POD_MAX_AGE_MS=envInt("LENSMCP_POD_MAX_AGE_MS",240*6e4,!0),exports.POD_STALE_GRACE_MS=envInt("LENSMCP_POD_STALE_GRACE_MS",1e4),exports.POD_RECYCLE_SETTLE_MS=envInt("LENSMCP_POD_RECYCLE_SETTLE_MS",8e3),exports.POD_STALE_SCAN_MS=envInt("LENSMCP_POD_STALE_SCAN_MS",3e4),exports.POD_STALE_RECYCLE_COOLDOWN_MS=envInt("LENSMCP_POD_STALE_RECYCLE_COOLDOWN_MS",6e4),exports.LENS_PROBE_ENABLED=process.env.LENSMCP_LENS_PROBE!=="0",exports.LENS_WATCHER_PROBE_ENABLED=process.env.LENSMCP_LENS_WATCHER_PROBE!=="0",exports.LENS_WATCHER_UNVERIFIED=process.env.LENSMCP_LENS_WATCHER_UNVERIFIED==="keep"?"keep":"recycle",exports.LENS_WATCH_SCOPE_ENABLED=process.env.LENSMCP_LENS_WATCH_SCOPE!=="0",exports.POD_WATCHER_UNVERIFIED=process.env.LENSMCP_POD_WATCHER_UNVERIFIED==="keep"?"keep":"recycle",exports.POD_WATCHER_SILENT=process.env.LENSMCP_POD_WATCHER_SILENT==="recycle"?"recycle":"keep",exports.POD_RECYCLE_MODE=process.env.LENSMCP_POD_RECYCLE_MODE==="in-place"?"in-place":"rolling",exports.POD_ROLL_READY_MS=envInt("LENSMCP_POD_ROLL_READY_MS",18e4),exports.POD_MAX_CONCURRENT_ROLLS=envInt("LENSMCP_POD_MAX_CONCURRENT_ROLLS",2,!0),exports.MAX_COLD_STARTS=envInt("LENSMCP_MAX_COLD_STARTS",Math.max(2,Math.floor(os.availableParallelism()/2)),!0),exports.LENS_PROBE_GRACE_MS=envInt("LENSMCP_LENS_PROBE_GRACE_MS",45e3),exports.LENS_PROBE_FAILS=envInt("LENSMCP_LENS_PROBE_FAILS",2),exports.LENS_PROBE_TIMEOUT_MS=envInt("LENSMCP_LENS_PROBE_TIMEOUT_MS",1e3),exports.LENS_PROBE_COOLDOWN_MS=envInt("LENSMCP_LENS_PROBE_COOLDOWN_MS",3e4),exports.LENS_PROBE_BOOT_GRACE_MS=envInt("LENSMCP_LENS_PROBE_BOOT_GRACE_MS",24e4),exports.PORT_FREE_WAIT_MS=envInt("LENSMCP_PORT_FREE_WAIT_MS",1e4),exports.PORT_FREE_POLL_MS=envInt("LENSMCP_PORT_FREE_POLL_MS",250),exports.CHILD_START_FAIL_MS=envInt("LENSMCP_CHILD_START_FAIL_MS",1e4),exports.MAX_PORT_CONFLICT_RETRIES=envInt("LENSMCP_MAX_PORT_CONFLICT_RETRIES",5),exports.LENS_PARKED_PORT_REPROBE_MS=envInt("LENSMCP_PARKED_PORT_REPROBE_MS",3e5),exports.LENS_RECYCLE_KILL_GRACE_MS=envInt("LENSMCP_RECYCLE_KILL_GRACE_MS",5e3),exports.LENS_RESTART_MODE=process.env.LENSMCP_LENS_RESTART_MODE==="in-place"?"in-place":"rolling",exports.LENS_REPLACEMENT_READY_MS=envInt("LENSMCP_LENS_REPLACEMENT_READY_MS",3e4),exports.LENS_REPLACEMENT_DRAIN_MS=envInt("LENSMCP_LENS_REPLACEMENT_DRAIN_MS",2e3,!0),exports.LENS_REQUEST_RECOVERY_WAIT_MS=envInt("LENSMCP_LENS_REQUEST_RECOVERY_WAIT_MS",15e3),exports.GATEWAY_KEEPALIVE_TIMEOUT_MS=envInt("LENSMCP_KEEPALIVE_TIMEOUT_MS",76e3),exports.GATEWAY_HEADERS_TIMEOUT_MS=envInt("LENSMCP_HEADERS_TIMEOUT_MS",6e4),exports.GATEWAY_STOP_GRACE_MS=envInt("LENSMCP_STOP_GRACE_MS",3e3),exports.GATEWAY_MAX_CONNECTIONS=envInt("LENSMCP_MAX_CONNECTIONS",0,!0),exports.GATEWAY_CONN_CHECK_MS=envInt("LENSMCP_CONN_CHECK_MS",0,!0),exports.BODY_STALL_MS=envInt("LENSMCP_BODY_STALL_MS",6e4,!0),exports.GATEWAY_H2_RESET_BURST=envInt("LENSMCP_H2_RESET_BURST",1e5),exports.GATEWAY_H2_RESET_RATE=envInt("LENSMCP_H2_RESET_RATE",1e4);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var P=Object.defineProperty;var v=(a,o)=>P(a,"name",{value:o,configurable:!0});var K=Object.defineProperty,w=v((a,o)=>K(a,"name",{value:o,configurable:!0}),"w"),M=Object.defineProperty,u=w((a,o)=>M(a,"name",{value:o,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.LENS_HMR_REFUSAL_REPORT_MS=void 0,exports.createUpgrade=createUpgrade;const tslib_1=require("tslib"),path=tslib_1.__importStar(require("node:path")),manifest_1=require("../manifest"),discovery_1=require("./discovery"),edge_1=require("./edge"),hmr_reload_1=require("./hmr-reload"),service_keys_1=require("./service-keys");exports.LENS_HMR_REFUSAL_REPORT_MS=1e4;function accountUpgrade(a,o){const i=a.svc;if(!i||o.destroyed)return;i.inflight+=1,i.lastUsed=Date.now();let d=!1;o.once("close",()=>{d||(d=!0,i.inflight-=1,i.lastUsed=Date.now())})}v(accountUpgrade,"accountUpgrade"),w(accountUpgrade,"accountUpgrade"),u(accountUpgrade,"accountUpgrade");function createUpgrade(a){const{rt:o,auth:i,proxy:d,hooks:p,obs:S}=a,y=new Set,k=u(e=>{e.destroyed||(y.add(e),e.once("close",()=>y.delete(e)))},"track");d.proxy.on?.("open",k);const _=new WeakMap,m=new Map,R=u((e,r)=>{const s=Date.now();s-(m.get(e.frontendKey)??0)<exports.LENS_HMR_REFUSAL_REPORT_MS||(m.set(e.frontendKey,s),console.warn(`[gateway] lens HMR socket refused: ${e.frontendKey} at ${e.target} answered ${r} for a tab on ${e.host} \u2014 that tab loads but gets no hot updates; the lens runtime reloads it once if it had a socket before.`),S?.emit("warning",`lens HMR socket refused: ${e.frontendKey} (${r})`,`cluster-lens-hmr-refused:${e.frontendKey}`,{kind:"lens-hmr-refused",frontendKey:e.frontendKey,host:e.host,target:e.target,answer:r},void 0,e.busFile))},"reportRefusal");d.proxy.on?.("proxyReqWs",(e,r)=>{const s=_.get(r);if(!s)return;const c=e;c.once("upgrade",()=>{s.answered=!0}),c.once("response",g=>{s.answered=!0,R(s,`HTTP ${g.statusCode??"?"}`)})});const U=u(async(e,r,s)=>{(0,edge_1.stripOwnedHeaders)(e);const c=(0,edge_1.canonicalize)(e.url??"/");if(c===void 0){r.destroy();return}e.url=c.path+c.query;const g=(e.headers.host||"").split(":")[0],t=(0,manifest_1.matchRoute)(o.routes,g,c.policy+c.query);if(!t){r.destroy();return}(0,edge_1.resolveClientIp)(o,e);const l=p.upgradeContext(e,r,void 0);if(l.route=t,t.internal){const n=i.internal(e,t,void 0);if(!n.ok){r.destroy();return}l.caller=n.caller}else{const n=i.public(e,t,void 0,c.policy);if(!n.ok){r.destroy();return}if(l.claims=n.claims,p.has("afterAuth")&&(await p.run("afterAuth",l),l.responded()))return}const x=t.pool?o.serviceKeys[(0,service_keys_1.serviceKeyId)(t.svc?.wsKey,t.project)]:void 0;if(x&&(e.headers["x-internal-token"]=x),t.prependPrefix&&!e.url?.startsWith(t.prependPrefix)&&(e.url=t.prependPrefix+(e.url??"/")),(0,edge_1.stampForwardingHeaders)(o,e),p.has("onUpgrade")&&(await p.run("onUpgrade",l),l.responded()))return;const h=t.pool?(()=>{const n=(0,discovery_1.pickSock)(t.pool,o.scanTtlMs);return n?{socketPath:n}:void 0})():t.target;if(!h){r.destroy();return}if(t.lens&&String(e.headers["sec-websocket-protocol"]??"").split(",").map(n=>n.trim()).includes("vite-hmr")){const n=t.lens.workspaceKey?`${t.lens.workspaceKey}:${t.lens.project}`:t.lens.project;(0,hmr_reload_1.registerHmrClient)(o,n,r);const f=!t.lens.workspaceRoot||path.resolve(t.lens.workspaceRoot)===path.resolve(o.root??"");_.set(e,{frontendKey:n,host:g,target:String(h),answered:!1,...f?{}:{busFile:path.join(t.lens.workspaceRoot,".lensmcp","events.jsonl")}})}accountUpgrade(t,r),d.proxy.ws(e,r,s,{target:h,changeOrigin:!t.pool,agent:d.agentForTarget(h)},n=>{const f=_.get(e);f&&!f.answered&&R(f,n?.code??n?.message??"an error"),r.destroy()})},"run"),b=u(((e,r,s)=>{r.on("error",()=>r.destroy()),k(r),U(e,r,s).catch(()=>r.destroy())}),"listener");return b.closeTunnels=()=>{const e=[...y];for(const r of e)r.destroy();return y.clear(),e.length},b}v(createUpgrade,"createUpgrade"),w(createUpgrade,"createUpgrade"),u(createUpgrade,"createUpgrade");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var d=Object.defineProperty;var o=(e,t)=>d(e,"name",{value:t,configurable:!0});var a=Object.defineProperty,r=o((e,t)=>a(e,"name",{value:t,configurable:!0}),"r"),s=Object.defineProperty,n=r((e,t)=>s(e,"name",{value:t,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.workspaceLogWriter=workspaceLogWriter,exports.closeWorkspaceLogs=closeWorkspaceLogs;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path")),inspector_secret_1=require("../../../inspector-secret"),fds=new Map,written=new Map,MAX_BYTES=50*1024*1024,CHECK_EVERY=1024*1024;function ensurePrivateDir(e){fs.mkdirSync(e,{recursive:!0,mode:448});try{const t=fs.statSync(e);(t.mode&63)!==0&&(typeof process.getuid!="function"||t.uid===process.getuid())&&fs.chmodSync(e,448)}catch{}}o(ensurePrivateDir,"ensurePrivateDir"),r(ensurePrivateDir,"ensurePrivateDir"),n(ensurePrivateDir,"ensurePrivateDir");function ownerOnly(e){try{fs.chmodSync(e,384)}catch{}}o(ownerOnly,"ownerOnly"),r(ownerOnly,"ownerOnly"),n(ownerOnly,"ownerOnly");function ensureFd(e){const t=fds.get(e);if(t!==void 0)return t;try{ensurePrivateDir(path.dirname(e));const c=fs.openSync(e,"a",384);return ownerOnly(e),fds.set(e,c),written.set(e,0),c}catch{return}}o(ensureFd,"ensureFd"),r(ensureFd,"ensureFd"),n(ensureFd,"ensureFd");function closeFd(e){const t=fds.get(e);if(fds.delete(e),written.delete(e),t!==void 0)try{fs.closeSync(t)}catch{}}o(closeFd,"closeFd"),r(closeFd,"closeFd"),n(closeFd,"closeFd");function rotateIfHuge(e){try{if(fs.statSync(e).size<=MAX_BYTES)return}catch{return}closeFd(e);try{fs.renameSync(e,`${e}.1`)}catch{}ownerOnly(`${e}.1`)}o(rotateIfHuge,"rotateIfHuge"),r(rotateIfHuge,"rotateIfHuge"),n(rotateIfHuge,"rotateIfHuge");function workspaceLogWriter(e){const t=path.join(e,".lensmcp","gateway.log");if(ensureFd(t)!==void 0)return c=>{const i=ensureFd(t);if(i===void 0)return;try{fs.writeSync(i,(0,inspector_secret_1.redactInspectorUrls)(c))}catch{closeFd(t);return}const u=(written.get(t)??0)+c.length;u>=CHECK_EVERY?(written.set(t,0),rotateIfHuge(t)):written.set(t,u)}}o(workspaceLogWriter,"workspaceLogWriter"),r(workspaceLogWriter,"workspaceLogWriter"),n(workspaceLogWriter,"workspaceLogWriter");function closeWorkspaceLogs(){for(const e of[...fds.keys()])closeFd(e)}o(closeWorkspaceLogs,"closeWorkspaceLogs"),r(closeWorkspaceLogs,"closeWorkspaceLogs"),n(closeWorkspaceLogs,"closeWorkspaceLogs");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var p=Object.defineProperty;var d=(e,r)=>p(e,"name",{value:r,configurable:!0});var w=Object.defineProperty,a=d((e,r)=>w(e,"name",{value:r,configurable:!0}),"a"),c=Object.defineProperty,i=a((e,r)=>c(e,"name",{value:r,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.guestMiddlewarePolicy=guestMiddlewarePolicy,exports.findGatewayMiddleware=findGatewayMiddleware,exports.loadMiddleware=loadMiddleware,exports.createWorkspaceMiddleware=createWorkspaceMiddleware;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path"));function guestMiddlewarePolicy(e=process.env){const r=e.LENSMCP_GUEST_MIDDLEWARE;return r==="owner"||r==="none"?r:"own"}d(guestMiddlewarePolicy,"guestMiddlewarePolicy"),a(guestMiddlewarePolicy,"guestMiddlewarePolicy"),i(guestMiddlewarePolicy,"guestMiddlewarePolicy");function findGatewayMiddleware(e,r){for(const n of Object.values(r)){let o;try{o=JSON.parse(fs.readFileSync(path.join(e,n.root,"project.json"),"utf8"))}catch{continue}for(const t of Object.values(o.targets??{}))if(t?.executor==="@lensmcp/cluster:gateway"&&typeof t.options?.middleware=="string"&&t.options.middleware)return t.options.middleware}}d(findGatewayMiddleware,"findGatewayMiddleware"),a(findGatewayMiddleware,"findGatewayMiddleware"),i(findGatewayMiddleware,"findGatewayMiddleware");function loadMiddleware(e){const r=require.resolve(e);delete require.cache[r];const n=require(r),o=n.default??n;if(typeof o!="function")throw new Error(`${e} exports no function`);return o}d(loadMiddleware,"loadMiddleware"),a(loadMiddleware,"loadMiddleware"),i(loadMiddleware,"loadMiddleware");function createWorkspaceMiddleware(e){const r=e.policy??"own",n=e.load??loadMiddleware,o=new Map;return{set(t,u,l){if(t===e.ownerKey)return;if(!l){o.set(t,void 0);return}const s=path.resolve(u,l);try{o.set(t,n(s)),r==="own"&&console.log(`[gateway] '${t}' routes run its own middleware: ${s}`)}catch(f){o.set(t,void 0),console.warn(`[gateway] could not load '${t}''s middleware ${s} (${f.message}) \u2014 its routes run with NO middleware until it registers again`)}},drop(t){o.delete(t)},for(t){if(t===void 0||t===e.ownerKey||r==="owner")return e.owner;if(r!=="none")return o.get(t)}}}d(createWorkspaceMiddleware,"createWorkspaceMiddleware"),a(createWorkspaceMiddleware,"createWorkspaceMiddleware"),i(createWorkspaceMiddleware,"createWorkspaceMiddleware");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var u=Object.defineProperty;var o=(r,e)=>u(r,"name",{value:e,configurable:!0});var p=Object.defineProperty,i=o((r,e)=>p(r,"name",{value:e,configurable:!0}),"i"),c=Object.defineProperty,s=i((r,e)=>c(r,"name",{value:e,configurable:!0}),"s");Object.defineProperty(exports,"__esModule",{value:!0}),exports.processStamp=processStamp,exports.registryPath=registryPath,exports.readWorkspaces=readWorkspaces,exports.registerWorkspace=registerWorkspace,exports.unregisterWorkspace=unregisterWorkspace,exports.isWorkspaceLive=isWorkspaceLive;const tslib_1=require("tslib"),node_child_process_1=require("node:child_process"),fs=tslib_1.__importStar(require("node:fs")),os=tslib_1.__importStar(require("node:os")),path=tslib_1.__importStar(require("node:path"));function processStamp(r){if(!r||r<=0||process.platform==="win32")return"";try{return(0,node_child_process_1.execFileSync)("ps",["-p",String(r),"-o","lstart="],{encoding:"utf8",timeout:2e3,stdio:["ignore","pipe","ignore"]}).trim()}catch{return""}}o(processStamp,"processStamp"),i(processStamp,"processStamp"),s(processStamp,"processStamp");function registryPath(){const r=process.env.LENSMCP_HOME||os.homedir();return path.join(r,".lensmcp","workspaces.json")}o(registryPath,"registryPath"),i(registryPath,"registryPath"),s(registryPath,"registryPath");function readWorkspaces(r=registryPath()){try{const e=JSON.parse(fs.readFileSync(r,"utf8"));return Array.isArray(e)?e.filter(t=>!!t&&typeof t.key=="string"&&typeof t.base=="string"):[]}catch{return[]}}o(readWorkspaces,"readWorkspaces"),i(readWorkspaces,"readWorkspaces"),s(readWorkspaces,"readWorkspaces");function writeWorkspaces(r,e=registryPath()){try{fs.mkdirSync(path.dirname(e),{recursive:!0}),fs.writeFileSync(e,JSON.stringify(r,null,2))}catch{}}o(writeWorkspaces,"writeWorkspaces"),i(writeWorkspaces,"writeWorkspaces"),s(writeWorkspaces,"writeWorkspaces");function registerWorkspace(r,e=registryPath()){const t=readWorkspaces(e).filter(n=>n.key!==r.key);t.push(r),t.sort((n,a)=>n.key.localeCompare(a.key)),writeWorkspaces(t,e)}o(registerWorkspace,"registerWorkspace"),i(registerWorkspace,"registerWorkspace"),s(registerWorkspace,"registerWorkspace");function unregisterWorkspace(r,e=registryPath()){writeWorkspaces(readWorkspaces(e).filter(t=>t.key!==r),e)}o(unregisterWorkspace,"unregisterWorkspace"),i(unregisterWorkspace,"unregisterWorkspace"),s(unregisterWorkspace,"unregisterWorkspace");function isWorkspaceLive(r){if(!r.pid||r.pid<=0)return!1;try{process.kill(r.pid,0)}catch(t){if(t.code!=="EPERM")return!1}if(!r.procStamp)return!0;const e=processStamp(r.pid);return e===""?!0:e===r.procStamp}o(isWorkspaceLive,"isWorkspaceLive"),i(isWorkspaceLive,"isWorkspaceLive"),s(isWorkspaceLive,"isWorkspaceLive");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var b=Object.defineProperty;var c=(e,t)=>b(e,"name",{value:t,configurable:!0});var h=Object.defineProperty,l=c((e,t)=>h(e,"name",{value:t,configurable:!0}),"l"),u=Object.defineProperty,i=l((e,t)=>u(e,"name",{value:t,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.SsrfBlockedError=void 0,exports.isBlockedAddress=isBlockedAddress,exports.assertFetchableUrl=assertFetchableUrl,exports.safeFetch=safeFetch,exports.pinnedLookup=pinnedLookup;const node_net_1=require("node:net"),promises_1=require("node:dns/promises");class SsrfBlockedError extends Error{static{c(this,"SsrfBlockedError")}static{l(this,"SsrfBlockedError")}static{i(this,"SsrfBlockedError")}constructor(t,o,r,s){super(`SSRF guard blocked ${o??"request"}: ${t}${r?` (${r})`:""}`,s!==void 0?{cause:s}:void 0),this.name="SsrfBlockedError",this.reason=t,this.url=o,this.address=r}}exports.SsrfBlockedError=SsrfBlockedError;function buildDefaultBlockList(){const e=new node_net_1.BlockList;return e.addSubnet("0.0.0.0",8,"ipv4"),e.addSubnet("10.0.0.0",8,"ipv4"),e.addSubnet("100.64.0.0",10,"ipv4"),e.addSubnet("127.0.0.0",8,"ipv4"),e.addSubnet("169.254.0.0",16,"ipv4"),e.addSubnet("172.16.0.0",12,"ipv4"),e.addSubnet("192.0.0.0",24,"ipv4"),e.addSubnet("192.168.0.0",16,"ipv4"),e.addSubnet("198.18.0.0",15,"ipv4"),e.addSubnet("240.0.0.0",4,"ipv4"),e.addAddress("::","ipv6"),e.addAddress("::1","ipv6"),e.addSubnet("fc00::",7,"ipv6"),e.addSubnet("fe80::",10,"ipv6"),e}c(buildDefaultBlockList,"buildDefaultBlockList"),l(buildDefaultBlockList,"buildDefaultBlockList"),i(buildDefaultBlockList,"buildDefaultBlockList");const DEFAULT_BLOCK_LIST=buildDefaultBlockList();function isBlockedAddress(e,t=DEFAULT_BLOCK_LIST){const o=(0,node_net_1.isIP)(e);return o===0?!0:t.check(e,o===6?"ipv6":"ipv4")}c(isBlockedAddress,"isBlockedAddress"),l(isBlockedAddress,"isBlockedAddress"),i(isBlockedAddress,"isBlockedAddress");const stripBrackets=i(e=>e.startsWith("[")&&e.endsWith("]")?e.slice(1,-1):e,"stripBrackets"),defaultResolve=i(async e=>(await(0,promises_1.lookup)(e,{all:!0,verbatim:!0})).map(t=>t.address),"defaultResolve");async function assertFetchableUrl(e,t={}){const o=t.allowedProtocols??["http:","https:"];let r;try{r=new URL(e)}catch{throw new SsrfBlockedError("malformed-url",String(e))}if(!o.includes(r.protocol))throw new SsrfBlockedError(`scheme-not-allowed:${r.protocol}`,r.href);if(r.username!==""||r.password!=="")throw new SsrfBlockedError("embedded-credentials",r.href);const s=stripBrackets(r.hostname);if(s==="")throw new SsrfBlockedError("missing-host",r.href);if(t.allowPrivate)return{url:r,hostname:s,addresses:(0,node_net_1.isIP)(s)?[s]:[]};const d=t.blockList??DEFAULT_BLOCK_LIST;if((0,node_net_1.isIP)(s)!==0){if(isBlockedAddress(s,d))throw new SsrfBlockedError("blocked-address",r.href,s);return{url:r,hostname:s,addresses:[s]}}const f=t.resolve??defaultResolve;let a;try{a=await f(s)}catch(n){throw new SsrfBlockedError("dns-resolution-failed",r.href,void 0,n)}if(a.length===0)throw new SsrfBlockedError("dns-no-records",r.href);for(const n of a)if(isBlockedAddress(n,d))throw new SsrfBlockedError("blocked-resolved-address",r.href,n);return{url:r,hostname:s,addresses:a}}c(assertFetchableUrl,"assertFetchableUrl"),l(assertFetchableUrl,"assertFetchableUrl"),i(assertFetchableUrl,"assertFetchableUrl");async function safeFetch(e,t={},o={}){const r=o.fetchImpl??globalThis.fetch,s=o.maxRedirects??5;let d=e;for(let f=0;;f++){const{url:a}=await assertFetchableUrl(d,o),n=await r(a,{...t,redirect:"manual"}),p=n.headers.get("location");if(n.status>=300&&n.status<400&&p){if(f>=s)throw new SsrfBlockedError("too-many-redirects",a.href);d=new URL(p,a).href;continue}return n}}c(safeFetch,"safeFetch"),l(safeFetch,"safeFetch"),i(safeFetch,"safeFetch");function pinnedLookup(e){const t=e.map(o=>({address:o,family:(0,node_net_1.isIP)(o)===6?6:4}));return(o,r,s)=>{const d=typeof r=="function"?r:s,f=typeof r=="object"&&r!==null&&r.all===!0;if(t.length===0){d(new Error(`SSRF guard: no pinned address for ${o}`));return}f?d(null,t):d(null,t[0].address,t[0].family)}}c(pinnedLookup,"pinnedLookup"),l(pinnedLookup,"pinnedLookup"),i(pinnedLookup,"pinnedLookup");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var ce=Object.defineProperty;var a=(e,t)=>ce(e,"name",{value:t,configurable:!0});var ie=Object.defineProperty,c=a((e,t)=>ie(e,"name",{value:t,configurable:!0}),"c"),se=Object.defineProperty,o=c((e,t)=>se(e,"name",{value:t,configurable:!0}),"o");Object.defineProperty(exports,"__esModule",{value:!0});const tslib_1=require("tslib"),path=tslib_1.__importStar(require("node:path")),fs=tslib_1.__importStar(require("node:fs")),node_child_process_1=require("node:child_process"),yaml=tslib_1.__importStar(require("js-yaml")),dev_devtool_1=require("../../dev-devtool"),devserver_notifier_1=require("../../devserver-notifier"),process_name_1=require("../../process-name"),worker_supervisor_1=require("../../worker-supervisor"),attach_1=require("../../shared-build/attach");function definedEnv(e){const t={};for(const[w,i]of Object.entries(e))typeof i=="string"&&(t[w]=i);return t}a(definedEnv,"definedEnv"),c(definedEnv,"definedEnv"),o(definedEnv,"definedEnv");const frozen=o(()=>process.env.LENSMCP_FREEZE==="1","frozen");async function*serveExecutor(e,t){process.env.NODE_ENV="development";const w=t.projectsConfigurations.projects[t.projectName],i=t.root,_=path.join(i,w.root),W=e.outputPath?path.join(i,e.outputPath):path.join(i,"dist",w.root),H=e.configEnv||"development",T=path.join(i,"config",`config.${H}.yaml`),k=3050;let p=k,l=t.projectName,y={};fs.existsSync(T)?(y=yaml.load(fs.readFileSync(T,"utf8")),p=Number(y.port)||p,l=y.serviceName||l):console.warn(`[serve] ${t.projectName}: no config file at ${T} \u2014 public devserver port defaults to ${k}. If another service also lacks its config, both bind ${k} \u2192 EADDRINUSE. Add config/config.${H}.yaml with a distinct \`port:\` (matching this project's cluster.port).`),e.serviceName&&(l=e.serviceName);const D=e.servePrefix??"",m=e.debugPort??(Number(process.env.LENSMCP_DEBUG_PORT)||void 0),Q=/^(1|true|yes|on)$/i.test((process.env.LENSMCP_DEBUG_FIXED_PORTS??"").trim()),v=e.logFile?path.resolve(i,e.logFile):process.env.LENSMCP_LOG_FILE||void 0;if(v){fs.mkdirSync(path.dirname(v),{recursive:!0}),fs.writeFileSync(v,"",{mode:384});try{fs.chmodSync(v,384)}catch{}}let x,I;e.gateway?.middleware&&(x=path.resolve(_,e.gateway.middleware),I=JSON.stringify(y));const Z=e.entryFile||"./src/deployments/service/main.ts",ee=e.tsConfigFile||"./tsconfig.app.json",oe=path.resolve(_,Z),V=path.resolve(_,ee),re=(e.workers||[]).map(r=>({entryName:r.name,entryPath:path.resolve(_,r.entryPath)})),J={appName:t.projectName,appRoot:_,outputDir:W,main:oe,tsConfig:V,assets:e.assets||[],additionalEntryPoints:re,port:p,serviceName:l,memoryLimit:e.memoryLimit||8192,buildLibsFromSource:e.buildLibsFromSource!==!1,workspaceRoot:i,orgScopes:e.orgScopes||[],bundlePackages:e.bundlePackages||[],nodeExternalsConfig:e.nodeExternalsConfig,webpackConfigPath:e.webpackConfigPath,httpsReload:e.gateway?.https===!0,...e.devtool!==void 0&&{devtool:e.devtool}};let u=null,A=!1,G=!1,f=!1;const Y=path.join(__dirname,"../../main.devserver.js"),X=path.join(__dirname,"../../main.devserver.ts"),z=!fs.existsSync(Y)&&fs.existsSync(X),M=z?X:Y,te=path.join(W,"main.js");function b(){u&&!u.killed&&(u.kill("SIGTERM"),u=null)}a(b,"A"),c(b,"H"),o(b,"cleanup");function S(){f=!0,b()}a(S,"N"),c(S,"O"),o(S,"stop");const ne=["SIGINT","SIGTERM","SIGHUP","SIGQUIT"].map(r=>{const n=o(()=>S(),"handler");return process.on(r,n),{sig:r,handler:n}});process.on("exit",S);function g(){if(f)return;if(!fs.existsSync(M)){console.error(`[serve] devserver script not found at ${M}`);return}const r=["--enable-source-maps"];z&&r.unshift("--require","@swc-node/register");const n=(0,node_child_process_1.fork)(M,{cwd:i,env:{...process.env,PORT:String(p),SERVICE_NAME:l,SERVE_PREFIX:D,LENSMCP_PROJECT:process.env.LENSMCP_PROJECT||t.projectName||l,LENSMCP_EVENT_FILE:process.env.LENSMCP_EVENT_FILE||path.join(i,".lensmcp","events.jsonl"),CHILD_COUNT:String(e.childCount||process.env.CHILD_COUNT||1),BUNDLE_PATH:te,...x&&{GATEWAY_MIDDLEWARE:x},...I&&{GATEWAY_CONFIG:I},...e.gateway?.routes?.length&&{GATEWAY_ROUTES:JSON.stringify(e.gateway.routes)},...e.gateway?.https&&{GATEWAY_HTTPS:"1"},...e.gateway?.extraPorts?.length&&{GATEWAY_EXTRA_PORTS:JSON.stringify(e.gateway.extraPorts)},...e.internalPort&&{INTERNAL_PORT:String(e.internalPort)},...m&&{LENSMCP_DEBUG_PORT:String(m)},...v&&{LENSMCP_LOG_FILE:v},...e.workers?.length&&{WORKERS:(0,worker_supervisor_1.serializeWorkerSpecs)(e.workers)},[dev_devtool_1.DEV_SOURCE_MAPS_ENV]:G?"1":"0"},stdio:["inherit","inherit","inherit","ipc"],execArgv:r,execPath:(0,process_name_1.namedExecPath)((0,process_name_1.processName)(process.env.LENSMCP_WS_KEY||path.basename(i),l,"dev"))});u=n,n.on("exit",(d,E)=>{u===n&&(u=null),!(E||d===0||f)&&(console.error(`[serve] devserver exited unexpectedly (code=${d}, signal=${E}) \u2014 respawning in 1.5s`),setTimeout(()=>{!f&&!u&&A&&g()},1500).unref?.())}),console.log(`[serve] Devserver started on port ${p} (service: ${l}${D?`, prefix: /${D}`:""})`),m?(console.warn(`[serve] DEBUGGER ENABLED for ${l}. Node's inspector has NO authentication \u2014 the ws:// UUID is the whole credential, and any account on this host that obtains it runs code as you. Do not enable this on a shared machine.`),Q?console.warn(`[serve] LENSMCP_DEBUG_FIXED_PORTS=1 \u2014 pod inspectors bind PREDICTABLE ports 127.0.0.1:${m}+slot (workers ${m}+20+i), reachable by any account on this host. Attach WebStorm (Attach to Node.js/Chrome) to ${m}. Unset it to bind ephemeral ports instead.`):console.log(`[serve] Debug: pod inspectors bind an EPHEMERAL 127.0.0.1 port. Get the ws:// URLs with \`lensmcp debug ${l}\` (the owner-only control socket); a devserver run in your own terminal also prints them there. Set LENSMCP_DEBUG_FIXED_PORTS=1 if your IDE needs a fixed attach port.`)):console.log(`[serve] Debug on demand: \`lensmcp debug ${l}\` opens pod inspectors without a restart`),v&&console.log(`[serve] Logs teed to ${v} \u2014 tail it in WebStorm via Run/Debug configuration \u2192 Logs tab`)}a(g,"E"),c(g,"_"),o(g,"startDevServer");function K(){if(!u||u.killed){console.log("[serve] Devserver not running, restarting..."),g();return}fetch(`http://localhost:${p}/webpack/reload`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"}).then(()=>console.log("[serve] Notified devserver to reload")).catch(r=>{console.warn("[serve] Failed to notify devserver, restarting...",r.message),b(),g()})}a(K,"te"),c(K,"ne"),o(K,"_notifyDevServerReload");let P=null;const F=[];function h(r){if(P){const n=P;P=null,n(r)}else F.push(r)}a(h,"v"),c(h,"h"),o(h,"pushResult");function U(){return F.length>0?Promise.resolve(F.shift()):new Promise(r=>{P=r})}a(U,"J"),c(U,"ee"),o(U,"waitForNext");let j=o(()=>{},"closeBuild");function R(){return!A||!u?(A=!0,g(),!0):!1}a(R,"F"),c(R,"J"),o(R,"builtOk");function N(){if(f)return;const{createDevWebpackConfig:r}=require("../../create-webpack-dev"),n=require("webpack"),d=r(J),{watch:E,...L}=d,s=n(L);G=(0,dev_devtool_1.bundleCarriesSourceMaps)(s.options.devtool);const O=o(($,C)=>{if($){console.error("[serve] Webpack error:",$),h({success:!1});return}const ae=C.hasErrors();if(console.info(C.toString({colors:!0,chunks:!1,assets:!0})),ae){h({success:!1});return}R(),h({success:!0,baseUrl:`http://localhost:${p}`})},"onBuild");if(frozen()){console.log(`[serve] ${t.projectName}: frozen \u2014 compiling once, no file watcher`),s.run(($,C)=>{O($,C),s.close(()=>{})});return}const q=s.watch(d.watchOptions||{},O);j=o(()=>q.close(()=>{}),"closeBuild")}a(N,"b"),c(N,"A"),o(N,"compileOnItsOwn");function B(r){const n=r.accepted.projects.filter(s=>s!==t.projectName);console.log(`[serve] ${t.projectName}: compiled by the workspace's shared compilation ${r.accepted.group.slice(0,8)}${n.length?` with ${n.join(", ")}`:""} \u2014 no webpack in this process`);const d=new devserver_notifier_1.DevserverNotifier(p,e.gateway?.https===!0,(0,devserver_notifier_1.devserverControlSock)(l)),E=(0,attach_1.createAttachedTypecheck)({appName:t.projectName,tsConfig:V,workspaceRoot:i,memoryLimit:e.memoryLimit||8192});let L;j=o(()=>{r.close(),E.dispose()},"closeBuild"),r.listen(s=>{if(!f)switch(s.type){case"watch-run":d.watchRun(s.paths);return;case"watch-closed":d.degrade("watch closed");return;case"failed":console.error(`[serve] the shared compiler failed: ${s.message}`),d.degrade(`compiler failed: ${s.message}`),h({success:!1});return;case"refused":console.log(`[serve] ${t.projectName}: compiling on its own from now on \u2014 ${s.reason}`),j(),N();return;case"built":{if(console.info(s.text),G=s.sourceMaps,E.built(s),!s.ok){d.failed(),h({success:!1});return}const O=s.hash!==L;L=s.hash;const q=R();d.built(O&&!q),h({success:!0,baseUrl:`http://localhost:${p}`});return}default:return}})}if(a(B,"X"),c(B,"re"),o(B,"attachToSharedBuild"),(0,attach_1.sharedBuildOffered)()&&!frozen()){const r=await(0,attach_1.joinSharedBuild)({project:t.projectName,target:t.targetName??"serve-hmr",...t.configurationName?{configuration:t.configurationName}:{},options:J,targetOptions:{...e},env:definedEnv(process.env)});r.kind==="attached"?B(r.session):(console.log(`[serve] ${t.projectName}: compiling on its own \u2014 ${r.reason}`),N())}else N();try{for(;;)yield await U()}finally{S(),j(),ne.forEach(({sig:r,handler:n})=>process.removeListener(r,n))}}a(serveExecutor,"serveExecutor"),c(serveExecutor,"serveExecutor"),o(serveExecutor,"serveExecutor"),exports.default=serveExecutor,module.exports=serveExecutor,module.exports.default=serveExecutor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var o=Object.defineProperty;var i=(e,t)=>o(e,"name",{value:t,configurable:!0});var s=Object.defineProperty,a=i((e,t)=>s(e,"name",{value:t,configurable:!0}),"a"),n=Object.defineProperty,r=a((e,t)=>n(e,"name",{value:t,configurable:!0}),"r");Object.defineProperty(exports,"__esModule",{value:!0}),exports.isValidHostname=isValidHostname;const LABEL=/^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$/,MAX_HOSTNAME_LENGTH=253;function isValidHostname(e){return typeof e!="string"||e.length===0||e.length>MAX_HOSTNAME_LENGTH?!1:e.split(".").every(t=>LABEL.test(t))}i(isValidHostname,"isValidHostname"),a(isValidHostname,"isValidHostname"),r(isValidHostname,"isValidHostname");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`).some(
|
|
1
|
+
"use strict";var b=Object.defineProperty;var p=(s,t)=>b(s,"name",{value:t,configurable:!0});var v=Object.defineProperty,h=p((s,t)=>v(s,"name",{value:t,configurable:!0}),"h"),m=Object.defineProperty,d=h((s,t)=>m(s,"name",{value:t,configurable:!0}),"d");Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=trustExecutor,exports.collectHosts=collectHosts;const tslib_1=require("tslib"),node_child_process_1=require("node:child_process"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path")),basic_ssl_1=require("../../basic-ssl"),checkout_cache_1=require("../../checkout-cache"),hostname_1=require("./hostname");async function trustExecutor(s,t){const r=(0,checkout_cache_1.checkoutCacheDir)(t.root,"davnx-webpack"),c=(0,basic_ssl_1.ensureCaSync)(r),a=process.env.LENSMCP_TRUST_HOSTS_ONLY==="1",u=collectHosts(s,t);if(u.length===0&&console.log("[trust] no concrete hostnames found (only wildcards?) \u2014 keychain step only."),process.platform!=="darwin"){console.log("[trust] non-macOS platform \u2014 do these manually:"),console.log(` \u2022 trust ${c} in your OS/browser store (Linux: update-ca-certificates / certutil)`);for(const e of u)console.log(` \u2022 /etc/hosts: "127.0.0.1 ${e}" and "::1 ${e}"`);return{success:!0}}const o=caSha256Fingerprint(c),f=a||o!==void 0&&(0,node_child_process_1.spawnSync)("security",["find-certificate","-a","-c","lensmcp local dev CA","-Z","/Library/Keychains/System.keychain"],{encoding:"utf8"}).stdout?.includes(o)===!0;if(a)console.log("[trust] hosts-only: a shared daemon serves TLS with its own CA \u2014 skipping the keychain step.");else if(f)console.log("[trust] CA already in the System keychain \u2014 skipping.");else{if(console.log(`[trust] adding CA to the System keychain (sudo will prompt): ${c}`),(0,node_child_process_1.spawnSync)("sudo",["security","add-trusted-cert","-d","-r","trustRoot","-k","/Library/Keychains/System.keychain",c],{stdio:"inherit"}).status!==0)return console.error("[trust] add-trusted-cert failed \u2014 rerun in a terminal so sudo can prompt."),{success:!1};console.log("[trust] CA trusted. Restart your browser once (it caches certificate verdicts).")}const i=fs.readFileSync("/etc/hosts","utf8"),n=d((e,S)=>i.split(`
|
|
2
|
+
`).some(w=>{const y=w.trim();if(y.startsWith("#"))return!1;const g=y.split(/\s+/);return g[0]===e&&g.slice(1).includes(S)}),"hasEntry"),l=[];for(const e of u)n("127.0.0.1",e)||l.push(`127.0.0.1 ${e}`),n("::1",e)||l.push(`::1 ${e}`);if(l.length===0)console.log("[trust] /etc/hosts already complete (both families for every hostname).");else{if(console.log(`[trust] appending to /etc/hosts (sudo):
|
|
3
3
|
${l.join(`
|
|
4
4
|
`)}`),(0,node_child_process_1.spawnSync)("sudo",["tee","-a","/etc/hosts"],{input:l.join(`
|
|
5
5
|
`)+`
|
|
6
|
-
`,stdio:["pipe","ignore","inherit"]}).status!==0)return console.error("[trust] /etc/hosts update failed."),{success:!1};(0,node_child_process_1.spawnSync)("sudo",["dscacheutil","-flushcache"],{stdio:"inherit"}),(0,node_child_process_1.spawnSync)("sudo",["killall","-HUP","mDNSResponder"],{stdio:"inherit"})}if(!a){const e=(0,node_child_process_1.spawnSync)("security",["verify-cert","-c",c,"-p","basic"],{stdio:"ignore"});console.log(`[trust] CA trust check: ${e.status===0?"OK":"NOT TRUSTED YET (browser restart may be needed)"}`)}for(const e of u)console.log(`[trust] ${e} \u2192 https ready (hosts + cert SAN ride the gateway config)`);return{success:!0}}h(trustExecutor,"trustExecutor"),d(trustExecutor,"trustExecutor");function caSha256Fingerprint(
|
|
6
|
+
`,stdio:["pipe","ignore","inherit"]}).status!==0)return console.error("[trust] /etc/hosts update failed."),{success:!1};(0,node_child_process_1.spawnSync)("sudo",["dscacheutil","-flushcache"],{stdio:"inherit"}),(0,node_child_process_1.spawnSync)("sudo",["killall","-HUP","mDNSResponder"],{stdio:"inherit"})}if(!a){const e=(0,node_child_process_1.spawnSync)("security",["verify-cert","-c",c,"-p","basic"],{stdio:"ignore"});console.log(`[trust] CA trust check: ${e.status===0?"OK":"NOT TRUSTED YET (browser restart may be needed)"}`)}for(const e of u)console.log(`[trust] ${e} \u2192 https ready (hosts + cert SAN ride the gateway config)`);return{success:!0}}p(trustExecutor,"trustExecutor"),h(trustExecutor,"trustExecutor"),d(trustExecutor,"trustExecutor");function caSha256Fingerprint(s){const t=(0,node_child_process_1.spawnSync)("openssl",["x509","-in",s,"-noout","-fingerprint","-sha256"],{encoding:"utf8"});if(t.status!==0||!t.stdout)return;const r=t.stdout.split("=")[1]?.replaceAll(":","").trim().toUpperCase();return r&&/^[0-9A-F]{64}$/.test(r)?r:void 0}p(caSha256Fingerprint,"caSha256Fingerprint"),h(caSha256Fingerprint,"caSha256Fingerprint"),d(caSha256Fingerprint,"caSha256Fingerprint");function collectHosts(s,t){const r=[],c=t.projectName?t.projectsConfigurations?.projects[t.projectName]:void 0,a=s.serveTarget??"serve-hmr",u=c?.targets?.[a]?.options?.gateway?.routes??[];for(const o of u)o.host&&(0,hostname_1.isValidHostname)(o.host)?r.push(o.host):o.host&&console.warn(`[trust] ignoring invalid hostname in ${a} routes: ${JSON.stringify(o.host)}`);for(const o of Object.values(t.projectsConfigurations?.projects??{}))try{const f=JSON.parse(fs.readFileSync(path.join(t.root,o.root,"project.json"),"utf8")),i=f.cluster??f.davnx,n=i?.host;n&&!(0,hostname_1.isValidHostname)(n)&&console.warn(`[trust] ignoring invalid hostname in ${o.root}/project.json: ${JSON.stringify(n)}`),n&&(0,hostname_1.isValidHostname)(n)&&(r.push(n),i?.service&&i.internalHost!==!1&&r.push(typeof i.internalHost=="string"?i.internalHost:`internal.${n}`))}catch{}return[...new Set([...r,"lensmcp.local",...s.hosts??[]])]}p(collectHosts,"collectHosts"),h(collectHosts,"collectHosts"),d(collectHosts,"collectHosts");
|