mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-08-05 23:41:31 +08:00
17 lines
19 KiB
JavaScript
Generated
17 lines
19 KiB
JavaScript
Generated
"use strict";var Pe=Object.create;var q=Object.defineProperty;var Le=Object.getOwnPropertyDescriptor;var Te=Object.getOwnPropertyNames;var De=Object.getPrototypeOf,Ae=Object.prototype.hasOwnProperty;var Re=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Te(e))!Ae.call(t,i)&&i!==n&&q(t,i,{get:()=>e[i],enumerable:!(r=Le(e,i))||r.enumerable});return t};var l=(t,e,n)=>(n=t!=null?Pe(De(t)):{},Re(e||!t||!t.__esModule?q(n,"default",{value:t,enumerable:!0}):n,t));var xe=require("node:child_process"),m=l(require("node:fs")),y=l(require("node:path"));function U(t){switch((t??"").trim().toLowerCase()){case"off":return"off";case"block":return"block";case"":case"warn":return"warn";default:return"warn"}}function I(t){return t?.tool_input?.command??""}function B(t){let e=[],n=/(?:--source-dir|--source-path|-d|-p)(?:[=\s]+)("[^"]+"|'[^']+'|\S+)/g,r;for(;(r=n.exec(t))!==null;)e.push(Ee(r[1]));return e}function Ee(t){return t.length>=2&&(t[0]==='"'||t[0]==="'")&&t[t.length-1]===t[0]?t.slice(1,-1):t}function $(t){return t.endsWith(".cls")||t.endsWith(".trigger")}function G(t,e){if(t==="off")return{allow:!0,message:""};let n=e.filter(o=>o.errors.length>0),r=n.reduce((o,a)=>o+a.errors.length,0);if(r===0)return{allow:!0,message:""};let i=_e(n);return t==="warn"?{allow:!0,message:`\u26A0\uFE0F Apex pre-deploy check found ${r} error${r===1?"":"s"} in ${n.length} file${n.length===1?"":"s"} (advisory \u2014 deploy continuing).
|
|
`+i+`
|
|
Set SFDX_LSP_DEPLOY_GATE=block to make this gate blocking, or =off to silence it.`}:{allow:!1,message:`BLOCKED: Apex pre-deploy check found ${r} error${r===1?"":"s"} in ${n.length} file${n.length===1?"":"s"}.
|
|
`+i+`
|
|
Fix the errors above, or set SFDX_LSP_DEPLOY_GATE=warn (advisory) / =off to override this gate.`}}function _e(t){let e=[];for(let n of t){e.push(` ${n.filePath}`);for(let r of n.errors){let i=r.code!==void 0?` [${r.code}]`:"";e.push(` ${r.line}:${r.column}${i} ${r.message}`)}}return e.join(`
|
|
`)}var ne=l(require("node:fs")),b=l(require("node:path")),re=require("node:url");function Me(t){switch(t){case 1:return"error";case 2:return"warning";case 3:return"info";case 4:return"hint";default:return"error"}}function j(t){return t.map(e=>({severity:Me(e.severity),line:e.range.start.line+1,column:e.range.start.character+1,code:e.code,message:e.message,source:e.source}))}var Ce={error:"\u{1F534}",warning:"\u{1F7E1}",info:"\u{1F535}",hint:"\u{1F4A1}"};function $e(t,e,n){if(n.length===0)return e;let r=j(n),i=r.reduce((s,u)=>(s[u.severity]++,s),{error:0,warning:0,info:0,hint:0}),o=["error","warning","info","hint"].filter(s=>i[s]>0).map(s=>`${i[s]} ${s}${i[s]===1?"":"s"}`).join(", "),a=[t,"",`${o}`,"","| | Location | Code | Message |","|---|---|---|---|"];for(let s of r){let u=s.code!==void 0?`\`${s.code}\``:"",g=s.message.replace(/\|/g,"\\|").replace(/\n/g," ");a.push(`| ${Ce[s.severity]} | ${s.line}:${s.column} | ${u} | ${g} |`)}return a.join(`
|
|
`)}function H(t,e){return $e(`### Apex diagnostics for \`${t}\``,`\u2705 No Apex diagnostics for \`${t}\`.`,e)}var L=class{failures=0;openedAt=0;threshold;cooldownMs;now;constructor(e={}){this.threshold=e.threshold??3,this.cooldownMs=e.cooldownMs??3e4,this.now=e.now??Date.now}state(){return this.failures<this.threshold?"closed":this.now()-this.openedAt>=this.cooldownMs?"half-open":"open"}canAttempt(){return this.state()!=="open"}recordSuccess(){this.failures=0,this.openedAt=0}recordFailure(){this.failures++,this.failures>=this.threshold&&(this.openedAt=this.now())}};var J=process.env.SFDX_LSP_DEBUG==="1";function T(t,e){let n=e.map(r=>typeof r=="string"?r:je(r));process.stderr.write(`[sf-lsp-host] ${t} ${n.join(" ")}
|
|
`)}function je(t){try{return JSON.stringify(t)}catch{return String(t)}}var c={info(...t){T("info",t)},warn(...t){T("warn",t)},error(...t){T("error",t)},debug(...t){J&&T("debug",t)},get debugEnabled(){return J}};function K(t){switch((t??"").trim().toLowerCase()){case"":case"all":return"all";case"apex-only":return"apex-only";case"disabled":return"disabled";default:return c.warn(`unknown SFDX_LSP value '${t}', defaulting to 'all'`),"all"}}function z(t,e){return t==="disabled"?!1:t==="apex-only"?e==="apex":!0}var Ne=t=>{process.stderr.write(t+`
|
|
`)},N=class{enabled;sink;now;constructor(e={}){this.enabled=e.enabled??process.env.SFDX_LSP_DEBUG==="1",this.sink=e.sink??Ne,this.now=e.now??Date.now}clock(){return this.now()}emit(e){this.enabled&&this.sink(JSON.stringify({telemetry:!0,ts:this.now(),...e}))}async time(e,n){if(!this.enabled)return n();let r=this.now();try{let i=await n();return this.emit({event:"request",tool:e,ms:this.now()-r,outcome:"ok"}),i}catch(i){throw this.emit({event:"request",tool:e,ms:this.now()-r,outcome:"error",error:i instanceof Error?i.message:String(i)}),i}}},X=new N({enabled:!1});var Fe=5e3,p=class extends Error{constructor(n){super(n);this.code=n;this.name="LspUnavailableError"}code},D=class{constructor(e,n){this.specs=e;this.options=n;this.spawnTimeoutMs=n.spawnTimeoutMs??Fe,this.now=n.now??Date.now,this.telemetry=n.telemetry??X;for(let r of e)this.entries.set(r.language,{spec:r,status:"idle",lastUsedAt:0}),this.breakers.set(r.language,new L({now:this.now}))}specs;options;entries=new Map;breakers=new Map;spawnTimeoutMs;now;telemetry;snapshot(){return[...this.entries.values()].map(e=>({language:e.spec.language,status:e.status,lastError:e.lastError,lastSpawnMs:e.lastSpawnMs,breaker:this.breakers.get(e.spec.language).state()}))}async getReadyClient(e,n){let r=this.entries.get(e);if(!r)throw new p("unknown_language");if(!z(this.options.killSwitch,e))throw new p("lsp_disabled");if(r.status==="ready"&&r.client&&!r.client.hasExited)return this.telemetry.emit({event:"client_cache",language:e,result:"hit"}),this.touch(r),r.client;if(r.status==="spawning"&&r.initPromise)return r.initPromise;let i=this.breakers.get(e);if(!i.canAttempt())throw new p("circuit_open");this.telemetry.emit({event:"client_cache",language:e,result:"miss"}),r.status="spawning";let o=this.bringUp(r,i,n);return r.initPromise=o,o}async bringUp(e,n,r){let i=await e.spec.gate(r);if(!i.ok)throw e.status="idle",e.initPromise=void 0,new p(i.error??"gate_failed");let o=e.spec.language,a=this.now();try{let s=await this.spawnWithTimeout(e,r);return e.client=s,e.status="ready",e.initPromise=void 0,e.lastError=void 0,e.lastSpawnMs=this.now()-a,this.recordBreaker(n,o,()=>n.recordSuccess()),this.telemetry.emit({event:"spawn",language:o,ms:e.lastSpawnMs,outcome:"ok"}),this.touch(e),c.debug(`${o} LSP ready`,{coldMs:e.lastSpawnMs}),s}catch(s){throw e.status="failed",e.initPromise=void 0,e.client=void 0,e.lastError=s instanceof Error?s.message:String(s),this.recordBreaker(n,o,()=>n.recordFailure()),this.telemetry.emit({event:"spawn",language:o,ms:this.now()-a,outcome:"error",error:e.lastError}),s instanceof p?s:new p("spawn_timeout")}}recordBreaker(e,n,r){let i=e.state();r();let o=e.state();i!==o&&this.telemetry.emit({event:"circuit",language:n,from:i,to:o})}spawnWithTimeout(e,n){let r=e.spec.createClient(n),i=new Promise((o,a)=>{let s=setTimeout(()=>a(new p("spawn_timeout")),this.spawnTimeoutMs);typeof s.unref=="function"&&s.unref()});return Promise.race([r,i])}touch(e){e.lastUsedAt=this.now(),this.armIdleTimer(e)}armIdleTimer(e){e.idleTimer&&clearTimeout(e.idleTimer);let n=setTimeout(()=>this.reap(e),e.spec.idleMs);typeof n.unref=="function"&&n.unref(),e.idleTimer=n}reap(e){if(e.status==="ready"){c.debug(`reaping idle ${e.spec.language} LSP`);try{e.client?.dispose()}catch(n){c.debug("LSP client dispose failed",{err:n.message})}e.client=void 0,e.status="idle",e.idleTimer&&clearTimeout(e.idleTimer),e.idleTimer=void 0}}shutdownAll(){for(let e of this.entries.values())this.reap(e)}};var f=class extends Error{constructor(e){super(e),this.name="ValidationError"}};function A(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function V(t){if(!A(t))throw new f("arguments must be an object");let e=t.filePath;if(typeof e!="string"||e.length===0)throw new f("filePath is required and must be a non-empty string");return{filePath:e}}function Y(t){if(!A(t)||typeof t.line!="number"||typeof t.character!="number")throw new f("invalid LSP Position");return{line:t.line,character:t.character}}function Oe(t){if(!A(t))throw new f("invalid LSP Range");return{start:Y(t.start),end:Y(t.end)}}function We(t){if(!A(t))throw new f("diagnostic must be an object");if(typeof t.message!="string")throw new f("diagnostic.message must be a string");let e=typeof t.severity=="number"?t.severity:void 0,n=typeof t.code=="string"||typeof t.code=="number"?t.code:void 0,r=typeof t.source=="string"?t.source:void 0;return{range:Oe(t.range),message:t.message,severity:e,code:n,source:r}}function Q(t){if(!Array.isArray(t))throw new f("diagnostics must be an array");let e=[];for(let n of t)try{e.push(We(n))}catch{}return e}var ie="apex",qe=5e3,Z=20,ee=250,Ue=6;function oe(t){return{name:"apex.diagnostics",description:"Run semantic Apex diagnostics on a .cls file via the Apex language server. Returns errors/warnings (unknown SObject fields, type errors, missing symbols) before a deploy round-trip. Spawns the Apex LSP lazily on first use; returns a structured { error } envelope (no_apex_workspace | lsp_disabled | spawn_timeout | circuit_open) when unavailable so callers can fall back gracefully.",inputSchema:{type:"object",properties:{filePath:{type:"string",description:"Absolute or workspace-relative path to the .cls file to analyze."}},required:["filePath"],additionalProperties:!1},handler:async e=>{let{filePath:n}=V(e),r=t.resolveWorkspace(),i=b.isAbsolute(n)?n:b.resolve(r.root,n),o;try{o=ne.readFileSync(i,"utf8")}catch{return{error:"file_not_found",filePath:i}}let a;try{a=await t.lifecycle.getReadyClient(ie,r)}catch(x){if(x instanceof p)return{error:x.code,filePath:i};throw x}let s=(0,re.pathToFileURL)(i).toString(),u=await Ie(a,s,o),g=Q(u);return{ok:!0,filePath:i,diagnostics:j(g),markdown:H(b.basename(i),g)}}}}async function Ie(t,e,n){t.notify("textDocument/didOpen",{textDocument:{uri:e,languageId:ie,version:1,text:n}});try{let r=0;for(let i=0;i<Z;i++){let o;try{o=(await Be(t.request("textDocument/diagnostic",{textDocument:{uri:e}}),qe))?.items}catch(s){if((s instanceof Error?s.message:String(s)).includes("Unhandled method")&&i<Z-1){await te(ee);continue}throw s}let a=Array.isArray(o)?o:[];if(a.length>0)return a;if(++r>=Ue)return[];await te(ee)}return[]}catch(r){return c.debug("diagnostic pull failed; treating as clean",{uri:e,error:r instanceof Error?r.message:String(r)}),[]}finally{try{t.notify("textDocument/didClose",{textDocument:{uri:e}})}catch{}}}function te(t){return new Promise(e=>{let n=setTimeout(e,t);typeof n.unref=="function"&&n.unref()})}function Be(t,e){return new Promise((n,r)=>{let i=setTimeout(()=>r(new Error("diagnostic_pull_timeout")),e);typeof i.unref=="function"&&i.unref(),t.then(o=>{clearTimeout(i),n(o)},o=>{clearTimeout(i),r(o)})})}var fe=l(require("node:path")),de=require("node:url");var F=`\r
|
|
\r
|
|
`,Ge=/Content-Length:\s*(\d+)/i,R=class{buffer=Buffer.alloc(0);push(e){this.buffer=Buffer.concat([this.buffer,e]);let n=[];for(;;){let r=this.buffer.indexOf(F);if(r===-1)break;let i=this.buffer.toString("utf8",0,r),o=Ge.exec(i);if(!o){this.buffer=this.buffer.subarray(r+F.length);continue}let a=Number(o[1]),s=r+F.length,u=s+a;if(this.buffer.length<u)break;let g=this.buffer.toString("utf8",s,u);this.buffer=this.buffer.subarray(u);try{n.push(JSON.parse(g))}catch{}}return n}};function se(t){let e=JSON.stringify(t),n=Buffer.from(e,"utf8"),r=Buffer.from(`Content-Length: ${n.length}\r
|
|
\r
|
|
`,"ascii");return Buffer.concat([r,n])}var E=class{constructor(e){this.transport=e}transport;nextId=1;pending=new Map;notificationHandlers=new Map;serverRequestHandlers=new Map;request(e,n){let r=this.nextId++,i={jsonrpc:"2.0",id:r,method:e,params:n};return new Promise((o,a)=>{this.pending.set(r,{resolve:o,reject:a}),this.transport.send(i)})}notify(e,n){let r={jsonrpc:"2.0",method:e,params:n};this.transport.send(r)}onNotification(e,n){let r=this.notificationHandlers.get(e)??[];return r.push(n),this.notificationHandlers.set(e,r),()=>{let i=this.notificationHandlers.get(e);if(!i)return;let o=i.indexOf(n);o>=0&&i.splice(o,1)}}onServerRequest(e,n){this.serverRequestHandlers.set(e,n)}handleMessage(e){let n=e;if(n.id!==void 0&&n.method===void 0){let r=this.pending.get(n.id);if(!r)return;this.pending.delete(n.id),n.error?r.reject(new Error(`LSP error ${n.error.code}: ${n.error.message}`)):r.resolve(n.result);return}if(n.id!==void 0&&n.method!==void 0){let r=this.serverRequestHandlers.get(n.method),i=r?r(n.params):null,o={jsonrpc:"2.0",id:n.id,result:i};this.transport.send(o);return}if(n.method!==void 0){let r=this.notificationHandlers.get(n.method);if(r)for(let i of r.slice())i(n.params)}}rejectAll(e){for(let[,n]of this.pending)n.reject(new Error(e));this.pending.clear()}};var _=class{constructor(e){this.child=e;let n={send:r=>{if(!this.exited)try{this.child.stdin.write(se(r))}catch(i){c.debug("LSP child stdin write failed",{err:i.message})}}};this.rpc=new E(n),this.child.stdin.on("error",r=>{c.debug("LSP child stdin error",{err:r.message})}),this.child.stdout.on("data",r=>{for(let i of this.decoder.push(r))this.rpc.handleMessage(i)}),this.rpc.onServerRequest("client/registerCapability",()=>null),this.rpc.onServerRequest("client/unregisterCapability",()=>null),this.rpc.onServerRequest("workspace/configuration",r=>(r?.items??[]).map(()=>null)),this.rpc.onServerRequest("window/workDoneProgress/create",()=>null),this.child.on("exit",r=>{this.exited=!0,this.rpc.rejectAll(`LSP child exited (code ${r})`),c.debug("LSP child exited",{code:r})})}child;decoder=new R;rpc;exited=!1;request(e,n){return this.rpc.request(e,n)}notify(e,n){this.rpc.notify(e,n)}onNotification(e,n){return this.rpc.onNotification(e,n)}onServerRequest(e,n){this.rpc.onServerRequest(e,n)}get hasExited(){return this.exited}dispose(){if(!this.exited){try{this.rpc.notify("shutdown"),this.rpc.notify("exit")}catch{}try{this.child.kill()}catch{}}}};var ae=require("node:child_process");function ce(t){let e=(0,ae.spawn)(t.command,t.args,{cwd:t.cwd,stdio:["pipe","pipe","pipe"]});return e.stderr.on("data",n=>{c.debugEnabled&&process.stderr.write(`[lsp:${t.label}] ${n.toString("utf8")}`)}),e.on("error",n=>{c.error(`failed to spawn LSP child '${t.label}'`,n.message)}),e}var ue=l(require("node:fs")),w=l(require("node:path"));function He(t){return ue.existsSync(w.join(t,".claude-plugin","plugin.json"))}function Je(t){for(let e=t;;){if(He(e))return e;let n=w.dirname(e);if(n===e)break;e=n}return w.resolve(t,"..")}function Ke(){let t=process.env.CLAUDE_PLUGIN_ROOT;return t&&t.length>0?t:Je(__dirname)}function le(){return w.join(Ke(),"vendor","apex-ls","dist","server.node.js")}function pe(t){return(0,de.pathToFileURL)(t).toString()}function ze(t){return{processId:process.pid,rootUri:pe(t.root),workspaceFolders:t.packageDirs.map(e=>({uri:pe(e),name:fe.basename(e)})),capabilities:{textDocument:{diagnostic:{dynamicRegistration:!1,relatedDocumentSupport:!1},publishDiagnostics:{relatedInformation:!0},synchronization:{didSave:!0,dynamicRegistration:!1}},workspace:{workspaceFolders:!0,configuration:!0,diagnostics:{refreshSupport:!0}}},initializationOptions:{apex:{environment:{serverMode:"development"},detailLevel:"public-api"}}}}async function me(t){let e=le(),n=ce({command:"node",args:[e,"--stdio"],cwd:t.root,label:"apex"}),r=new _(n);return await r.request("initialize",ze(t)),r.notify("initialized",{}),c.debug("apex-ls initialized",{root:t.root}),r}var ge=l(require("node:fs")),M=l(require("node:path")),Xe=new Set(["node_modules",".git",".sfdx",".sf","dist","out","coverage"]);function he(t,e=0){if(e>12)return!1;let n;try{n=ge.readdirSync(t,{withFileTypes:!0})}catch{return!1}let r=M.basename(t)==="classes";for(let i of n)if(i.isFile()&&r&&i.name.endsWith(".cls"))return!0;for(let i of n)if(i.isDirectory()&&!Xe.has(i.name)&&he(M.join(t,i.name),e+1))return!0;return!1}function Ye(t){return t.packageDirs.some(e=>he(e))}function we(t){return Ye(t)?{ok:!0}:{ok:!1,error:"no_apex_workspace"}}var Ve=900*1e3,ye={language:"apex",idleMs:Ve,gate:we,createClient:me};var be=require("node:child_process"),C=l(require("node:fs")),d=l(require("node:path"));function Qe(t){let e=d.resolve(t);for(let n=0;n<64;n++){if(C.existsSync(d.join(e,"sfdx-project.json")))return e;let r=d.dirname(e);if(r===e)break;e=r}}function Ze(t){try{let n=(0,be.execFileSync)("git",["rev-parse","--show-toplevel"],{cwd:t,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();return n.length>0?n:void 0}catch{return}}function et(t){try{let e=C.readFileSync(d.join(t,"sfdx-project.json"),"utf8"),r=(JSON.parse(e).packageDirectories??[]).map(i=>i?.path).filter(i=>typeof i=="string"&&i.length>0).map(i=>d.resolve(t,i));return r.length>0?tt(r):[t]}catch{return[t]}}function tt(t){return Array.from(new Set(t))}function ke(t=process.cwd()){let e=Qe(t);if(e)return{root:e,packageDirs:et(e),source:"sfdx-project"};let n=Ze(t);if(n)return{root:n,packageDirs:[n],source:"git-root"};let r=d.resolve(t);return{root:r,packageDirs:[r],source:"cwd"}}var nt=2e4,O=25;function rt(){try{return m.readFileSync(0,"utf8")}catch{return""}}function k(t){t&&process.stderr.write(t+`
|
|
`),process.stdout.write(JSON.stringify({continue:!0})),process.exit(0)}function it(t){process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:t}})),process.exit(0)}function ot(t,e){let n=B(t),r=n.length>0?st(n,e):at(e),i=ct(r.filter($).filter(o=>m.existsSync(o)));return i.length>O?{files:i.slice(0,O),truncated:!0}:{files:i,truncated:!1}}function st(t,e){let n=[];for(let r of t){let i=y.isAbsolute(r)?r:y.resolve(e.root,r),o;try{o=m.statSync(i)}catch{continue}o.isFile()?n.push(i):o.isDirectory()&&n.push(...Se(i))}return n}function Se(t,e=0){if(e>12)return[];let n=[],r;try{r=m.readdirSync(t,{withFileTypes:!0})}catch{return n}for(let i of r){if(i.name.startsWith(".")||i.name==="node_modules")continue;let o=y.join(t,i.name);i.isDirectory()?n.push(...Se(o,e+1)):$(i.name)&&n.push(o)}return n}function at(t){try{return(0,xe.execFileSync)("git",["status","--porcelain","--untracked-files=all"],{cwd:t.root,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).split(`
|
|
`).map(n=>n.slice(3).trim()).filter(n=>n.length>0).map(n=>y.resolve(t.root,n))}catch{return[]}}function ct(t){return Array.from(new Set(t))}function ut(t,e,n){return new Promise(r=>{let i=setTimeout(()=>r(n()),e);typeof i.unref=="function"&&i.unref(),t.then(o=>{clearTimeout(i),r(o)},()=>{clearTimeout(i),r(n())})})}async function lt(){let t=U(process.env.SFDX_LSP_DEPLOY_GATE);t==="off"&&k();let e=K(process.env.SFDX_LSP);e==="disabled"&&k();let n;try{n=JSON.parse(rt()||"{}")}catch{k()}let r=I(n),i;try{i=ke()}catch{k()}let{files:o,truncated:a}=ot(r,i);o.length===0&&k();let s=new D([ye],{killSwitch:e}),u=oe({lifecycle:s,resolveWorkspace:()=>i}),x=await ut((async()=>{let v=[];for(let P of o)try{let h=await u.handler({filePath:P});if("error"in h){v.push({filePath:P,errors:[],skippedReason:h.error});continue}v.push({filePath:P,errors:h.diagnostics.filter(ve=>ve.severity==="error")})}catch(h){v.push({filePath:P,errors:[],skippedReason:h instanceof Error?h.message:String(h)})}return v})(),nt,()=>[]);s.shutdownAll();let S=G(t,x),W=a?`
|
|
(Checked the first ${O} Apex files; more were changed but not analyzed.)`:"";S.allow||it(S.message+W),k(S.message?S.message+W:void 0)}lt().catch(()=>{process.stdout.write(JSON.stringify({continue:!0})),process.exit(0)});
|