Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@php-wasm/cli-util

Package Overview
Dependencies
Maintainers
7
Versions
52
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@php-wasm/cli-util - npm Package Compare versions

Comparing version
3.1.18
to
3.1.19
+14
-10
index.cjs

@@ -1,7 +0,9 @@

"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("fs"),P=require("path"),k=require("@php-wasm/util"),j=require("fast-xml-parser"),X=require("jsonc-parser");function B(o){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(o){for(const t in o)if(t!=="default"){const a=Object.getOwnPropertyDescriptor(o,t);Object.defineProperty(r,t,a.get?a:{enumerable:!0,get:()=>o[t]})}}return r.default=o,Object.freeze(r)}const v=B(X),M="PHPWASMCLI";async function R(o,r,t){const a=t==="win32"?"junction":"dir";p.symlinkSync(o,r,a)}async function q(o){try{p.lstatSync(o).isSymbolicLink()&&p.unlinkSync(o)}catch{}}function O(o,r){return r.filter(t=>{const a=P.resolve(t.hostPath),h=P.join(o,P.sep);return a===o||a.startsWith(h)})}const x={ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,cdataPropName:"__cdata",commentPropName:"__xmlComment",allowBooleanAttributes:!0,trimValues:!0},_={ignoreAttributes:x.ignoreAttributes,attributeNamePrefix:x.attributeNamePrefix,preserveOrder:x.preserveOrder,cdataPropName:x.cdataPropName,commentPropName:x.commentPropName,suppressBooleanAttributes:!x.allowBooleanAttributes,format:!0,indentBy:" "},C={allowEmptyContent:!0,allowTrailingComma:!0};function A(o,r){var b,I,D,F,L,T;const{name:t,host:a,port:h,mappings:f,ideKey:i}=r,u=new j.XMLParser(x),g=(()=>{try{return u.parse(o,!0)}catch{throw new Error("PhpStorm configuration file is not valid XML.")}})(),m={server:[{}],":@":{name:t,host:`${a}:${h}`,use_path_mappings:"true"}};f&&f.length&&(m.server[0].path_mappings=f.map(e=>({mapping:[],":@":{"local-root":`$PROJECT_DIR$/${k.toPosixPath(P.relative(r.projectDir,e.hostPath))}`,"remote-root":e.vfsPath}})));let n=g==null?void 0:g.find(e=>!!(e!=null&&e.project));if(n){const e=(b=n[":@"])==null?void 0:b.version;if(e===void 0)throw new Error('PhpStorm IDE integration only supports <project version="4"> in workspace.xml, but the <project> configuration has no version number.');if(e!=="4")throw new Error(`PhpStorm IDE integration only supports <project version="4"> in workspace.xml, but we found a <project> configuration with version "${e}".`)}n===void 0&&(n={project:[],":@":{version:"4"}},g.push(n));let s=(I=n.project)==null?void 0:I.find(e=>{var S;return!!(e!=null&&e.component)&&((S=e==null?void 0:e[":@"])==null?void 0:S.name)==="PhpServers"});s===void 0&&(s={component:[],":@":{name:"PhpServers"}},n.project===void 0&&(n.project=[]),n.project.push(s));let l=(D=s.component)==null?void 0:D.find(e=>!!(e!=null&&e.servers));l===void 0&&(l={servers:[]},s.component===void 0&&(s.component=[]),s.component.push(l));const y=(F=l.servers)==null?void 0:F.findIndex(e=>{var S;return!!(e!=null&&e.server)&&((S=e==null?void 0:e[":@"])==null?void 0:S.name)===t});(y===void 0||y<0)&&(l.servers===void 0&&(l.servers=[]),l.servers.push(m));let d=(L=n.project)==null?void 0:L.find(e=>{var S;return!!(e!=null&&e.component)&&((S=e==null?void 0:e[":@"])==null?void 0:S.name)==="RunManager"});if(d===void 0&&(d={component:[],":@":{name:"RunManager"}},n.project===void 0&&(n.project=[]),n.project.push(d)),(((T=d.component)==null?void 0:T.findIndex(e=>{var S;return!!(e!=null&&e.configuration)&&((S=e==null?void 0:e[":@"])==null?void 0:S.name)===t}))??-1)<0){const e={configuration:[{method:[],":@":{v:"2"}}],":@":{name:t,type:"PhpRemoteDebugRunConfigurationType",factoryName:"PHP Remote Debug",filter_connections:"FILTER",server_name:t,session_id:i}};d.component===void 0&&(d.component=[]),d.component.push(e)}const E=new j.XMLBuilder(_).build(g);try{u.parse(E,!0)}catch{throw new Error("The resulting PhpStorm configuration file is not valid XML.")}return E}function N(o,r){var m,n;const{name:t,mappings:a}=r,h=[];let f=o,i=v.parseTree(f,h,C);if(i===void 0||h.length)throw new Error("VS Code configuration file is not valid JSON.");let u=v.findNodeAtLocation(i,["configurations"]);if(u===void 0||u.children===void 0){const s=v.modify(f,["configurations"],[],{});f=v.applyEdits(f,s),i=v.parseTree(f,[],C),u=v.findNodeAtLocation(i,["configurations"])}const g=(m=u==null?void 0:u.children)==null?void 0:m.findIndex(s=>{var l;return((l=v.findNodeAtLocation(s,["name"]))==null?void 0:l.value)===t});if(g===void 0||g<0){const s={name:t,type:"php",request:"launch",port:9003};a&&a.length&&(s.pathMappings=a.reduce((d,c)=>(d[c.vfsPath]=`\${workspaceFolder}/${k.toPosixPath(P.relative(r.workspaceDir,c.hostPath))}`,d),{}));const l=((n=u==null?void 0:u.children)==null?void 0:n.length)||0,y=v.modify(f,["configurations",l],s,{formattingOptions:{insertSpaces:!0,tabSize:4,eol:`
`}});f=$(f,y)}return f}async function V({name:o,ides:r,host:t,port:a,cwd:h,mounts:f,ideKey:i=M}){const u=f?O(h,f):[],g={};if(r.includes("phpstorm")){const m=".idea/workspace.xml",n=P.join(h,m);if(!p.existsSync(n)){if(p.existsSync(P.dirname(n)))p.writeFileSync(n,`<?xml version="1.0" encoding="UTF-8"?>
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("fs"),w=require("path"),D=require("@php-wasm/util"),C=require("fast-xml-parser"),B=require("jsonc-parser");function H(c){const f=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(c){for(const r in c)if(r!=="default"){const d=Object.getOwnPropertyDescriptor(c,r);Object.defineProperty(f,r,d.get?d:{enumerable:!0,get:()=>c[r]})}}return f.default=c,Object.freeze(f)}const x=H(B),M="PHPWASMCLI",R=["/dev/","/home/","/internal/","/request/","/proc/"];async function q(c,f,r){const d=r==="win32"?"junction":"dir";p.symlinkSync(c,f,d)}async function V(c){try{p.lstatSync(c).isSymbolicLink()&&p.unlinkSync(c)}catch{}}function X(c,f){return f.filter(r=>{const d=w.resolve(r.hostPath),u=w.join(c,w.sep);return d===c||d.startsWith(u)})}const E={ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,cdataPropName:"__cdata",commentPropName:"__xmlComment",allowBooleanAttributes:!0,trimValues:!0},F={ignoreAttributes:E.ignoreAttributes,attributeNamePrefix:E.attributeNamePrefix,preserveOrder:E.preserveOrder,cdataPropName:E.cdataPropName,commentPropName:E.commentPropName,suppressBooleanAttributes:!E.allowBooleanAttributes,format:!0,indentBy:" "},I={allowEmptyContent:!0,allowTrailingComma:!0};function $(c,f){var S,b,k,L,T,_;const{name:r,host:d,port:u,pathMappings:h,ideKey:t}=f,P=new C.XMLParser(E),v=(()=>{try{return P.parse(c,!0)}catch{throw new Error("PhpStorm configuration file is not valid XML.")}})(),y={server:[{}],":@":{name:r,host:`${d}:${u}`,use_path_mappings:"true"}};h&&h.length&&(y.server[0].path_mappings=h.map(n=>({mapping:[],":@":{"local-root":`$PROJECT_DIR$/${D.toPosixPath(w.relative(f.projectDir,n.hostPath))}`,"remote-root":n.vfsPath}})));let l=v==null?void 0:v.find(n=>!!(n!=null&&n.project));if(l){const n=(S=l[":@"])==null?void 0:S.version;if(n===void 0)throw new Error('PhpStorm IDE integration only supports <project version="4"> in workspace.xml, but the <project> configuration has no version number.');if(n!=="4")throw new Error(`PhpStorm IDE integration only supports <project version="4"> in workspace.xml, but we found a <project> configuration with version "${n}".`)}l===void 0&&(l={project:[],":@":{version:"4"}},v.push(l));let o=(b=l.project)==null?void 0:b.find(n=>{var j;return!!(n!=null&&n.component)&&((j=n==null?void 0:n[":@"])==null?void 0:j.name)==="PhpServers"});o===void 0&&(o={component:[],":@":{name:"PhpServers"}},l.project===void 0&&(l.project=[]),l.project.push(o));let i=(k=o.component)==null?void 0:k.find(n=>!!(n!=null&&n.servers));i===void 0&&(i={servers:[]},o.component===void 0&&(o.component=[]),o.component.push(i));const s=(L=i.servers)==null?void 0:L.findIndex(n=>{var j;return!!(n!=null&&n.server)&&((j=n==null?void 0:n[":@"])==null?void 0:j.name)===r});(s===void 0||s<0)&&(i.servers===void 0&&(i.servers=[]),i.servers.push(y));let e=(T=l.project)==null?void 0:T.find(n=>{var j;return!!(n!=null&&n.component)&&((j=n==null?void 0:n[":@"])==null?void 0:j.name)==="RunManager"});if(e===void 0&&(e={component:[],":@":{name:"RunManager"}},l.project===void 0&&(l.project=[]),l.project.push(e)),(((_=e.component)==null?void 0:_.findIndex(n=>{var j;return!!(n!=null&&n.configuration)&&((j=n==null?void 0:n[":@"])==null?void 0:j.name)===r}))??-1)<0){const n={configuration:[{method:[],":@":{v:"2"}}],":@":{name:r,type:"PhpRemoteDebugRunConfigurationType",factoryName:"PHP Remote Debug",filter_connections:"FILTER",server_name:r,session_id:t}};e.component===void 0&&(e.component=[]),e.component.push(n)}const m=new C.XMLBuilder(F).build(v);try{P.parse(m,!0)}catch{throw new Error("The resulting PhpStorm configuration file is not valid XML.")}return m}function A(c,f){var l,o,i,s;const{pathSkippings:r}=f,d=new C.XMLParser(E),u=(()=>{try{return d.parse(c,!0)}catch{throw new Error("PhpStorm PHP configuration file is not valid XML.")}})();let h=u==null?void 0:u.find(e=>!!(e!=null&&e.project));if(h){const e=(l=h[":@"])==null?void 0:l.version;if(e===void 0)throw new Error('PhpStorm IDE integration only supports <project version="4"> in php.xml, but the <project> configuration has no version number.');if(e!=="4")throw new Error(`PhpStorm IDE integration only supports <project version="4"> in php.xml, but we found a <project> configuration with version "${e}".`)}h===void 0&&(h={project:[],":@":{version:"4"}},u.push(h));let t=(o=h.project)==null?void 0:o.find(e=>{var a;return!!(e!=null&&e.component)&&((a=e==null?void 0:e[":@"])==null?void 0:a.name)==="PhpStepFilterConfiguration"});t===void 0&&(t={component:[],":@":{name:"PhpStepFilterConfiguration"}},h.project===void 0&&(h.project=[]),h.project.push(t));let P=(i=t.component)==null?void 0:i.find(e=>!!(e!=null&&e.skipped_files));if(P===void 0&&(P={skipped_files:[]},t.component===void 0&&(t.component=[]),t.component.push(P)),r&&r.length)for(const e of r){const g=`$PROJECT_DIR$${e.endsWith("/")?e.slice(0,-1):e}`;((s=P.skipped_files)==null?void 0:s.some(S=>{var b;return!!(S!=null&&S.skipped_file)&&((b=S==null?void 0:S[":@"])==null?void 0:b.file)===g}))||(P.skipped_files===void 0&&(P.skipped_files=[]),P.skipped_files.push({skipped_file:[],":@":{file:g}}))}const y=new C.XMLBuilder(F).build(u);try{d.parse(y,!0)}catch{throw new Error("The resulting PhpStorm PHP configuration file is not valid XML.")}return y}function O(c,f){var l,o;const{name:r,pathMappings:d,pathSkippings:u}=f,h=[];let t=c,P=x.parseTree(t,h,I);if(P===void 0||h.length)throw new Error("VS Code configuration file is not valid JSON.");let v=x.findNodeAtLocation(P,["configurations"]);if(v===void 0||v.children===void 0){const i=x.modify(t,["configurations"],[],{});t=x.applyEdits(t,i),P=x.parseTree(t,[],I),v=x.findNodeAtLocation(P,["configurations"])}const y=(l=v==null?void 0:v.children)==null?void 0:l.findIndex(i=>{var s;return((s=x.findNodeAtLocation(i,["name"]))==null?void 0:s.value)===r});if(y===void 0||y<0){const i={name:r,type:"php",request:"launch",port:9003};d&&d.length&&(i.pathMappings=d.reduce((a,g)=>(a[g.vfsPath]=`\${workspaceFolder}/${D.toPosixPath(w.relative(f.workspaceDir,g.hostPath))}`,a),{})),u&&u.length&&(i.skipFiles=u.map(a=>a.endsWith("/")?`${a}**`:a));const s=((o=v==null?void 0:v.children)==null?void 0:o.length)||0,e=x.modify(t,["configurations",s],i,{formattingOptions:{insertSpaces:!0,tabSize:4,eol:`
`}});t=N(t,e)}return t}async function J({name:c,ides:f,host:r,port:d,cwd:u,mounts:h,pathSkippings:t,ideKey:P=M}){const v=h?X(u,h):[],y={};if(f.includes("phpstorm")){const l=".idea/workspace.xml",o=w.join(u,l);if(!p.existsSync(o)){if(p.existsSync(w.dirname(o)))p.writeFileSync(o,`<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
</project>`);else if(r.length==1)throw new Error("PhpStorm IDE integration requested, but no '.idea' directory was found in the current working directory.")}if(p.existsSync(n)){const s=p.readFileSync(n,"utf8"),l=A(s,{name:o,host:t,port:a,projectDir:h,mappings:u,ideKey:i});p.writeFileSync(n,l),g.phpstorm=m}}if(r.includes("vscode")){const m=".vscode/launch.json",n=P.join(h,m);if(!p.existsSync(n)){if(p.existsSync(P.dirname(n)))p.writeFileSync(n,`{
</project>`);else if(f.length==1)throw new Error("PhpStorm IDE integration requested, but no '.idea' directory was found in the current working directory.")}if(p.existsSync(o)){const i=p.readFileSync(o,"utf8"),s=$(i,{name:c,host:r,port:d,projectDir:u,pathMappings:v,ideKey:P});p.writeFileSync(o,s),y.phpstorm=l}if(t&&t.length){const i=".idea/php.xml",s=w.join(u,i);if(p.existsSync(s)||p.existsSync(w.dirname(s))&&p.writeFileSync(s,`<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
</project>`),p.existsSync(s)){const e=p.readFileSync(s,"utf8"),a=A(e,{pathSkippings:t});p.writeFileSync(s,a),y["phpstorm-php"]=i}}}if(f.includes("vscode")){const l=".vscode/launch.json",o=w.join(u,l);if(!p.existsSync(o)){if(p.existsSync(w.dirname(o)))p.writeFileSync(o,`{
"configurations": []
}`);else if(r.length==1)throw new Error("VS Code IDE integration requested, but no '.vscode' directory was found in the current working directory.")}if(p.existsSync(n)){const s=p.readFileSync(n,"utf-8"),l=N(s,{name:o,workspaceDir:h,mappings:u});l!==s&&(p.writeFileSync(n,l),g.vscode=m)}}return g}async function J(o,r){var h,f,i,u;const t=P.join(r,".idea/workspace.xml");if(p.existsSync(t)){const g=p.readFileSync(t,"utf8"),m=new j.XMLParser(x),n=(()=>{try{return m.parse(g,!0)}catch{throw new Error("PhpStorm configuration file is not valid XML.")}})(),s=n.find(c=>!!(c!=null&&c.project)),l=(h=s==null?void 0:s.project)==null?void 0:h.find(c=>{var w;return!!(c!=null&&c.component)&&((w=c==null?void 0:c[":@"])==null?void 0:w.name)==="PhpServers"}),y=(f=l==null?void 0:l.component)==null?void 0:f.find(c=>!!(c!=null&&c.servers)),d=(i=y==null?void 0:y.servers)==null?void 0:i.findIndex(c=>{var w;return!!(c!=null&&c.server)&&((w=c==null?void 0:c[":@"])==null?void 0:w.name)===o});if(d!==void 0&&d>=0){y.servers.splice(d,1);const w=new j.XMLBuilder(_).build(n);try{m.parse(w,!0)}catch{throw new Error("The resulting PhpStorm configuration file is not valid XML.")}w===`<?xml version="1.0" encoding="UTF-8"?>
}`);else if(f.length==1)throw new Error("VS Code IDE integration requested, but no '.vscode' directory was found in the current working directory.")}if(p.existsSync(o)){const i=p.readFileSync(o,"utf-8"),s=O(i,{name:c,workspaceDir:u,pathMappings:v,pathSkippings:t});s!==i&&(p.writeFileSync(o,s),y.vscode=l)}}return y}async function U(c,f){var h,t,P,v,y;const r=w.join(f,".idea/workspace.xml");if(p.existsSync(r)){const l=p.readFileSync(r,"utf8"),o=new C.XMLParser(E),i=(()=>{try{return o.parse(l,!0)}catch{throw new Error("PhpStorm configuration file is not valid XML.")}})(),s=i.find(m=>!!(m!=null&&m.project)),e=(h=s==null?void 0:s.project)==null?void 0:h.find(m=>{var S;return!!(m!=null&&m.component)&&((S=m==null?void 0:m[":@"])==null?void 0:S.name)==="PhpServers"}),a=(t=e==null?void 0:e.component)==null?void 0:t.find(m=>!!(m!=null&&m.servers)),g=(P=a==null?void 0:a.servers)==null?void 0:P.findIndex(m=>{var S;return!!(m!=null&&m.server)&&((S=m==null?void 0:m[":@"])==null?void 0:S.name)===c});if(g!==void 0&&g>=0){a.servers.splice(g,1);const S=new C.XMLBuilder(F).build(i);try{o.parse(S,!0)}catch{throw new Error("The resulting PhpStorm configuration file is not valid XML.")}S===`<?xml version="1.0" encoding="UTF-8"?>
<project version="4">

@@ -11,12 +13,14 @@ <component name="PhpServers">

</component>
</project>`?p.unlinkSync(t):p.writeFileSync(t,w)}}const a=P.join(r,".vscode/launch.json");if(p.existsSync(a)){const g=[],m=p.readFileSync(a,"utf-8"),n=v.parseTree(m,g,C);if(n===void 0||g.length)throw new Error("VS Code configuration file is not valid JSON.");const s=v.findNodeAtLocation(n,["configurations"]),l=(u=s==null?void 0:s.children)==null?void 0:u.findIndex(y=>{var d;return((d=v.findNodeAtLocation(y,["name"]))==null?void 0:d.value)===o});if(l!==void 0&&l>=0){const y=v.modify(m,["configurations",l],void 0,{formattingOptions:{insertSpaces:!0,tabSize:4,eol:`
`}}),d=$(m,y);d===`{
</project>`?p.unlinkSync(r):p.writeFileSync(r,S)}}const d=w.join(f,".idea/php.xml");if(p.existsSync(d)){const l=p.readFileSync(d,"utf8"),o=new C.XMLParser(E),i=(()=>{try{return o.parse(l,!0)}catch{throw new Error("PhpStorm PHP configuration file is not valid XML.")}})(),s=i.find(a=>!!(a!=null&&a.project)),e=(v=s==null?void 0:s.project)==null?void 0:v.findIndex(a=>{var g;return!!(a!=null&&a.component)&&((g=a==null?void 0:a[":@"])==null?void 0:g.name)==="PhpStepFilterConfiguration"});if(e!==void 0&&e>=0){s.project.splice(e,1);const g=new C.XMLBuilder(F).build(i);try{o.parse(g,!0)}catch{throw new Error("The resulting PhpStorm PHP configuration file is not valid XML.")}g===`<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
</project>`?p.unlinkSync(d):p.writeFileSync(d,g)}}const u=w.join(f,".vscode/launch.json");if(p.existsSync(u)){const l=[],o=p.readFileSync(u,"utf-8"),i=x.parseTree(o,l,I);if(i===void 0||l.length)throw new Error("VS Code configuration file is not valid JSON.");const s=x.findNodeAtLocation(i,["configurations"]),e=(y=s==null?void 0:s.children)==null?void 0:y.findIndex(a=>{var g;return((g=x.findNodeAtLocation(a,["name"]))==null?void 0:g.value)===c});if(e!==void 0&&e>=0){const a=x.modify(o,["configurations",e],void 0,{formattingOptions:{insertSpaces:!0,tabSize:4,eol:`
`}}),g=N(o,a);g===`{
"configurations": []
}`?p.unlinkSync(a):p.writeFileSync(a,d)}}}function U({cwd:o,mounts:r,pathSkippings:t}){return{pathMappings:o&&r?O(o,r):void 0,pathSkippings:t}}function $(o,r){const t=[],a=v.applyEdits(o,r);if(t.length=0,v.parseTree(a,t,C),t.length){const h=t.map(i=>({message:v.printParseErrorCode(i.error),offset:i.offset,length:i.length,fragment:a.slice(Math.max(0,i.offset-20),Math.min(a.length,i.offset+i.length+10))})).map(i=>`${i.message} at ${i.offset}:${i.length} (${i.fragment})`),f=r.map(i=>`At ${i.offset}:${i.length} - (${i.content})`);throw new Error(`VS Code configuration file (.vscode/launch.json) is not valid a JSONC after CLI modifications. This is likely a CLI bug. Please report it at https://github.com/WordPress/wordpress-playground/issues and include the contents of your ".vscode/launch.json" file.
}`?p.unlinkSync(u):p.writeFileSync(u,g)}}}function W({cwd:c,mounts:f,pathSkippings:r}){return{pathMappings:c&&f?X(c,f):void 0,pathSkippings:r}}function N(c,f){const r=[],d=x.applyEdits(c,f);if(r.length=0,x.parseTree(d,r,I),r.length){const u=r.map(t=>({message:x.printParseErrorCode(t.error),offset:t.offset,length:t.length,fragment:d.slice(Math.max(0,t.offset-20),Math.min(d.length,t.offset+t.length+10))})).map(t=>`${t.message} at ${t.offset}:${t.length} (${t.fragment})`),h=f.map(t=>`At ${t.offset}:${t.length} - (${t.content})`);throw new Error(`VS Code configuration file (.vscode/launch.json) is not valid a JSONC after CLI modifications. This is likely a CLI bug. Please report it at https://github.com/WordPress/wordpress-playground/issues and include the contents of your ".vscode/launch.json" file.
Applied edits: ${f.join(`
Applied edits: ${h.join(`
`)}
The errors are: ${h.join(`
`)}`)}return a}exports.DEFAULT_IDE_KEY=M;exports.addXdebugIDEConfig=V;exports.clearXdebugIDEConfig=J;exports.createTempDirSymlink=R;exports.makeXdebugConfig=U;exports.removeTempDirSymlink=q;exports.updatePhpStormConfig=A;exports.updateVSCodeConfig=N;
The errors are: ${u.join(`
`)}`)}return d}exports.DEFAULT_IDE_KEY=M;exports.DEFAULT_PATH_SKIPPINGS=R;exports.addXdebugIDEConfig=J;exports.clearXdebugIDEConfig=U;exports.createTempDirSymlink=q;exports.makeXdebugConfig=W;exports.removeTempDirSymlink=V;exports.updatePhpStormPHPConfig=A;exports.updatePhpStormWorkspaceConfig=$;exports.updateVSCodeConfig=O;
//# sourceMappingURL=index.cjs.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.cjs","sources":["../../../../packages/php-wasm/cli-util/src/lib/xdebug-path-mappings.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport { toPosixPath } from '@php-wasm/util';\nimport type { Mount } from './mounts';\nimport {\n\ttype X2jOptions,\n\ttype XmlBuilderOptions,\n\tXMLParser,\n\tXMLBuilder,\n} from 'fast-xml-parser';\nimport * as JSONC from 'jsonc-parser';\n\nexport interface XdebugOptions {\n\tideKey?: string;\n\tpathMappings?: Mount[];\n\tpathSkippings?: string[];\n}\n\nexport const DEFAULT_IDE_KEY = 'PHPWASMCLI';\n\n/**\n * Create a symlink to a tempory directory.\n *\n * The symlink is created to access the system temp dir\n * inside the current debugging directory.\n *\n * @param nativeDirPath The system temp dir path.\n * @param symlinkPath The symlink name.\n */\nexport async function createTempDirSymlink(\n\tnativeDirPath: string,\n\tsymlinkPath: string,\n\tplatform: string\n) {\n\tconst type =\n\t\tplatform === 'win32'\n\t\t\t? // On Windows, creating a 'dir' symlink can require elevated permissions.\n\t\t\t\t// In this case, let's make junction points because they function like\n\t\t\t\t// symlinks and do not require elevated permissions.\n\t\t\t\t'junction'\n\t\t\t: 'dir';\n\tfs.symlinkSync(nativeDirPath, symlinkPath, type);\n}\n\n/**\n * Remove the given temporary directory symlink if it exists.\n *\n * @param symlinkPath The symlink path.\n */\nexport async function removeTempDirSymlink(symlinkPath: string) {\n\ttry {\n\t\tconst stats = fs.lstatSync(symlinkPath);\n\t\tif (stats.isSymbolicLink()) {\n\t\t\tfs.unlinkSync(symlinkPath);\n\t\t}\n\t} catch {\n\t\t// Symlink does not exist or cannot be accessed, nothing to remove\n\t}\n}\n\n/**\n * Filters out mounts that are not in the current working directory\n *\n * @param mounts The mounts list.\n */\nfunction filterLocalMounts(cwd: string, mounts: Mount[]) {\n\treturn mounts.filter((mount) => {\n\t\tconst absoluteHostPath = path.resolve(mount.hostPath);\n\t\tconst cwdChildPrefix = path.join(cwd, path.sep);\n\t\treturn (\n\t\t\t// If auto-mounting from the current directory,\n\t\t\t// the entire project directory can be mapped.\n\t\t\tabsoluteHostPath === cwd ||\n\t\t\tabsoluteHostPath.startsWith(cwdChildPrefix)\n\t\t);\n\t});\n}\n\nexport type XdebugConfig = {\n\t/**\n\t * The current working directory to consider for debugger path mapping.\n\t */\n\tcwd?: string;\n\t/**\n\t * The mounts to consider for debugger path mapping.\n\t */\n\tmounts?: Mount[];\n\t/**\n\t * The paths to consider for debugger path skipping.\n\t */\n\tpathSkippings?: string[];\n};\n\nexport type IDEConfig = {\n\t/**\n\t * The name of the configuration within the IDE configuration.\n\t */\n\tname: string;\n\t/**\n\t * The IDEs to configure.\n\t */\n\tides: string[];\n\t/**\n\t * The web server host.\n\t */\n\thost: string;\n\t/**\n\t * The web server port.\n\t */\n\tport: number;\n\t/**\n\t * The current working directory to consider for debugger path mapping.\n\t */\n\tcwd: string;\n\t/**\n\t * The mounts to consider for debugger path mapping.\n\t */\n\tmounts?: Mount[];\n\t/**\n\t * The IDE key to use for the debug configuration. Defaults to 'PHPWASMCLI'.\n\t */\n\tideKey?: string;\n};\n\ntype PhpStormConfigMetaData = {\n\tname?: string;\n\tversion?: string;\n\thost?: string;\n\tuse_path_mappings?: string;\n\t'local-root'?: string;\n\t'remote-root'?: string;\n\t/**\n\t * The type of the server.\n\t */\n\ttype?: 'PhpRemoteDebugRunConfigurationType';\n\tfactoryName?: string;\n\tfilter_connections?: 'FILTER';\n\tserver_name?: string;\n\tsession_id?: string;\n\tv?: string;\n};\n\ntype PhpStormConfigNode = {\n\t':@'?: PhpStormConfigMetaData;\n\tproject?: PhpStormConfigNode[];\n\tcomponent?: PhpStormConfigNode[];\n\tservers?: PhpStormConfigNode[];\n\tserver?: PhpStormConfigNode[];\n\tpath_mappings?: PhpStormConfigNode[];\n\tmapping?: PhpStormConfigNode[];\n\tconfiguration?: PhpStormConfigNode[];\n\tmethod?: PhpStormConfigNode[];\n};\n\ntype VSCodeConfigMetaData = {\n\t[key: string]: string;\n};\n\ntype VSCodeConfigNode = {\n\tname: string;\n\ttype: string;\n\trequest: string;\n\tport: number;\n\tpathMappings?: VSCodeConfigMetaData;\n};\n\nconst xmlParserOptions: X2jOptions = {\n\tignoreAttributes: false,\n\tattributeNamePrefix: '',\n\tpreserveOrder: true,\n\tcdataPropName: '__cdata',\n\tcommentPropName: '__xmlComment',\n\tallowBooleanAttributes: true,\n\ttrimValues: true,\n};\nconst xmlBuilderOptions: XmlBuilderOptions = {\n\tignoreAttributes: xmlParserOptions.ignoreAttributes,\n\tattributeNamePrefix: xmlParserOptions.attributeNamePrefix,\n\tpreserveOrder: xmlParserOptions.preserveOrder,\n\tcdataPropName: xmlParserOptions.cdataPropName,\n\tcommentPropName: xmlParserOptions.commentPropName,\n\tsuppressBooleanAttributes: !xmlParserOptions.allowBooleanAttributes,\n\tformat: true,\n\tindentBy: '\\t',\n};\n\nconst jsoncParseOptions: JSONC.ParseOptions = {\n\tallowEmptyContent: true,\n\tallowTrailingComma: true,\n};\n\nexport type PhpStormConfigOptions = {\n\tname: string;\n\thost: string;\n\tport: number;\n\tprojectDir: string;\n\tmappings?: Mount[];\n\tideKey: string;\n};\n\n/**\n * Pure function to update PHPStorm XML config with Xdebug server and run configuration.\n *\n * @param xmlContent The original XML content of workspace.xml\n * @param options Configuration options for the server\n * @returns Updated XML content\n * @throws Error if XML is invalid or configuration is incompatible\n */\nexport function updatePhpStormConfig(\n\txmlContent: string,\n\toptions: PhpStormConfigOptions\n): string {\n\tconst { name, host, port, mappings, ideKey } = options;\n\n\tconst xmlParser = new XMLParser(xmlParserOptions);\n\n\t// Parse the XML\n\tconst config: PhpStormConfigNode[] = (() => {\n\t\ttry {\n\t\t\treturn xmlParser.parse(xmlContent, true);\n\t\t} catch {\n\t\t\tthrow new Error('PhpStorm configuration file is not valid XML.');\n\t\t}\n\t})();\n\n\t// Create the server element with path mappings\n\tconst serverElement: PhpStormConfigNode = {\n\t\tserver: [{}],\n\t\t':@': {\n\t\t\tname,\n\t\t\t// NOTE: PhpStorm quirk: Xdebug only works when the full URL (including port)\n\t\t\t// is provided in `host`. The separate `port` field is ignored or misinterpreted,\n\t\t\t// so we rely solely on host: \"host:port\".\n\t\t\thost: `${host}:${port}`,\n\t\t\tuse_path_mappings: 'true',\n\t\t},\n\t};\n\n\tif (mappings && mappings.length) {\n\t\tserverElement.server![0].path_mappings = mappings.map((mapping) => ({\n\t\t\tmapping: [],\n\t\t\t':@': {\n\t\t\t\t'local-root': `$PROJECT_DIR$/${toPosixPath(\n\t\t\t\t\tpath.relative(options.projectDir, mapping.hostPath)\n\t\t\t\t)}`,\n\t\t\t\t'remote-root': mapping.vfsPath,\n\t\t\t},\n\t\t}));\n\t}\n\n\t// Find or create project element\n\tlet projectElement = config?.find((c: PhpStormConfigNode) => !!c?.project);\n\tif (projectElement) {\n\t\tconst projectVersion = projectElement[':@']?.version;\n\t\tif (projectVersion === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm IDE integration only supports <project version=\"4\"> in workspace.xml, ' +\n\t\t\t\t\t'but the <project> configuration has no version number.'\n\t\t\t);\n\t\t} else if (projectVersion !== '4') {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm IDE integration only supports <project version=\"4\"> in workspace.xml, ' +\n\t\t\t\t\t`but we found a <project> configuration with version \"${projectVersion}\".`\n\t\t\t);\n\t\t}\n\t}\n\tif (projectElement === undefined) {\n\t\tprojectElement = {\n\t\t\tproject: [],\n\t\t\t':@': { version: '4' },\n\t\t};\n\t\tconfig.push(projectElement);\n\t}\n\n\t// Find or create PhpServers component\n\tlet componentElement = projectElement.project?.find(\n\t\t(c: PhpStormConfigNode) =>\n\t\t\t!!c?.component && c?.[':@']?.name === 'PhpServers'\n\t);\n\tif (componentElement === undefined) {\n\t\tcomponentElement = {\n\t\t\tcomponent: [],\n\t\t\t':@': { name: 'PhpServers' },\n\t\t};\n\n\t\tif (projectElement.project === undefined) {\n\t\t\tprojectElement.project = [];\n\t\t}\n\n\t\tprojectElement.project.push(componentElement);\n\t}\n\n\t// Find or create servers element\n\tlet serversElement = componentElement.component?.find(\n\t\t(c: PhpStormConfigNode) => !!c?.servers\n\t);\n\tif (serversElement === undefined) {\n\t\tserversElement = { servers: [] };\n\n\t\tif (componentElement.component === undefined) {\n\t\t\tcomponentElement.component = [];\n\t\t}\n\n\t\tcomponentElement.component.push(serversElement);\n\t}\n\n\t// Check if server already exists\n\tconst serverElementIndex = serversElement.servers?.findIndex(\n\t\t(c: PhpStormConfigNode) => !!c?.server && c?.[':@']?.name === name\n\t);\n\n\t// Only add server if it doesn't exist\n\tif (serverElementIndex === undefined || serverElementIndex < 0) {\n\t\tif (serversElement.servers === undefined) {\n\t\t\tserversElement.servers = [];\n\t\t}\n\n\t\tserversElement.servers.push(serverElement);\n\t}\n\n\t// Find or create RunManager component\n\tlet runManagerElement = projectElement.project?.find(\n\t\t(c: PhpStormConfigNode) =>\n\t\t\t!!c?.component && c?.[':@']?.name === 'RunManager'\n\t);\n\tif (runManagerElement === undefined) {\n\t\trunManagerElement = {\n\t\t\tcomponent: [],\n\t\t\t':@': { name: 'RunManager' },\n\t\t};\n\n\t\tif (projectElement.project === undefined) {\n\t\t\tprojectElement.project = [];\n\t\t}\n\n\t\tprojectElement.project.push(runManagerElement);\n\t}\n\n\t// Check if run configuration already exists\n\tconst existingConfigIndex =\n\t\trunManagerElement.component?.findIndex(\n\t\t\t(c: PhpStormConfigNode) =>\n\t\t\t\t!!c?.configuration && c?.[':@']?.name === name\n\t\t) ?? -1;\n\n\t// Only add run configuration if it doesn't exist\n\tif (existingConfigIndex < 0) {\n\t\tconst runConfigElement: PhpStormConfigNode = {\n\t\t\tconfiguration: [\n\t\t\t\t{\n\t\t\t\t\tmethod: [],\n\t\t\t\t\t':@': { v: '2' },\n\t\t\t\t},\n\t\t\t],\n\t\t\t':@': {\n\t\t\t\tname: name,\n\t\t\t\ttype: 'PhpRemoteDebugRunConfigurationType',\n\t\t\t\tfactoryName: 'PHP Remote Debug',\n\t\t\t\tfilter_connections: 'FILTER',\n\t\t\t\tserver_name: name,\n\t\t\t\tsession_id: ideKey,\n\t\t\t},\n\t\t};\n\n\t\tif (runManagerElement.component === undefined) {\n\t\t\trunManagerElement.component = [];\n\t\t}\n\n\t\trunManagerElement.component.push(runConfigElement);\n\t}\n\n\t// Build the updated XML\n\tconst xmlBuilder = new XMLBuilder(xmlBuilderOptions);\n\tconst xml = xmlBuilder.build(config);\n\n\t// Validate the generated XML\n\ttry {\n\t\txmlParser.parse(xml, true);\n\t} catch {\n\t\tthrow new Error(\n\t\t\t'The resulting PhpStorm configuration file is not valid XML.'\n\t\t);\n\t}\n\n\treturn xml;\n}\n\nexport type VSCodeConfigOptions = {\n\tname: string;\n\tworkspaceDir: string;\n\tmappings?: Mount[];\n};\n\n/**\n * Pure function to update VS Code JSON config with Xdebug configuration.\n *\n * @param jsonContent The original JSON content of launch.json\n * @param options Configuration options\n * @returns Updated JSON content\n * @throws Error if JSON is invalid\n */\nexport function updateVSCodeConfig(\n\tjsonContent: string,\n\toptions: VSCodeConfigOptions\n): string {\n\tconst { name, mappings } = options;\n\n\tconst errors: JSONC.ParseError[] = [];\n\n\tlet content = jsonContent;\n\tlet root = JSONC.parseTree(content, errors, jsoncParseOptions);\n\n\tif (root === undefined || errors.length) {\n\t\tthrow new Error('VS Code configuration file is not valid JSON.');\n\t}\n\n\t// Find or create configurations array\n\tlet configurationsNode = JSONC.findNodeAtLocation(root, ['configurations']);\n\n\tif (\n\t\tconfigurationsNode === undefined ||\n\t\tconfigurationsNode.children === undefined\n\t) {\n\t\tconst edits = JSONC.modify(content, ['configurations'], [], {});\n\t\tcontent = JSONC.applyEdits(content, edits);\n\n\t\troot = JSONC.parseTree(content, [], jsoncParseOptions);\n\t\tconfigurationsNode = JSONC.findNodeAtLocation(root!, [\n\t\t\t'configurations',\n\t\t]);\n\t}\n\n\t// Check if configuration already exists\n\tconst configurationIndex = configurationsNode?.children?.findIndex(\n\t\t(child: any) =>\n\t\t\tJSONC.findNodeAtLocation(child, ['name'])?.value === name\n\t);\n\n\t// Only add configuration if it doesn't exist\n\tif (configurationIndex === undefined || configurationIndex < 0) {\n\t\tconst configuration: VSCodeConfigNode = {\n\t\t\tname: name,\n\t\t\ttype: 'php',\n\t\t\trequest: 'launch',\n\t\t\tport: 9003,\n\t\t};\n\n\t\tif (mappings && mappings.length) {\n\t\t\tconfiguration.pathMappings = mappings.reduce((acc, mount) => {\n\t\t\t\tacc[mount.vfsPath] = `\\${workspaceFolder}/${toPosixPath(\n\t\t\t\t\tpath.relative(options.workspaceDir, mount.hostPath)\n\t\t\t\t)}`;\n\t\t\t\treturn acc;\n\t\t\t}, {} as VSCodeConfigMetaData);\n\t\t}\n\n\t\t// Get the current length to append at the end\n\t\tconst currentLength = configurationsNode?.children?.length || 0;\n\n\t\tconst edits = JSONC.modify(\n\t\t\tcontent,\n\t\t\t['configurations', currentLength],\n\t\t\tconfiguration,\n\t\t\t{\n\t\t\t\tformattingOptions: {\n\t\t\t\t\tinsertSpaces: true,\n\t\t\t\t\ttabSize: 4,\n\t\t\t\t\teol: '\\n',\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\n\t\tcontent = jsoncApplyEdits(content, edits);\n\t}\n\n\treturn content;\n}\n\n/**\n * Implement necessary parameters and path mappings in IDE configuration files.\n *\n * @param name The configuration name.\n * @param mounts The mounts options.\n */\nexport async function addXdebugIDEConfig({\n\tname,\n\tides,\n\thost,\n\tport,\n\tcwd,\n\tmounts,\n\tideKey = DEFAULT_IDE_KEY,\n}: IDEConfig) {\n\tconst mappings = mounts ? filterLocalMounts(cwd, mounts) : [];\n\tconst modifiedConfig: Record<string, string> = {};\n\n\t// PHPstorm\n\tif (ides.includes('phpstorm')) {\n\t\tconst phpStormRelativeConfigFilePath = '.idea/workspace.xml';\n\t\tconst phpStormConfigFilePath = path.join(\n\t\t\tcwd,\n\t\t\tphpStormRelativeConfigFilePath\n\t\t);\n\n\t\t// Create a template config file if the IDE directory exists,\n\t\t// or throw an error if IDE integration is requested but the directory is missing.\n\t\tif (!fs.existsSync(phpStormConfigFilePath)) {\n\t\t\tif (fs.existsSync(path.dirname(phpStormConfigFilePath))) {\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tphpStormConfigFilePath,\n\t\t\t\t\t'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<project version=\"4\">\\n</project>'\n\t\t\t\t);\n\t\t\t} else if (ides.length == 1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`PhpStorm IDE integration requested, but no '.idea' directory was found in the current working directory.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (fs.existsSync(phpStormConfigFilePath)) {\n\t\t\tconst contents = fs.readFileSync(phpStormConfigFilePath, 'utf8');\n\t\t\tconst updatedXml = updatePhpStormConfig(contents, {\n\t\t\t\tname,\n\t\t\t\thost,\n\t\t\t\tport,\n\t\t\t\tprojectDir: cwd,\n\t\t\t\tmappings,\n\t\t\t\tideKey,\n\t\t\t});\n\t\t\tfs.writeFileSync(phpStormConfigFilePath, updatedXml);\n\t\t\tmodifiedConfig['phpstorm'] = phpStormRelativeConfigFilePath;\n\t\t}\n\t}\n\n\t// VSCode\n\tif (ides.includes('vscode')) {\n\t\tconst vsCodeRelativeConfigFilePath = '.vscode/launch.json';\n\t\tconst vsCodeConfigFilePath = path.join(\n\t\t\tcwd,\n\t\t\tvsCodeRelativeConfigFilePath\n\t\t);\n\n\t\t// Create a template config file if the IDE directory exists,\n\t\t// or throw an error if IDE integration is requested but the directory is missing.\n\t\tif (!fs.existsSync(vsCodeConfigFilePath)) {\n\t\t\tif (fs.existsSync(path.dirname(vsCodeConfigFilePath))) {\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tvsCodeConfigFilePath,\n\t\t\t\t\t'{\\n \"configurations\": []\\n}'\n\t\t\t\t);\n\t\t\t} else if (ides.length == 1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`VS Code IDE integration requested, but no '.vscode' directory was found in the current working directory.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (fs.existsSync(vsCodeConfigFilePath)) {\n\t\t\tconst content = fs.readFileSync(vsCodeConfigFilePath, 'utf-8');\n\t\t\tconst updatedJson = updateVSCodeConfig(content, {\n\t\t\t\tname,\n\t\t\t\tworkspaceDir: cwd,\n\t\t\t\tmappings,\n\t\t\t});\n\n\t\t\t// Only write and track the file if changes were made\n\t\t\tif (updatedJson !== content) {\n\t\t\t\tfs.writeFileSync(vsCodeConfigFilePath, updatedJson);\n\t\t\t\tmodifiedConfig['vscode'] = vsCodeRelativeConfigFilePath;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn modifiedConfig;\n}\n\n/**\n * Remove stale parameters and path mappings in IDE configuration files.\n *\n * @param name The configuration name.\n * @param cwd The current working directory.\n */\nexport async function clearXdebugIDEConfig(name: string, cwd: string) {\n\tconst phpStormConfigFilePath = path.join(cwd, '.idea/workspace.xml');\n\t// PhpStorm\n\tif (fs.existsSync(phpStormConfigFilePath)) {\n\t\tconst contents = fs.readFileSync(phpStormConfigFilePath, 'utf8');\n\t\tconst xmlParser = new XMLParser(xmlParserOptions);\n\t\t// NOTE: Using an IIFE so `config` can remain const.\n\t\tconst config: PhpStormConfigNode[] = (() => {\n\t\t\ttry {\n\t\t\t\treturn xmlParser.parse(contents, true);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'PhpStorm configuration file is not valid XML.'\n\t\t\t\t);\n\t\t\t}\n\t\t})();\n\n\t\tconst projectElement = config.find(\n\t\t\t(c: PhpStormConfigNode) => !!c?.project\n\t\t);\n\t\tconst componentElement = projectElement?.project?.find(\n\t\t\t(c: PhpStormConfigNode) =>\n\t\t\t\t!!c?.component && c?.[':@']?.name === 'PhpServers'\n\t\t);\n\t\tconst serversElement = componentElement?.component?.find(\n\t\t\t(c: PhpStormConfigNode) => !!c?.servers\n\t\t);\n\t\tconst serverElementIndex = serversElement?.servers?.findIndex(\n\t\t\t(c: PhpStormConfigNode) => !!c?.server && c?.[':@']?.name === name\n\t\t);\n\n\t\tif (serverElementIndex !== undefined && serverElementIndex >= 0) {\n\t\t\tserversElement!.servers!.splice(serverElementIndex, 1);\n\n\t\t\tconst xmlBuilder = new XMLBuilder(xmlBuilderOptions);\n\t\t\tconst xml = xmlBuilder.build(config);\n\n\t\t\ttry {\n\t\t\t\txmlParser.parse(xml, true);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'The resulting PhpStorm configuration file is not valid XML.'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\txml ===\n\t\t\t\t'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<project version=\"4\">\\n\t<component name=\"PhpServers\">\\n\t\t<servers></servers>\\n\t</component>\\n</project>'\n\t\t\t) {\n\t\t\t\tfs.unlinkSync(phpStormConfigFilePath);\n\t\t\t} else {\n\t\t\t\tfs.writeFileSync(phpStormConfigFilePath, xml);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst vsCodeConfigFilePath = path.join(cwd, '.vscode/launch.json');\n\t// VSCode\n\tif (fs.existsSync(vsCodeConfigFilePath)) {\n\t\tconst errors: JSONC.ParseError[] = [];\n\n\t\tconst content = fs.readFileSync(vsCodeConfigFilePath, 'utf-8');\n\t\tconst root = JSONC.parseTree(content, errors, jsoncParseOptions);\n\n\t\tif (root === undefined || errors.length) {\n\t\t\tthrow new Error('VS Code configuration file is not valid JSON.');\n\t\t}\n\n\t\tconst configurationsNode = JSONC.findNodeAtLocation(root, [\n\t\t\t'configurations',\n\t\t]);\n\n\t\tconst configurationIndex = configurationsNode?.children?.findIndex(\n\t\t\t(child: any) =>\n\t\t\t\tJSONC.findNodeAtLocation(child, ['name'])?.value === name\n\t\t);\n\n\t\tif (configurationIndex !== undefined && configurationIndex >= 0) {\n\t\t\tconst edits = JSONC.modify(\n\t\t\t\tcontent,\n\t\t\t\t['configurations', configurationIndex],\n\t\t\t\tundefined,\n\t\t\t\t{\n\t\t\t\t\tformattingOptions: {\n\t\t\t\t\t\tinsertSpaces: true,\n\t\t\t\t\t\ttabSize: 4,\n\t\t\t\t\t\teol: '\\n',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tconst json = jsoncApplyEdits(content, edits);\n\t\t\tif (json === '{\\n \"configurations\": []\\n}') {\n\t\t\t\tfs.unlinkSync(vsCodeConfigFilePath);\n\t\t\t} else {\n\t\t\t\tfs.writeFileSync(vsCodeConfigFilePath, json);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Implement path mapping and path skipping in Xdebug.\n *\n * @param name The configuration name.\n * @param mounts The mounts options.\n * @param pathSkippings The skipping paths options.\n * @returns Xdebug options\n */\nexport function makeXdebugConfig({\n\tcwd,\n\tmounts,\n\tpathSkippings,\n}: XdebugConfig): XdebugOptions {\n\tconst pathMappings =\n\t\tcwd && mounts ? filterLocalMounts(cwd, mounts) : undefined;\n\n\treturn { pathMappings, pathSkippings };\n}\n\nfunction jsoncApplyEdits(content: string, edits: JSONC.Edit[]) {\n\tconst errors: JSONC.ParseError[] = [];\n\tconst json = JSONC.applyEdits(content, edits);\n\n\terrors.length = 0;\n\n\tJSONC.parseTree(json, errors, jsoncParseOptions);\n\n\tif (errors.length) {\n\t\tconst formattedErrors = errors\n\t\t\t.map((error) => {\n\t\t\t\treturn {\n\t\t\t\t\tmessage: JSONC.printParseErrorCode(error.error),\n\t\t\t\t\toffset: error.offset,\n\t\t\t\t\tlength: error.length,\n\t\t\t\t\tfragment: json.slice(\n\t\t\t\t\t\tMath.max(0, error.offset - 20),\n\t\t\t\t\t\tMath.min(json.length, error.offset + error.length + 10)\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t})\n\t\t\t.map(\n\t\t\t\t(error) =>\n\t\t\t\t\t`${error.message} at ${error.offset}:${error.length} (${error.fragment})`\n\t\t\t);\n\t\tconst formattedEdits = edits.map(\n\t\t\t(edit) => `At ${edit.offset}:${edit.length} - (${edit.content})`\n\t\t);\n\t\tthrow new Error(\n\t\t\t`VS Code configuration file (.vscode/launch.json) is not valid a JSONC after CLI modifications. This is likely ` +\n\t\t\t\t`a CLI bug. Please report it at https://github.com/WordPress/wordpress-playground/issues and include the contents ` +\n\t\t\t\t`of your \".vscode/launch.json\" file. \\n\\n Applied edits: ${formattedEdits.join(\n\t\t\t\t\t'\\n'\n\t\t\t\t)}\\n\\n The errors are: ${formattedErrors.join('\\n')}`\n\t\t);\n\t}\n\n\treturn json;\n}\n"],"names":["DEFAULT_IDE_KEY","createTempDirSymlink","nativeDirPath","symlinkPath","platform","type","fs","removeTempDirSymlink","filterLocalMounts","cwd","mounts","mount","absoluteHostPath","path","cwdChildPrefix","xmlParserOptions","xmlBuilderOptions","jsoncParseOptions","updatePhpStormConfig","xmlContent","options","name","host","port","mappings","ideKey","xmlParser","XMLParser","config","serverElement","mapping","toPosixPath","projectElement","c","projectVersion","_a","componentElement","_b","serversElement","_c","serverElementIndex","_d","runManagerElement","_e","_f","runConfigElement","xml","XMLBuilder","updateVSCodeConfig","jsonContent","errors","content","root","JSONC","configurationsNode","edits","configurationIndex","child","configuration","acc","currentLength","jsoncApplyEdits","addXdebugIDEConfig","ides","modifiedConfig","phpStormRelativeConfigFilePath","phpStormConfigFilePath","contents","updatedXml","vsCodeRelativeConfigFilePath","vsCodeConfigFilePath","updatedJson","clearXdebugIDEConfig","json","makeXdebugConfig","pathSkippings","formattedErrors","error","formattedEdits","edit"],"mappings":"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"}
{"version":3,"file":"index.cjs","sources":["../../../../packages/php-wasm/cli-util/src/lib/xdebug-path-mappings.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport { toPosixPath } from '@php-wasm/util';\nimport type { Mount } from './mounts';\nimport {\n\ttype X2jOptions,\n\ttype XmlBuilderOptions,\n\tXMLParser,\n\tXMLBuilder,\n} from 'fast-xml-parser';\nimport * as JSONC from 'jsonc-parser';\n\nexport interface XdebugOptions {\n\tideKey?: string;\n\tpathMappings?: Mount[];\n\tpathSkippings?: string[];\n}\n\nexport const DEFAULT_IDE_KEY = 'PHPWASMCLI';\nexport const DEFAULT_PATH_SKIPPINGS = [\n\t'/dev/',\n\t'/home/',\n\t'/internal/',\n\t'/request/',\n\t'/proc/',\n];\n\n/**\n * Create a symlink to a tempory directory.\n *\n * The symlink is created to access the system temp dir\n * inside the current debugging directory.\n *\n * @param nativeDirPath The system temp dir path.\n * @param symlinkPath The symlink name.\n */\nexport async function createTempDirSymlink(\n\tnativeDirPath: string,\n\tsymlinkPath: string,\n\tplatform: string\n) {\n\tconst type =\n\t\tplatform === 'win32'\n\t\t\t? // On Windows, creating a 'dir' symlink can require elevated permissions.\n\t\t\t\t// In this case, let's make junction points because they function like\n\t\t\t\t// symlinks and do not require elevated permissions.\n\t\t\t\t'junction'\n\t\t\t: 'dir';\n\tfs.symlinkSync(nativeDirPath, symlinkPath, type);\n}\n\n/**\n * Remove the given temporary directory symlink if it exists.\n *\n * @param symlinkPath The symlink path.\n */\nexport async function removeTempDirSymlink(symlinkPath: string) {\n\ttry {\n\t\tconst stats = fs.lstatSync(symlinkPath);\n\t\tif (stats.isSymbolicLink()) {\n\t\t\tfs.unlinkSync(symlinkPath);\n\t\t}\n\t} catch {\n\t\t// Symlink does not exist or cannot be accessed, nothing to remove\n\t}\n}\n\n/**\n * Filters out mounts that are not in the current working directory\n *\n * @param mounts The mounts list.\n */\nfunction filterLocalMounts(cwd: string, mounts: Mount[]) {\n\treturn mounts.filter((mount) => {\n\t\tconst absoluteHostPath = path.resolve(mount.hostPath);\n\t\tconst cwdChildPrefix = path.join(cwd, path.sep);\n\t\treturn (\n\t\t\t// If auto-mounting from the current directory,\n\t\t\t// the entire project directory can be mapped.\n\t\t\tabsoluteHostPath === cwd ||\n\t\t\tabsoluteHostPath.startsWith(cwdChildPrefix)\n\t\t);\n\t});\n}\n\nexport type XdebugConfig = {\n\t/**\n\t * The current working directory to consider for debugger path mapping.\n\t */\n\tcwd?: string;\n\t/**\n\t * The mounts to consider for debugger path mapping.\n\t */\n\tmounts?: Mount[];\n\t/**\n\t * The paths to consider for debugger path skipping.\n\t */\n\tpathSkippings?: string[];\n};\n\nexport type IDEConfig = {\n\t/**\n\t * The name of the configuration within the IDE configuration.\n\t */\n\tname: string;\n\t/**\n\t * The IDEs to configure.\n\t */\n\tides: string[];\n\t/**\n\t * The web server host.\n\t */\n\thost: string;\n\t/**\n\t * The web server port.\n\t */\n\tport: number;\n\t/**\n\t * The current working directory to consider for debugger path mapping.\n\t */\n\tcwd: string;\n\t/**\n\t * The mounts to consider for debugger path mapping.\n\t */\n\tmounts?: Mount[];\n\t/**\n\t * The paths to skip when debugging.\n\t */\n\tpathSkippings?: string[];\n\t/**\n\t * The IDE key to use for the debug configuration. Defaults to 'PHPWASMCLI'.\n\t */\n\tideKey?: string;\n};\n\ntype PhpStormWorkspaceConfigMetaData = {\n\tname?: string;\n\tversion?: string;\n\thost?: string;\n\tuse_path_mappings?: string;\n\t'local-root'?: string;\n\t'remote-root'?: string;\n\ttype?: 'PhpRemoteDebugRunConfigurationType';\n\tfactoryName?: string;\n\tfilter_connections?: 'FILTER';\n\tserver_name?: string;\n\tsession_id?: string;\n\tv?: string;\n};\n\ntype PhpStormWorkspaceConfigNode = {\n\t':@'?: PhpStormWorkspaceConfigMetaData;\n\tproject?: PhpStormWorkspaceConfigNode[];\n\tcomponent?: PhpStormWorkspaceConfigNode[];\n\tservers?: PhpStormWorkspaceConfigNode[];\n\tserver?: PhpStormWorkspaceConfigNode[];\n\tpath_mappings?: PhpStormWorkspaceConfigNode[];\n\tmapping?: PhpStormWorkspaceConfigNode[];\n\tconfiguration?: PhpStormWorkspaceConfigNode[];\n\tmethod?: PhpStormWorkspaceConfigNode[];\n};\n\ntype PhpStormPHPConfigMetaData = {\n\tname?: string;\n\tversion?: string;\n\tfile?: string;\n};\n\ntype PhpStormPHPConfigNode = {\n\t':@'?: PhpStormPHPConfigMetaData;\n\tproject?: PhpStormPHPConfigNode[];\n\tcomponent?: PhpStormPHPConfigNode[];\n\tskipped_files?: PhpStormPHPConfigNode[];\n\tskipped_file?: PhpStormPHPConfigNode[];\n};\n\ntype VSCodeConfigMetaData = {\n\t[key: string]: string;\n};\n\ntype VSCodeConfigNode = {\n\tname: string;\n\ttype: string;\n\trequest: string;\n\tport: number;\n\tpathMappings?: VSCodeConfigMetaData;\n\tskipFiles?: string[];\n};\n\nconst xmlParserOptions: X2jOptions = {\n\tignoreAttributes: false,\n\tattributeNamePrefix: '',\n\tpreserveOrder: true,\n\tcdataPropName: '__cdata',\n\tcommentPropName: '__xmlComment',\n\tallowBooleanAttributes: true,\n\ttrimValues: true,\n};\nconst xmlBuilderOptions: XmlBuilderOptions = {\n\tignoreAttributes: xmlParserOptions.ignoreAttributes,\n\tattributeNamePrefix: xmlParserOptions.attributeNamePrefix,\n\tpreserveOrder: xmlParserOptions.preserveOrder,\n\tcdataPropName: xmlParserOptions.cdataPropName,\n\tcommentPropName: xmlParserOptions.commentPropName,\n\tsuppressBooleanAttributes: !xmlParserOptions.allowBooleanAttributes,\n\tformat: true,\n\tindentBy: '\\t',\n};\n\nconst jsoncParseOptions: JSONC.ParseOptions = {\n\tallowEmptyContent: true,\n\tallowTrailingComma: true,\n};\n\nexport type PhpStormWorkspaceConfigOptions = {\n\tname: string;\n\thost: string;\n\tport: number;\n\tprojectDir: string;\n\tpathMappings?: Mount[];\n\tideKey: string;\n};\n\n/**\n * Pure function to update PHPStorm XML config with Xdebug server and run configuration.\n *\n * @param xmlContent The original XML content of workspace.xml\n * @param options Configuration options for the server\n * @returns Updated XML content\n * @throws Error if XML is invalid or configuration is incompatible\n */\nexport function updatePhpStormWorkspaceConfig(\n\txmlContent: string,\n\toptions: PhpStormWorkspaceConfigOptions\n): string {\n\tconst { name, host, port, pathMappings, ideKey } = options;\n\n\tconst xmlParser = new XMLParser(xmlParserOptions);\n\n\t// Parse the XML\n\tconst config: PhpStormWorkspaceConfigNode[] = (() => {\n\t\ttry {\n\t\t\treturn xmlParser.parse(xmlContent, true);\n\t\t} catch {\n\t\t\tthrow new Error('PhpStorm configuration file is not valid XML.');\n\t\t}\n\t})();\n\n\t// Create the server element with path mappings\n\tconst serverElement: PhpStormWorkspaceConfigNode = {\n\t\tserver: [{}],\n\t\t':@': {\n\t\t\tname,\n\t\t\t// NOTE: PhpStorm quirk: Xdebug only works when the full URL (including port)\n\t\t\t// is provided in `host`. The separate `port` field is ignored or misinterpreted,\n\t\t\t// so we rely solely on host: \"host:port\".\n\t\t\thost: `${host}:${port}`,\n\t\t\tuse_path_mappings: 'true',\n\t\t},\n\t};\n\n\tif (pathMappings && pathMappings.length) {\n\t\tserverElement.server![0].path_mappings = pathMappings.map(\n\t\t\t(pathMapping) => ({\n\t\t\t\tmapping: [],\n\t\t\t\t':@': {\n\t\t\t\t\t'local-root': `$PROJECT_DIR$/${toPosixPath(\n\t\t\t\t\t\tpath.relative(options.projectDir, pathMapping.hostPath)\n\t\t\t\t\t)}`,\n\t\t\t\t\t'remote-root': pathMapping.vfsPath,\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n\n\t// Find or create project element\n\tlet projectElement = config?.find(\n\t\t(c: PhpStormWorkspaceConfigNode) => !!c?.project\n\t);\n\tif (projectElement) {\n\t\tconst projectVersion = projectElement[':@']?.version;\n\t\tif (projectVersion === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm IDE integration only supports <project version=\"4\"> in workspace.xml, ' +\n\t\t\t\t\t'but the <project> configuration has no version number.'\n\t\t\t);\n\t\t} else if (projectVersion !== '4') {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm IDE integration only supports <project version=\"4\"> in workspace.xml, ' +\n\t\t\t\t\t`but we found a <project> configuration with version \"${projectVersion}\".`\n\t\t\t);\n\t\t}\n\t}\n\tif (projectElement === undefined) {\n\t\tprojectElement = {\n\t\t\tproject: [],\n\t\t\t':@': { version: '4' },\n\t\t};\n\t\tconfig.push(projectElement);\n\t}\n\n\t// Find or create PhpServers component\n\tlet componentElement = projectElement.project?.find(\n\t\t(c: PhpStormWorkspaceConfigNode) =>\n\t\t\t!!c?.component && c?.[':@']?.name === 'PhpServers'\n\t);\n\tif (componentElement === undefined) {\n\t\tcomponentElement = {\n\t\t\tcomponent: [],\n\t\t\t':@': { name: 'PhpServers' },\n\t\t};\n\n\t\tif (projectElement.project === undefined) {\n\t\t\tprojectElement.project = [];\n\t\t}\n\n\t\tprojectElement.project.push(componentElement);\n\t}\n\n\t// Find or create servers element\n\tlet serversElement = componentElement.component?.find(\n\t\t(c: PhpStormWorkspaceConfigNode) => !!c?.servers\n\t);\n\tif (serversElement === undefined) {\n\t\tserversElement = { servers: [] };\n\n\t\tif (componentElement.component === undefined) {\n\t\t\tcomponentElement.component = [];\n\t\t}\n\n\t\tcomponentElement.component.push(serversElement);\n\t}\n\n\t// Check if server already exists\n\tconst serverElementIndex = serversElement.servers?.findIndex(\n\t\t(c: PhpStormWorkspaceConfigNode) =>\n\t\t\t!!c?.server && c?.[':@']?.name === name\n\t);\n\n\t// Only add server if it doesn't exist\n\tif (serverElementIndex === undefined || serverElementIndex < 0) {\n\t\tif (serversElement.servers === undefined) {\n\t\t\tserversElement.servers = [];\n\t\t}\n\n\t\tserversElement.servers.push(serverElement);\n\t}\n\n\t// Find or create RunManager component\n\tlet runManagerElement = projectElement.project?.find(\n\t\t(c: PhpStormWorkspaceConfigNode) =>\n\t\t\t!!c?.component && c?.[':@']?.name === 'RunManager'\n\t);\n\tif (runManagerElement === undefined) {\n\t\trunManagerElement = {\n\t\t\tcomponent: [],\n\t\t\t':@': { name: 'RunManager' },\n\t\t};\n\n\t\tif (projectElement.project === undefined) {\n\t\t\tprojectElement.project = [];\n\t\t}\n\n\t\tprojectElement.project.push(runManagerElement);\n\t}\n\n\t// Check if run configuration already exists\n\tconst existingConfigIndex =\n\t\trunManagerElement.component?.findIndex(\n\t\t\t(c: PhpStormWorkspaceConfigNode) =>\n\t\t\t\t!!c?.configuration && c?.[':@']?.name === name\n\t\t) ?? -1;\n\n\t// Only add run configuration if it doesn't exist\n\tif (existingConfigIndex < 0) {\n\t\tconst runConfigElement: PhpStormWorkspaceConfigNode = {\n\t\t\tconfiguration: [\n\t\t\t\t{\n\t\t\t\t\tmethod: [],\n\t\t\t\t\t':@': { v: '2' },\n\t\t\t\t},\n\t\t\t],\n\t\t\t':@': {\n\t\t\t\tname: name,\n\t\t\t\ttype: 'PhpRemoteDebugRunConfigurationType',\n\t\t\t\tfactoryName: 'PHP Remote Debug',\n\t\t\t\tfilter_connections: 'FILTER',\n\t\t\t\tserver_name: name,\n\t\t\t\tsession_id: ideKey,\n\t\t\t},\n\t\t};\n\n\t\tif (runManagerElement.component === undefined) {\n\t\t\trunManagerElement.component = [];\n\t\t}\n\n\t\trunManagerElement.component.push(runConfigElement);\n\t}\n\n\t// Build the updated XML\n\tconst xmlBuilder = new XMLBuilder(xmlBuilderOptions);\n\tconst xml = xmlBuilder.build(config);\n\n\t// Validate the generated XML\n\ttry {\n\t\txmlParser.parse(xml, true);\n\t} catch {\n\t\tthrow new Error(\n\t\t\t'The resulting PhpStorm configuration file is not valid XML.'\n\t\t);\n\t}\n\n\treturn xml;\n}\n\nexport type PhpStormPHPConfigOptions = {\n\tpathSkippings?: string[];\n};\n\n/**\n * Pure function to update PhpStorm php.xml config with skipped files.\n *\n * @param xmlContent The original XML content of php.xml\n * @param options Configuration options for skipped files\n * @returns Updated XML content\n * @throws Error if XML is invalid or configuration is incompatible\n */\nexport function updatePhpStormPHPConfig(\n\txmlContent: string,\n\toptions: PhpStormPHPConfigOptions\n): string {\n\tconst { pathSkippings } = options;\n\n\tconst xmlParser = new XMLParser(xmlParserOptions);\n\n\tconst config: PhpStormPHPConfigNode[] = (() => {\n\t\ttry {\n\t\t\treturn xmlParser.parse(xmlContent, true);\n\t\t} catch {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm PHP configuration file is not valid XML.'\n\t\t\t);\n\t\t}\n\t})();\n\n\t// Find or create project element\n\tlet projectElement = config?.find(\n\t\t(c: PhpStormPHPConfigNode) => !!c?.project\n\t);\n\tif (projectElement) {\n\t\tconst projectVersion = projectElement[':@']?.version;\n\t\tif (projectVersion === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm IDE integration only supports ' +\n\t\t\t\t\t'<project version=\"4\"> in php.xml, ' +\n\t\t\t\t\t'but the <project> configuration has no version number.'\n\t\t\t);\n\t\t} else if (projectVersion !== '4') {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm IDE integration only supports ' +\n\t\t\t\t\t'<project version=\"4\"> in php.xml, ' +\n\t\t\t\t\t`but we found a <project> configuration ` +\n\t\t\t\t\t`with version \"${projectVersion}\".`\n\t\t\t);\n\t\t}\n\t}\n\tif (projectElement === undefined) {\n\t\tprojectElement = {\n\t\t\tproject: [],\n\t\t\t':@': { version: '4' },\n\t\t};\n\t\tconfig.push(projectElement);\n\t}\n\n\t// Find or create PhpStepFilterConfiguration component\n\tlet componentElement = projectElement.project?.find(\n\t\t(c: PhpStormPHPConfigNode) =>\n\t\t\t!!c?.component && c?.[':@']?.name === 'PhpStepFilterConfiguration'\n\t);\n\tif (componentElement === undefined) {\n\t\tcomponentElement = {\n\t\t\tcomponent: [],\n\t\t\t':@': { name: 'PhpStepFilterConfiguration' },\n\t\t};\n\n\t\tif (projectElement.project === undefined) {\n\t\t\tprojectElement.project = [];\n\t\t}\n\n\t\tprojectElement.project.push(componentElement);\n\t}\n\n\t// Find or create skipped_files element\n\tlet skippedFilesElement = componentElement.component?.find(\n\t\t(c: PhpStormPHPConfigNode) => !!c?.skipped_files\n\t);\n\tif (skippedFilesElement === undefined) {\n\t\tskippedFilesElement = { skipped_files: [] };\n\n\t\tif (componentElement.component === undefined) {\n\t\t\tcomponentElement.component = [];\n\t\t}\n\n\t\tcomponentElement.component.push(skippedFilesElement);\n\t}\n\n\t// Add skipped files\n\tif (pathSkippings && pathSkippings.length) {\n\t\tfor (const skippedPath of pathSkippings) {\n\t\t\tconst normalizedPath = skippedPath.endsWith('/')\n\t\t\t\t? skippedPath.slice(0, -1)\n\t\t\t\t: skippedPath;\n\t\t\tconst filePath = `$PROJECT_DIR$${normalizedPath}`;\n\n\t\t\t// Check if already exists\n\t\t\tconst exists = skippedFilesElement.skipped_files?.some(\n\t\t\t\t(c: PhpStormPHPConfigNode) =>\n\t\t\t\t\t!!c?.skipped_file && c?.[':@']?.file === filePath\n\t\t\t);\n\n\t\t\tif (!exists) {\n\t\t\t\tif (skippedFilesElement.skipped_files === undefined) {\n\t\t\t\t\tskippedFilesElement.skipped_files = [];\n\t\t\t\t}\n\n\t\t\t\tskippedFilesElement.skipped_files.push({\n\t\t\t\t\tskipped_file: [],\n\t\t\t\t\t':@': { file: filePath },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Build the updated XML\n\tconst xmlBuilder = new XMLBuilder(xmlBuilderOptions);\n\tconst xml = xmlBuilder.build(config);\n\n\t// Validate the generated XML\n\ttry {\n\t\txmlParser.parse(xml, true);\n\t} catch {\n\t\tthrow new Error(\n\t\t\t'The resulting PhpStorm PHP configuration file ' +\n\t\t\t\t'is not valid XML.'\n\t\t);\n\t}\n\n\treturn xml;\n}\n\nexport type VSCodeConfigOptions = {\n\tname: string;\n\tworkspaceDir: string;\n\tpathMappings?: Mount[];\n\tpathSkippings?: string[];\n};\n\n/**\n * Pure function to update VS Code JSON config with Xdebug configuration.\n *\n * @param jsonContent The original JSON content of launch.json\n * @param options Configuration options\n * @returns Updated JSON content\n * @throws Error if JSON is invalid\n */\nexport function updateVSCodeConfig(\n\tjsonContent: string,\n\toptions: VSCodeConfigOptions\n): string {\n\tconst { name, pathMappings, pathSkippings } = options;\n\n\tconst errors: JSONC.ParseError[] = [];\n\n\tlet content = jsonContent;\n\tlet root = JSONC.parseTree(content, errors, jsoncParseOptions);\n\n\tif (root === undefined || errors.length) {\n\t\tthrow new Error('VS Code configuration file is not valid JSON.');\n\t}\n\n\t// Find or create configurations array\n\tlet configurationsNode = JSONC.findNodeAtLocation(root, ['configurations']);\n\n\tif (\n\t\tconfigurationsNode === undefined ||\n\t\tconfigurationsNode.children === undefined\n\t) {\n\t\tconst edits = JSONC.modify(content, ['configurations'], [], {});\n\t\tcontent = JSONC.applyEdits(content, edits);\n\n\t\troot = JSONC.parseTree(content, [], jsoncParseOptions);\n\t\tconfigurationsNode = JSONC.findNodeAtLocation(root!, [\n\t\t\t'configurations',\n\t\t]);\n\t}\n\n\t// Check if configuration already exists\n\tconst configurationIndex = configurationsNode?.children?.findIndex(\n\t\t(child: any) =>\n\t\t\tJSONC.findNodeAtLocation(child, ['name'])?.value === name\n\t);\n\n\t// Only add configuration if it doesn't exist\n\tif (configurationIndex === undefined || configurationIndex < 0) {\n\t\tconst configuration: VSCodeConfigNode = {\n\t\t\tname: name,\n\t\t\ttype: 'php',\n\t\t\trequest: 'launch',\n\t\t\tport: 9003,\n\t\t};\n\n\t\tif (pathMappings && pathMappings.length) {\n\t\t\tconfiguration.pathMappings = pathMappings.reduce((acc, mount) => {\n\t\t\t\tacc[mount.vfsPath] = `\\${workspaceFolder}/${toPosixPath(\n\t\t\t\t\tpath.relative(options.workspaceDir, mount.hostPath)\n\t\t\t\t)}`;\n\t\t\t\treturn acc;\n\t\t\t}, {} as VSCodeConfigMetaData);\n\t\t}\n\n\t\tif (pathSkippings && pathSkippings.length) {\n\t\t\tconfiguration.skipFiles = pathSkippings.map((skippedPath) =>\n\t\t\t\tskippedPath.endsWith('/') ? `${skippedPath}**` : skippedPath\n\t\t\t);\n\t\t}\n\n\t\t// Get the current length to append at the end\n\t\tconst currentLength = configurationsNode?.children?.length || 0;\n\n\t\tconst edits = JSONC.modify(\n\t\t\tcontent,\n\t\t\t['configurations', currentLength],\n\t\t\tconfiguration,\n\t\t\t{\n\t\t\t\tformattingOptions: {\n\t\t\t\t\tinsertSpaces: true,\n\t\t\t\t\ttabSize: 4,\n\t\t\t\t\teol: '\\n',\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\n\t\tcontent = jsoncApplyEdits(content, edits);\n\t}\n\n\treturn content;\n}\n\n/**\n * Implement necessary parameters and path mappings in IDE configuration files.\n *\n * @param name The configuration name.\n * @param mounts The mounts options.\n */\nexport async function addXdebugIDEConfig({\n\tname,\n\tides,\n\thost,\n\tport,\n\tcwd,\n\tmounts,\n\tpathSkippings,\n\tideKey = DEFAULT_IDE_KEY,\n}: IDEConfig) {\n\tconst pathMappings = mounts ? filterLocalMounts(cwd, mounts) : [];\n\tconst modifiedConfig: Record<string, string> = {};\n\n\t// PHPstorm\n\tif (ides.includes('phpstorm')) {\n\t\tconst phpStormRelativeConfigFilePath = '.idea/workspace.xml';\n\t\tconst phpStormConfigFilePath = path.join(\n\t\t\tcwd,\n\t\t\tphpStormRelativeConfigFilePath\n\t\t);\n\n\t\t// Create a template config file if the IDE directory exists,\n\t\t// or throw an error if IDE integration is requested but the directory is missing.\n\t\tif (!fs.existsSync(phpStormConfigFilePath)) {\n\t\t\tif (fs.existsSync(path.dirname(phpStormConfigFilePath))) {\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tphpStormConfigFilePath,\n\t\t\t\t\t'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<project version=\"4\">\\n</project>'\n\t\t\t\t);\n\t\t\t} else if (ides.length == 1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`PhpStorm IDE integration requested, but no '.idea' directory was found in the current working directory.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (fs.existsSync(phpStormConfigFilePath)) {\n\t\t\tconst contents = fs.readFileSync(phpStormConfigFilePath, 'utf8');\n\t\t\tconst updatedXml = updatePhpStormWorkspaceConfig(contents, {\n\t\t\t\tname,\n\t\t\t\thost,\n\t\t\t\tport,\n\t\t\t\tprojectDir: cwd,\n\t\t\t\tpathMappings,\n\t\t\t\tideKey,\n\t\t\t});\n\t\t\tfs.writeFileSync(phpStormConfigFilePath, updatedXml);\n\t\t\tmodifiedConfig['phpstorm'] = phpStormRelativeConfigFilePath;\n\t\t}\n\n\t\t// PhpStorm php.xml (path skippings)\n\t\tif (pathSkippings && pathSkippings.length) {\n\t\t\tconst phpStormRelativePHPConfigFilePath = '.idea/php.xml';\n\t\t\tconst phpStormPHPConfigFilePath = path.join(\n\t\t\t\tcwd,\n\t\t\t\tphpStormRelativePHPConfigFilePath\n\t\t\t);\n\n\t\t\tif (!fs.existsSync(phpStormPHPConfigFilePath)) {\n\t\t\t\tif (fs.existsSync(path.dirname(phpStormPHPConfigFilePath))) {\n\t\t\t\t\tfs.writeFileSync(\n\t\t\t\t\t\tphpStormPHPConfigFilePath,\n\t\t\t\t\t\t'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<project version=\"4\">\\n</project>'\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (fs.existsSync(phpStormPHPConfigFilePath)) {\n\t\t\t\tconst contents = fs.readFileSync(\n\t\t\t\t\tphpStormPHPConfigFilePath,\n\t\t\t\t\t'utf8'\n\t\t\t\t);\n\t\t\t\tconst updatedXml = updatePhpStormPHPConfig(contents, {\n\t\t\t\t\tpathSkippings,\n\t\t\t\t});\n\t\t\t\tfs.writeFileSync(phpStormPHPConfigFilePath, updatedXml);\n\t\t\t\tmodifiedConfig['phpstorm-php'] =\n\t\t\t\t\tphpStormRelativePHPConfigFilePath;\n\t\t\t}\n\t\t}\n\t}\n\n\t// VSCode\n\tif (ides.includes('vscode')) {\n\t\tconst vsCodeRelativeConfigFilePath = '.vscode/launch.json';\n\t\tconst vsCodeConfigFilePath = path.join(\n\t\t\tcwd,\n\t\t\tvsCodeRelativeConfigFilePath\n\t\t);\n\n\t\t// Create a template config file if the IDE directory exists,\n\t\t// or throw an error if IDE integration is requested but the directory is missing.\n\t\tif (!fs.existsSync(vsCodeConfigFilePath)) {\n\t\t\tif (fs.existsSync(path.dirname(vsCodeConfigFilePath))) {\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tvsCodeConfigFilePath,\n\t\t\t\t\t'{\\n \"configurations\": []\\n}'\n\t\t\t\t);\n\t\t\t} else if (ides.length == 1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`VS Code IDE integration requested, but no '.vscode' directory was found in the current working directory.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (fs.existsSync(vsCodeConfigFilePath)) {\n\t\t\tconst content = fs.readFileSync(vsCodeConfigFilePath, 'utf-8');\n\t\t\tconst updatedJson = updateVSCodeConfig(content, {\n\t\t\t\tname,\n\t\t\t\tworkspaceDir: cwd,\n\t\t\t\tpathMappings,\n\t\t\t\tpathSkippings,\n\t\t\t});\n\n\t\t\t// Only write and track the file if changes were made\n\t\t\tif (updatedJson !== content) {\n\t\t\t\tfs.writeFileSync(vsCodeConfigFilePath, updatedJson);\n\t\t\t\tmodifiedConfig['vscode'] = vsCodeRelativeConfigFilePath;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn modifiedConfig;\n}\n\n/**\n * Remove stale parameters and path mappings in IDE configuration files.\n *\n * @param name The configuration name.\n * @param cwd The current working directory.\n */\nexport async function clearXdebugIDEConfig(name: string, cwd: string) {\n\tconst phpStormConfigFilePath = path.join(cwd, '.idea/workspace.xml');\n\t// PhpStorm\n\tif (fs.existsSync(phpStormConfigFilePath)) {\n\t\tconst contents = fs.readFileSync(phpStormConfigFilePath, 'utf8');\n\t\tconst xmlParser = new XMLParser(xmlParserOptions);\n\t\t// NOTE: Using an IIFE so `config` can remain const.\n\t\tconst config: PhpStormWorkspaceConfigNode[] = (() => {\n\t\t\ttry {\n\t\t\t\treturn xmlParser.parse(contents, true);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'PhpStorm configuration file is not valid XML.'\n\t\t\t\t);\n\t\t\t}\n\t\t})();\n\n\t\tconst projectElement = config.find(\n\t\t\t(c: PhpStormWorkspaceConfigNode) => !!c?.project\n\t\t);\n\t\tconst componentElement = projectElement?.project?.find(\n\t\t\t(c: PhpStormWorkspaceConfigNode) =>\n\t\t\t\t!!c?.component && c?.[':@']?.name === 'PhpServers'\n\t\t);\n\t\tconst serversElement = componentElement?.component?.find(\n\t\t\t(c: PhpStormWorkspaceConfigNode) => !!c?.servers\n\t\t);\n\t\tconst serverElementIndex = serversElement?.servers?.findIndex(\n\t\t\t(c: PhpStormWorkspaceConfigNode) =>\n\t\t\t\t!!c?.server && c?.[':@']?.name === name\n\t\t);\n\n\t\tif (serverElementIndex !== undefined && serverElementIndex >= 0) {\n\t\t\tserversElement!.servers!.splice(serverElementIndex, 1);\n\n\t\t\tconst xmlBuilder = new XMLBuilder(xmlBuilderOptions);\n\t\t\tconst xml = xmlBuilder.build(config);\n\n\t\t\ttry {\n\t\t\t\txmlParser.parse(xml, true);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'The resulting PhpStorm configuration file is not valid XML.'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\txml ===\n\t\t\t\t'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<project version=\"4\">\\n\t<component name=\"PhpServers\">\\n\t\t<servers></servers>\\n\t</component>\\n</project>'\n\t\t\t) {\n\t\t\t\tfs.unlinkSync(phpStormConfigFilePath);\n\t\t\t} else {\n\t\t\t\tfs.writeFileSync(phpStormConfigFilePath, xml);\n\t\t\t}\n\t\t}\n\t}\n\n\t// PhpStorm php.xml (path skippings)\n\tconst phpStormPHPConfigFilePath = path.join(cwd, '.idea/php.xml');\n\tif (fs.existsSync(phpStormPHPConfigFilePath)) {\n\t\tconst contents = fs.readFileSync(phpStormPHPConfigFilePath, 'utf8');\n\t\tconst xmlParser = new XMLParser(xmlParserOptions);\n\t\tconst config: PhpStormPHPConfigNode[] = (() => {\n\t\t\ttry {\n\t\t\t\treturn xmlParser.parse(contents, true);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'PhpStorm PHP configuration file is not valid XML.'\n\t\t\t\t);\n\t\t\t}\n\t\t})();\n\n\t\tconst projectElement = config.find(\n\t\t\t(c: PhpStormPHPConfigNode) => !!c?.project\n\t\t);\n\t\tconst componentIndex = projectElement?.project?.findIndex(\n\t\t\t(c: PhpStormPHPConfigNode) =>\n\t\t\t\t!!c?.component &&\n\t\t\t\tc?.[':@']?.name === 'PhpStepFilterConfiguration'\n\t\t);\n\n\t\tif (componentIndex !== undefined && componentIndex >= 0) {\n\t\t\tprojectElement!.project!.splice(componentIndex, 1);\n\n\t\t\tconst xmlBuilder = new XMLBuilder(xmlBuilderOptions);\n\t\t\tconst xml = xmlBuilder.build(config);\n\n\t\t\ttry {\n\t\t\t\txmlParser.parse(xml, true);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'The resulting PhpStorm PHP configuration file ' +\n\t\t\t\t\t\t'is not valid XML.'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\txml ===\n\t\t\t\t'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<project version=\"4\">\\n</project>'\n\t\t\t) {\n\t\t\t\tfs.unlinkSync(phpStormPHPConfigFilePath);\n\t\t\t} else {\n\t\t\t\tfs.writeFileSync(phpStormPHPConfigFilePath, xml);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst vsCodeConfigFilePath = path.join(cwd, '.vscode/launch.json');\n\t// VSCode\n\tif (fs.existsSync(vsCodeConfigFilePath)) {\n\t\tconst errors: JSONC.ParseError[] = [];\n\n\t\tconst content = fs.readFileSync(vsCodeConfigFilePath, 'utf-8');\n\t\tconst root = JSONC.parseTree(content, errors, jsoncParseOptions);\n\n\t\tif (root === undefined || errors.length) {\n\t\t\tthrow new Error('VS Code configuration file is not valid JSON.');\n\t\t}\n\n\t\tconst configurationsNode = JSONC.findNodeAtLocation(root, [\n\t\t\t'configurations',\n\t\t]);\n\n\t\tconst configurationIndex = configurationsNode?.children?.findIndex(\n\t\t\t(child: any) =>\n\t\t\t\tJSONC.findNodeAtLocation(child, ['name'])?.value === name\n\t\t);\n\n\t\tif (configurationIndex !== undefined && configurationIndex >= 0) {\n\t\t\tconst edits = JSONC.modify(\n\t\t\t\tcontent,\n\t\t\t\t['configurations', configurationIndex],\n\t\t\t\tundefined,\n\t\t\t\t{\n\t\t\t\t\tformattingOptions: {\n\t\t\t\t\t\tinsertSpaces: true,\n\t\t\t\t\t\ttabSize: 4,\n\t\t\t\t\t\teol: '\\n',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tconst json = jsoncApplyEdits(content, edits);\n\t\t\tif (json === '{\\n \"configurations\": []\\n}') {\n\t\t\t\tfs.unlinkSync(vsCodeConfigFilePath);\n\t\t\t} else {\n\t\t\t\tfs.writeFileSync(vsCodeConfigFilePath, json);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Implement path mapping and path skipping in Xdebug.\n *\n * @param name The configuration name.\n * @param mounts The mounts options.\n * @param pathSkippings The skipping paths options.\n * @returns Xdebug options\n */\nexport function makeXdebugConfig({\n\tcwd,\n\tmounts,\n\tpathSkippings,\n}: XdebugConfig): XdebugOptions {\n\tconst pathMappings =\n\t\tcwd && mounts ? filterLocalMounts(cwd, mounts) : undefined;\n\n\treturn { pathMappings, pathSkippings };\n}\n\nfunction jsoncApplyEdits(content: string, edits: JSONC.Edit[]) {\n\tconst errors: JSONC.ParseError[] = [];\n\tconst json = JSONC.applyEdits(content, edits);\n\n\terrors.length = 0;\n\n\tJSONC.parseTree(json, errors, jsoncParseOptions);\n\n\tif (errors.length) {\n\t\tconst formattedErrors = errors\n\t\t\t.map((error) => {\n\t\t\t\treturn {\n\t\t\t\t\tmessage: JSONC.printParseErrorCode(error.error),\n\t\t\t\t\toffset: error.offset,\n\t\t\t\t\tlength: error.length,\n\t\t\t\t\tfragment: json.slice(\n\t\t\t\t\t\tMath.max(0, error.offset - 20),\n\t\t\t\t\t\tMath.min(json.length, error.offset + error.length + 10)\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t})\n\t\t\t.map(\n\t\t\t\t(error) =>\n\t\t\t\t\t`${error.message} at ${error.offset}:${error.length} (${error.fragment})`\n\t\t\t);\n\t\tconst formattedEdits = edits.map(\n\t\t\t(edit) => `At ${edit.offset}:${edit.length} - (${edit.content})`\n\t\t);\n\t\tthrow new Error(\n\t\t\t`VS Code configuration file (.vscode/launch.json) is not valid a JSONC after CLI modifications. This is likely ` +\n\t\t\t\t`a CLI bug. Please report it at https://github.com/WordPress/wordpress-playground/issues and include the contents ` +\n\t\t\t\t`of your \".vscode/launch.json\" file. \\n\\n Applied edits: ${formattedEdits.join(\n\t\t\t\t\t'\\n'\n\t\t\t\t)}\\n\\n The errors are: ${formattedErrors.join('\\n')}`\n\t\t);\n\t}\n\n\treturn json;\n}\n"],"names":["DEFAULT_IDE_KEY","DEFAULT_PATH_SKIPPINGS","createTempDirSymlink","nativeDirPath","symlinkPath","platform","type","fs","removeTempDirSymlink","filterLocalMounts","cwd","mounts","mount","absoluteHostPath","path","cwdChildPrefix","xmlParserOptions","xmlBuilderOptions","jsoncParseOptions","updatePhpStormWorkspaceConfig","xmlContent","options","name","host","port","pathMappings","ideKey","xmlParser","XMLParser","config","serverElement","pathMapping","toPosixPath","projectElement","c","projectVersion","_a","componentElement","_b","serversElement","_c","serverElementIndex","_d","runManagerElement","_e","_f","runConfigElement","xml","XMLBuilder","updatePhpStormPHPConfig","pathSkippings","skippedFilesElement","skippedPath","filePath","updateVSCodeConfig","jsonContent","errors","content","root","JSONC","configurationsNode","edits","configurationIndex","child","configuration","acc","currentLength","jsoncApplyEdits","addXdebugIDEConfig","ides","modifiedConfig","phpStormRelativeConfigFilePath","phpStormConfigFilePath","contents","updatedXml","phpStormRelativePHPConfigFilePath","phpStormPHPConfigFilePath","vsCodeRelativeConfigFilePath","vsCodeConfigFilePath","updatedJson","clearXdebugIDEConfig","componentIndex","json","makeXdebugConfig","formattedErrors","error","formattedEdits","edit"],"mappings":"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"}
+343
-209

@@ -1,9 +0,15 @@

import f from "fs";
import P from "path";
import { toPosixPath as D } from "@php-wasm/util";
import { XMLParser as T, XMLBuilder as $ } from "fast-xml-parser";
import * as v from "jsonc-parser";
const O = "PHPWASMCLI";
async function q(c, a, r) {
const p = r === "win32" ? (
import a from "fs";
import w from "path";
import { toPosixPath as $ } from "@php-wasm/util";
import { XMLParser as F, XMLBuilder as b } from "fast-xml-parser";
import * as x from "jsonc-parser";
const N = "PHPWASMCLI", U = [
"/dev/",
"/home/",
"/internal/",
"/request/",
"/proc/"
];
async function W(u, f, l) {
const d = l === "win32" ? (
// On Windows, creating a 'dir' symlink can require elevated permissions.

@@ -14,21 +20,21 @@ // In this case, let's make junction points because they function like

) : "dir";
f.symlinkSync(c, a, p);
a.symlinkSync(u, f, d);
}
async function H(c) {
async function q(u) {
try {
f.lstatSync(c).isSymbolicLink() && f.unlinkSync(c);
a.lstatSync(u).isSymbolicLink() && a.unlinkSync(u);
} catch {
}
}
function A(c, a) {
return a.filter((r) => {
const p = P.resolve(r.hostPath), h = P.join(c, P.sep);
function D(u, f) {
return f.filter((l) => {
const d = w.resolve(l.hostPath), c = w.join(u, w.sep);
return (
// If auto-mounting from the current directory,
// the entire project directory can be mapped.
p === c || p.startsWith(h)
d === u || d.startsWith(c)
);
});
}
const x = {
const E = {
ignoreAttributes: !1,

@@ -41,63 +47,67 @@ attributeNamePrefix: "",

trimValues: !0
}, M = {
ignoreAttributes: x.ignoreAttributes,
attributeNamePrefix: x.attributeNamePrefix,
preserveOrder: x.preserveOrder,
cdataPropName: x.cdataPropName,
commentPropName: x.commentPropName,
suppressBooleanAttributes: !x.allowBooleanAttributes,
}, I = {
ignoreAttributes: E.ignoreAttributes,
attributeNamePrefix: E.attributeNamePrefix,
preserveOrder: E.preserveOrder,
cdataPropName: E.cdataPropName,
commentPropName: E.commentPropName,
suppressBooleanAttributes: !E.allowBooleanAttributes,
format: !0,
indentBy: " "
}, j = {
}, k = {
allowEmptyContent: !0,
allowTrailingComma: !0
};
function _(c, a) {
var E, b, I, F, L, k;
const { name: r, host: p, port: h, mappings: l, ideKey: t } = a, m = new T(x), g = (() => {
function X(u, f) {
var S, C, L, T, _, M;
const { name: l, host: d, port: c, pathMappings: h, ideKey: t } = f, P = new F(E), v = (() => {
try {
return m.parse(c, !0);
return P.parse(u, !0);
} catch {
throw new Error("PhpStorm configuration file is not valid XML.");
}
})(), u = {
})(), y = {
server: [{}],
":@": {
name: r,
name: l,
// NOTE: PhpStorm quirk: Xdebug only works when the full URL (including port)
// is provided in `host`. The separate `port` field is ignored or misinterpreted,
// so we rely solely on host: "host:port".
host: `${p}:${h}`,
host: `${d}:${c}`,
use_path_mappings: "true"
}
};
l && l.length && (u.server[0].path_mappings = l.map((e) => ({
mapping: [],
":@": {
"local-root": `$PROJECT_DIR$/${D(
P.relative(a.projectDir, e.hostPath)
)}`,
"remote-root": e.vfsPath
}
})));
let n = g == null ? void 0 : g.find((e) => !!(e != null && e.project));
if (n) {
const e = (E = n[":@"]) == null ? void 0 : E.version;
if (e === void 0)
h && h.length && (y.server[0].path_mappings = h.map(
(n) => ({
mapping: [],
":@": {
"local-root": `$PROJECT_DIR$/${$(
w.relative(f.projectDir, n.hostPath)
)}`,
"remote-root": n.vfsPath
}
})
));
let p = v == null ? void 0 : v.find(
(n) => !!(n != null && n.project)
);
if (p) {
const n = (S = p[":@"]) == null ? void 0 : S.version;
if (n === void 0)
throw new Error(
'PhpStorm IDE integration only supports <project version="4"> in workspace.xml, but the <project> configuration has no version number.'
);
if (e !== "4")
if (n !== "4")
throw new Error(
`PhpStorm IDE integration only supports <project version="4"> in workspace.xml, but we found a <project> configuration with version "${e}".`
`PhpStorm IDE integration only supports <project version="4"> in workspace.xml, but we found a <project> configuration with version "${n}".`
);
}
n === void 0 && (n = {
p === void 0 && (p = {
project: [],
":@": { version: "4" }
}, g.push(n));
let o = (b = n.project) == null ? void 0 : b.find(
(e) => {
var S;
return !!(e != null && e.component) && ((S = e == null ? void 0 : e[":@"]) == null ? void 0 : S.name) === "PhpServers";
}, v.push(p));
let o = (C = p.project) == null ? void 0 : C.find(
(n) => {
var j;
return !!(n != null && n.component) && ((j = n == null ? void 0 : n[":@"]) == null ? void 0 : j.name) === "PhpServers";
}

@@ -108,30 +118,30 @@ );

":@": { name: "PhpServers" }
}, n.project === void 0 && (n.project = []), n.project.push(o));
let s = (I = o.component) == null ? void 0 : I.find(
(e) => !!(e != null && e.servers)
}, p.project === void 0 && (p.project = []), p.project.push(o));
let i = (L = o.component) == null ? void 0 : L.find(
(n) => !!(n != null && n.servers)
);
s === void 0 && (s = { servers: [] }, o.component === void 0 && (o.component = []), o.component.push(s));
const y = (F = s.servers) == null ? void 0 : F.findIndex(
(e) => {
var S;
return !!(e != null && e.server) && ((S = e == null ? void 0 : e[":@"]) == null ? void 0 : S.name) === r;
i === void 0 && (i = { servers: [] }, o.component === void 0 && (o.component = []), o.component.push(i));
const r = (T = i.servers) == null ? void 0 : T.findIndex(
(n) => {
var j;
return !!(n != null && n.server) && ((j = n == null ? void 0 : n[":@"]) == null ? void 0 : j.name) === l;
}
);
(y === void 0 || y < 0) && (s.servers === void 0 && (s.servers = []), s.servers.push(u));
let d = (L = n.project) == null ? void 0 : L.find(
(e) => {
var S;
return !!(e != null && e.component) && ((S = e == null ? void 0 : e[":@"]) == null ? void 0 : S.name) === "RunManager";
(r === void 0 || r < 0) && (i.servers === void 0 && (i.servers = []), i.servers.push(y));
let e = (_ = p.project) == null ? void 0 : _.find(
(n) => {
var j;
return !!(n != null && n.component) && ((j = n == null ? void 0 : n[":@"]) == null ? void 0 : j.name) === "RunManager";
}
);
if (d === void 0 && (d = {
if (e === void 0 && (e = {
component: [],
":@": { name: "RunManager" }
}, n.project === void 0 && (n.project = []), n.project.push(d)), (((k = d.component) == null ? void 0 : k.findIndex(
(e) => {
var S;
return !!(e != null && e.configuration) && ((S = e == null ? void 0 : e[":@"]) == null ? void 0 : S.name) === r;
}, p.project === void 0 && (p.project = []), p.project.push(e)), (((M = e.component) == null ? void 0 : M.findIndex(
(n) => {
var j;
return !!(n != null && n.configuration) && ((j = n == null ? void 0 : n[":@"]) == null ? void 0 : j.name) === l;
}
)) ?? -1) < 0) {
const e = {
const n = {
configuration: [

@@ -144,15 +154,15 @@ {

":@": {
name: r,
name: l,
type: "PhpRemoteDebugRunConfigurationType",
factoryName: "PHP Remote Debug",
filter_connections: "FILTER",
server_name: r,
server_name: l,
session_id: t
}
};
d.component === void 0 && (d.component = []), d.component.push(e);
e.component === void 0 && (e.component = []), e.component.push(n);
}
const C = new $(M).build(g);
const m = new b(I).build(v);
try {
m.parse(C, !0);
P.parse(m, !0);
} catch {

@@ -163,26 +173,91 @@ throw new Error(

}
return C;
return m;
}
function B(c, a) {
var u, n;
const { name: r, mappings: p } = a, h = [];
let l = c, t = v.parseTree(l, h, j);
if (t === void 0 || h.length)
function B(u, f) {
var p, o, i, r;
const { pathSkippings: l } = f, d = new F(E), c = (() => {
try {
return d.parse(u, !0);
} catch {
throw new Error(
"PhpStorm PHP configuration file is not valid XML."
);
}
})();
let h = c == null ? void 0 : c.find(
(e) => !!(e != null && e.project)
);
if (h) {
const e = (p = h[":@"]) == null ? void 0 : p.version;
if (e === void 0)
throw new Error(
'PhpStorm IDE integration only supports <project version="4"> in php.xml, but the <project> configuration has no version number.'
);
if (e !== "4")
throw new Error(
`PhpStorm IDE integration only supports <project version="4"> in php.xml, but we found a <project> configuration with version "${e}".`
);
}
h === void 0 && (h = {
project: [],
":@": { version: "4" }
}, c.push(h));
let t = (o = h.project) == null ? void 0 : o.find(
(e) => {
var s;
return !!(e != null && e.component) && ((s = e == null ? void 0 : e[":@"]) == null ? void 0 : s.name) === "PhpStepFilterConfiguration";
}
);
t === void 0 && (t = {
component: [],
":@": { name: "PhpStepFilterConfiguration" }
}, h.project === void 0 && (h.project = []), h.project.push(t));
let P = (i = t.component) == null ? void 0 : i.find(
(e) => !!(e != null && e.skipped_files)
);
if (P === void 0 && (P = { skipped_files: [] }, t.component === void 0 && (t.component = []), t.component.push(P)), l && l.length)
for (const e of l) {
const g = `$PROJECT_DIR$${e.endsWith("/") ? e.slice(0, -1) : e}`;
((r = P.skipped_files) == null ? void 0 : r.some(
(S) => {
var C;
return !!(S != null && S.skipped_file) && ((C = S == null ? void 0 : S[":@"]) == null ? void 0 : C.file) === g;
}
)) || (P.skipped_files === void 0 && (P.skipped_files = []), P.skipped_files.push({
skipped_file: [],
":@": { file: g }
}));
}
const y = new b(I).build(c);
try {
d.parse(y, !0);
} catch {
throw new Error(
"The resulting PhpStorm PHP configuration file is not valid XML."
);
}
return y;
}
function O(u, f) {
var p, o;
const { name: l, pathMappings: d, pathSkippings: c } = f, h = [];
let t = u, P = x.parseTree(t, h, k);
if (P === void 0 || h.length)
throw new Error("VS Code configuration file is not valid JSON.");
let m = v.findNodeAtLocation(t, ["configurations"]);
if (m === void 0 || m.children === void 0) {
const o = v.modify(l, ["configurations"], [], {});
l = v.applyEdits(l, o), t = v.parseTree(l, [], j), m = v.findNodeAtLocation(t, [
let v = x.findNodeAtLocation(P, ["configurations"]);
if (v === void 0 || v.children === void 0) {
const i = x.modify(t, ["configurations"], [], {});
t = x.applyEdits(t, i), P = x.parseTree(t, [], k), v = x.findNodeAtLocation(P, [
"configurations"
]);
}
const g = (u = m == null ? void 0 : m.children) == null ? void 0 : u.findIndex(
(o) => {
var s;
return ((s = v.findNodeAtLocation(o, ["name"])) == null ? void 0 : s.value) === r;
const y = (p = v == null ? void 0 : v.children) == null ? void 0 : p.findIndex(
(i) => {
var r;
return ((r = x.findNodeAtLocation(i, ["name"])) == null ? void 0 : r.value) === l;
}
);
if (g === void 0 || g < 0) {
const o = {
name: r,
if (y === void 0 || y < 0) {
const i = {
name: l,
type: "php",

@@ -192,9 +267,11 @@ request: "launch",

};
p && p.length && (o.pathMappings = p.reduce((d, i) => (d[i.vfsPath] = `\${workspaceFolder}/${D(
P.relative(a.workspaceDir, i.hostPath)
)}`, d), {}));
const s = ((n = m == null ? void 0 : m.children) == null ? void 0 : n.length) || 0, y = v.modify(
l,
["configurations", s],
o,
d && d.length && (i.pathMappings = d.reduce((s, g) => (s[g.vfsPath] = `\${workspaceFolder}/${$(
w.relative(f.workspaceDir, g.hostPath)
)}`, s), {})), c && c.length && (i.skipFiles = c.map(
(s) => s.endsWith("/") ? `${s}**` : s
));
const r = ((o = v == null ? void 0 : v.children) == null ? void 0 : o.length) || 0, e = x.modify(
t,
["configurations", r],
i,
{

@@ -209,25 +286,26 @@ formattingOptions: {

);
l = N(l, y);
t = A(t, e);
}
return l;
return t;
}
async function U({
name: c,
ides: a,
host: r,
port: p,
cwd: h,
mounts: l,
ideKey: t = O
async function z({
name: u,
ides: f,
host: l,
port: d,
cwd: c,
mounts: h,
pathSkippings: t,
ideKey: P = N
}) {
const m = l ? A(h, l) : [], g = {};
if (a.includes("phpstorm")) {
const u = ".idea/workspace.xml", n = P.join(
h,
u
const v = h ? D(c, h) : [], y = {};
if (f.includes("phpstorm")) {
const p = ".idea/workspace.xml", o = w.join(
c,
p
);
if (!f.existsSync(n)) {
if (f.existsSync(P.dirname(n)))
f.writeFileSync(
n,
if (!a.existsSync(o)) {
if (a.existsSync(w.dirname(o)))
a.writeFileSync(
o,
`<?xml version="1.0" encoding="UTF-8"?>

@@ -237,3 +315,3 @@ <project version="4">

);
else if (a.length == 1)
else if (f.length == 1)
throw new Error(

@@ -243,23 +321,43 @@ "PhpStorm IDE integration requested, but no '.idea' directory was found in the current working directory."

}
if (f.existsSync(n)) {
const o = f.readFileSync(n, "utf8"), s = _(o, {
name: c,
host: r,
port: p,
projectDir: h,
mappings: m,
ideKey: t
if (a.existsSync(o)) {
const i = a.readFileSync(o, "utf8"), r = X(i, {
name: u,
host: l,
port: d,
projectDir: c,
pathMappings: v,
ideKey: P
});
f.writeFileSync(n, s), g.phpstorm = u;
a.writeFileSync(o, r), y.phpstorm = p;
}
if (t && t.length) {
const i = ".idea/php.xml", r = w.join(
c,
i
);
if (a.existsSync(r) || a.existsSync(w.dirname(r)) && a.writeFileSync(
r,
`<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
</project>`
), a.existsSync(r)) {
const e = a.readFileSync(
r,
"utf8"
), s = B(e, {
pathSkippings: t
});
a.writeFileSync(r, s), y["phpstorm-php"] = i;
}
}
}
if (a.includes("vscode")) {
const u = ".vscode/launch.json", n = P.join(
h,
u
if (f.includes("vscode")) {
const p = ".vscode/launch.json", o = w.join(
c,
p
);
if (!f.existsSync(n)) {
if (f.existsSync(P.dirname(n)))
f.writeFileSync(
n,
if (!a.existsSync(o)) {
if (a.existsSync(w.dirname(o)))
a.writeFileSync(
o,
`{

@@ -269,3 +367,3 @@ "configurations": []

);
else if (a.length == 1)
else if (f.length == 1)
throw new Error(

@@ -275,20 +373,21 @@ "VS Code IDE integration requested, but no '.vscode' directory was found in the current working directory."

}
if (f.existsSync(n)) {
const o = f.readFileSync(n, "utf-8"), s = B(o, {
name: c,
workspaceDir: h,
mappings: m
if (a.existsSync(o)) {
const i = a.readFileSync(o, "utf-8"), r = O(i, {
name: u,
workspaceDir: c,
pathMappings: v,
pathSkippings: t
});
s !== o && (f.writeFileSync(n, s), g.vscode = u);
r !== i && (a.writeFileSync(o, r), y.vscode = p);
}
}
return g;
return y;
}
async function W(c, a) {
var h, l, t, m;
const r = P.join(a, ".idea/workspace.xml");
if (f.existsSync(r)) {
const g = f.readFileSync(r, "utf8"), u = new T(x), n = (() => {
async function K(u, f) {
var h, t, P, v, y;
const l = w.join(f, ".idea/workspace.xml");
if (a.existsSync(l)) {
const p = a.readFileSync(l, "utf8"), o = new F(E), i = (() => {
try {
return u.parse(g, !0);
return o.parse(p, !0);
} catch {

@@ -299,22 +398,22 @@ throw new Error(

}
})(), o = n.find(
(i) => !!(i != null && i.project)
), s = (h = o == null ? void 0 : o.project) == null ? void 0 : h.find(
(i) => {
var w;
return !!(i != null && i.component) && ((w = i == null ? void 0 : i[":@"]) == null ? void 0 : w.name) === "PhpServers";
})(), r = i.find(
(m) => !!(m != null && m.project)
), e = (h = r == null ? void 0 : r.project) == null ? void 0 : h.find(
(m) => {
var S;
return !!(m != null && m.component) && ((S = m == null ? void 0 : m[":@"]) == null ? void 0 : S.name) === "PhpServers";
}
), y = (l = s == null ? void 0 : s.component) == null ? void 0 : l.find(
(i) => !!(i != null && i.servers)
), d = (t = y == null ? void 0 : y.servers) == null ? void 0 : t.findIndex(
(i) => {
var w;
return !!(i != null && i.server) && ((w = i == null ? void 0 : i[":@"]) == null ? void 0 : w.name) === c;
), s = (t = e == null ? void 0 : e.component) == null ? void 0 : t.find(
(m) => !!(m != null && m.servers)
), g = (P = s == null ? void 0 : s.servers) == null ? void 0 : P.findIndex(
(m) => {
var S;
return !!(m != null && m.server) && ((S = m == null ? void 0 : m[":@"]) == null ? void 0 : S.name) === u;
}
);
if (d !== void 0 && d >= 0) {
y.servers.splice(d, 1);
const w = new $(M).build(n);
if (g !== void 0 && g >= 0) {
s.servers.splice(g, 1);
const S = new b(I).build(i);
try {
u.parse(w, !0);
o.parse(S, !0);
} catch {

@@ -325,3 +424,3 @@ throw new Error(

}
w === `<?xml version="1.0" encoding="UTF-8"?>
S === `<?xml version="1.0" encoding="UTF-8"?>
<project version="4">

@@ -331,22 +430,55 @@ <component name="PhpServers">

</component>
</project>` ? f.unlinkSync(r) : f.writeFileSync(r, w);
</project>` ? a.unlinkSync(l) : a.writeFileSync(l, S);
}
}
const p = P.join(a, ".vscode/launch.json");
if (f.existsSync(p)) {
const g = [], u = f.readFileSync(p, "utf-8"), n = v.parseTree(u, g, j);
if (n === void 0 || g.length)
const d = w.join(f, ".idea/php.xml");
if (a.existsSync(d)) {
const p = a.readFileSync(d, "utf8"), o = new F(E), i = (() => {
try {
return o.parse(p, !0);
} catch {
throw new Error(
"PhpStorm PHP configuration file is not valid XML."
);
}
})(), r = i.find(
(s) => !!(s != null && s.project)
), e = (v = r == null ? void 0 : r.project) == null ? void 0 : v.findIndex(
(s) => {
var g;
return !!(s != null && s.component) && ((g = s == null ? void 0 : s[":@"]) == null ? void 0 : g.name) === "PhpStepFilterConfiguration";
}
);
if (e !== void 0 && e >= 0) {
r.project.splice(e, 1);
const g = new b(I).build(i);
try {
o.parse(g, !0);
} catch {
throw new Error(
"The resulting PhpStorm PHP configuration file is not valid XML."
);
}
g === `<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
</project>` ? a.unlinkSync(d) : a.writeFileSync(d, g);
}
}
const c = w.join(f, ".vscode/launch.json");
if (a.existsSync(c)) {
const p = [], o = a.readFileSync(c, "utf-8"), i = x.parseTree(o, p, k);
if (i === void 0 || p.length)
throw new Error("VS Code configuration file is not valid JSON.");
const o = v.findNodeAtLocation(n, [
const r = x.findNodeAtLocation(i, [
"configurations"
]), s = (m = o == null ? void 0 : o.children) == null ? void 0 : m.findIndex(
(y) => {
var d;
return ((d = v.findNodeAtLocation(y, ["name"])) == null ? void 0 : d.value) === c;
]), e = (y = r == null ? void 0 : r.children) == null ? void 0 : y.findIndex(
(s) => {
var g;
return ((g = x.findNodeAtLocation(s, ["name"])) == null ? void 0 : g.value) === u;
}
);
if (s !== void 0 && s >= 0) {
const y = v.modify(
u,
["configurations", s],
if (e !== void 0 && e >= 0) {
const s = x.modify(
o,
["configurations", e],
void 0,

@@ -361,30 +493,30 @@ {

}
), d = N(u, y);
d === `{
), g = A(o, s);
g === `{
"configurations": []
}` ? f.unlinkSync(p) : f.writeFileSync(p, d);
}` ? a.unlinkSync(c) : a.writeFileSync(c, g);
}
}
}
function z({
cwd: c,
mounts: a,
pathSkippings: r
function G({
cwd: u,
mounts: f,
pathSkippings: l
}) {
return { pathMappings: c && a ? A(c, a) : void 0, pathSkippings: r };
return { pathMappings: u && f ? D(u, f) : void 0, pathSkippings: l };
}
function N(c, a) {
const r = [], p = v.applyEdits(c, a);
if (r.length = 0, v.parseTree(p, r, j), r.length) {
const h = r.map((t) => ({
message: v.printParseErrorCode(t.error),
function A(u, f) {
const l = [], d = x.applyEdits(u, f);
if (l.length = 0, x.parseTree(d, l, k), l.length) {
const c = l.map((t) => ({
message: x.printParseErrorCode(t.error),
offset: t.offset,
length: t.length,
fragment: p.slice(
fragment: d.slice(
Math.max(0, t.offset - 20),
Math.min(p.length, t.offset + t.length + 10)
Math.min(d.length, t.offset + t.length + 10)
)
})).map(
(t) => `${t.message} at ${t.offset}:${t.length} (${t.fragment})`
), l = a.map(
), h = f.map(
(t) => `At ${t.offset}:${t.length} - (${t.content})`

@@ -395,3 +527,3 @@ );

Applied edits: ${l.join(
Applied edits: ${h.join(
`

@@ -401,18 +533,20 @@ `

The errors are: ${h.join(`
The errors are: ${c.join(`
`)}`
);
}
return p;
return d;
}
export {
O as DEFAULT_IDE_KEY,
U as addXdebugIDEConfig,
W as clearXdebugIDEConfig,
q as createTempDirSymlink,
z as makeXdebugConfig,
H as removeTempDirSymlink,
_ as updatePhpStormConfig,
B as updateVSCodeConfig
N as DEFAULT_IDE_KEY,
U as DEFAULT_PATH_SKIPPINGS,
z as addXdebugIDEConfig,
K as clearXdebugIDEConfig,
W as createTempDirSymlink,
G as makeXdebugConfig,
q as removeTempDirSymlink,
B as updatePhpStormPHPConfig,
X as updatePhpStormWorkspaceConfig,
O as updateVSCodeConfig
};
//# sourceMappingURL=index.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sources":["../../../../packages/php-wasm/cli-util/src/lib/xdebug-path-mappings.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport { toPosixPath } from '@php-wasm/util';\nimport type { Mount } from './mounts';\nimport {\n\ttype X2jOptions,\n\ttype XmlBuilderOptions,\n\tXMLParser,\n\tXMLBuilder,\n} from 'fast-xml-parser';\nimport * as JSONC from 'jsonc-parser';\n\nexport interface XdebugOptions {\n\tideKey?: string;\n\tpathMappings?: Mount[];\n\tpathSkippings?: string[];\n}\n\nexport const DEFAULT_IDE_KEY = 'PHPWASMCLI';\n\n/**\n * Create a symlink to a tempory directory.\n *\n * The symlink is created to access the system temp dir\n * inside the current debugging directory.\n *\n * @param nativeDirPath The system temp dir path.\n * @param symlinkPath The symlink name.\n */\nexport async function createTempDirSymlink(\n\tnativeDirPath: string,\n\tsymlinkPath: string,\n\tplatform: string\n) {\n\tconst type =\n\t\tplatform === 'win32'\n\t\t\t? // On Windows, creating a 'dir' symlink can require elevated permissions.\n\t\t\t\t// In this case, let's make junction points because they function like\n\t\t\t\t// symlinks and do not require elevated permissions.\n\t\t\t\t'junction'\n\t\t\t: 'dir';\n\tfs.symlinkSync(nativeDirPath, symlinkPath, type);\n}\n\n/**\n * Remove the given temporary directory symlink if it exists.\n *\n * @param symlinkPath The symlink path.\n */\nexport async function removeTempDirSymlink(symlinkPath: string) {\n\ttry {\n\t\tconst stats = fs.lstatSync(symlinkPath);\n\t\tif (stats.isSymbolicLink()) {\n\t\t\tfs.unlinkSync(symlinkPath);\n\t\t}\n\t} catch {\n\t\t// Symlink does not exist or cannot be accessed, nothing to remove\n\t}\n}\n\n/**\n * Filters out mounts that are not in the current working directory\n *\n * @param mounts The mounts list.\n */\nfunction filterLocalMounts(cwd: string, mounts: Mount[]) {\n\treturn mounts.filter((mount) => {\n\t\tconst absoluteHostPath = path.resolve(mount.hostPath);\n\t\tconst cwdChildPrefix = path.join(cwd, path.sep);\n\t\treturn (\n\t\t\t// If auto-mounting from the current directory,\n\t\t\t// the entire project directory can be mapped.\n\t\t\tabsoluteHostPath === cwd ||\n\t\t\tabsoluteHostPath.startsWith(cwdChildPrefix)\n\t\t);\n\t});\n}\n\nexport type XdebugConfig = {\n\t/**\n\t * The current working directory to consider for debugger path mapping.\n\t */\n\tcwd?: string;\n\t/**\n\t * The mounts to consider for debugger path mapping.\n\t */\n\tmounts?: Mount[];\n\t/**\n\t * The paths to consider for debugger path skipping.\n\t */\n\tpathSkippings?: string[];\n};\n\nexport type IDEConfig = {\n\t/**\n\t * The name of the configuration within the IDE configuration.\n\t */\n\tname: string;\n\t/**\n\t * The IDEs to configure.\n\t */\n\tides: string[];\n\t/**\n\t * The web server host.\n\t */\n\thost: string;\n\t/**\n\t * The web server port.\n\t */\n\tport: number;\n\t/**\n\t * The current working directory to consider for debugger path mapping.\n\t */\n\tcwd: string;\n\t/**\n\t * The mounts to consider for debugger path mapping.\n\t */\n\tmounts?: Mount[];\n\t/**\n\t * The IDE key to use for the debug configuration. Defaults to 'PHPWASMCLI'.\n\t */\n\tideKey?: string;\n};\n\ntype PhpStormConfigMetaData = {\n\tname?: string;\n\tversion?: string;\n\thost?: string;\n\tuse_path_mappings?: string;\n\t'local-root'?: string;\n\t'remote-root'?: string;\n\t/**\n\t * The type of the server.\n\t */\n\ttype?: 'PhpRemoteDebugRunConfigurationType';\n\tfactoryName?: string;\n\tfilter_connections?: 'FILTER';\n\tserver_name?: string;\n\tsession_id?: string;\n\tv?: string;\n};\n\ntype PhpStormConfigNode = {\n\t':@'?: PhpStormConfigMetaData;\n\tproject?: PhpStormConfigNode[];\n\tcomponent?: PhpStormConfigNode[];\n\tservers?: PhpStormConfigNode[];\n\tserver?: PhpStormConfigNode[];\n\tpath_mappings?: PhpStormConfigNode[];\n\tmapping?: PhpStormConfigNode[];\n\tconfiguration?: PhpStormConfigNode[];\n\tmethod?: PhpStormConfigNode[];\n};\n\ntype VSCodeConfigMetaData = {\n\t[key: string]: string;\n};\n\ntype VSCodeConfigNode = {\n\tname: string;\n\ttype: string;\n\trequest: string;\n\tport: number;\n\tpathMappings?: VSCodeConfigMetaData;\n};\n\nconst xmlParserOptions: X2jOptions = {\n\tignoreAttributes: false,\n\tattributeNamePrefix: '',\n\tpreserveOrder: true,\n\tcdataPropName: '__cdata',\n\tcommentPropName: '__xmlComment',\n\tallowBooleanAttributes: true,\n\ttrimValues: true,\n};\nconst xmlBuilderOptions: XmlBuilderOptions = {\n\tignoreAttributes: xmlParserOptions.ignoreAttributes,\n\tattributeNamePrefix: xmlParserOptions.attributeNamePrefix,\n\tpreserveOrder: xmlParserOptions.preserveOrder,\n\tcdataPropName: xmlParserOptions.cdataPropName,\n\tcommentPropName: xmlParserOptions.commentPropName,\n\tsuppressBooleanAttributes: !xmlParserOptions.allowBooleanAttributes,\n\tformat: true,\n\tindentBy: '\\t',\n};\n\nconst jsoncParseOptions: JSONC.ParseOptions = {\n\tallowEmptyContent: true,\n\tallowTrailingComma: true,\n};\n\nexport type PhpStormConfigOptions = {\n\tname: string;\n\thost: string;\n\tport: number;\n\tprojectDir: string;\n\tmappings?: Mount[];\n\tideKey: string;\n};\n\n/**\n * Pure function to update PHPStorm XML config with Xdebug server and run configuration.\n *\n * @param xmlContent The original XML content of workspace.xml\n * @param options Configuration options for the server\n * @returns Updated XML content\n * @throws Error if XML is invalid or configuration is incompatible\n */\nexport function updatePhpStormConfig(\n\txmlContent: string,\n\toptions: PhpStormConfigOptions\n): string {\n\tconst { name, host, port, mappings, ideKey } = options;\n\n\tconst xmlParser = new XMLParser(xmlParserOptions);\n\n\t// Parse the XML\n\tconst config: PhpStormConfigNode[] = (() => {\n\t\ttry {\n\t\t\treturn xmlParser.parse(xmlContent, true);\n\t\t} catch {\n\t\t\tthrow new Error('PhpStorm configuration file is not valid XML.');\n\t\t}\n\t})();\n\n\t// Create the server element with path mappings\n\tconst serverElement: PhpStormConfigNode = {\n\t\tserver: [{}],\n\t\t':@': {\n\t\t\tname,\n\t\t\t// NOTE: PhpStorm quirk: Xdebug only works when the full URL (including port)\n\t\t\t// is provided in `host`. The separate `port` field is ignored or misinterpreted,\n\t\t\t// so we rely solely on host: \"host:port\".\n\t\t\thost: `${host}:${port}`,\n\t\t\tuse_path_mappings: 'true',\n\t\t},\n\t};\n\n\tif (mappings && mappings.length) {\n\t\tserverElement.server![0].path_mappings = mappings.map((mapping) => ({\n\t\t\tmapping: [],\n\t\t\t':@': {\n\t\t\t\t'local-root': `$PROJECT_DIR$/${toPosixPath(\n\t\t\t\t\tpath.relative(options.projectDir, mapping.hostPath)\n\t\t\t\t)}`,\n\t\t\t\t'remote-root': mapping.vfsPath,\n\t\t\t},\n\t\t}));\n\t}\n\n\t// Find or create project element\n\tlet projectElement = config?.find((c: PhpStormConfigNode) => !!c?.project);\n\tif (projectElement) {\n\t\tconst projectVersion = projectElement[':@']?.version;\n\t\tif (projectVersion === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm IDE integration only supports <project version=\"4\"> in workspace.xml, ' +\n\t\t\t\t\t'but the <project> configuration has no version number.'\n\t\t\t);\n\t\t} else if (projectVersion !== '4') {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm IDE integration only supports <project version=\"4\"> in workspace.xml, ' +\n\t\t\t\t\t`but we found a <project> configuration with version \"${projectVersion}\".`\n\t\t\t);\n\t\t}\n\t}\n\tif (projectElement === undefined) {\n\t\tprojectElement = {\n\t\t\tproject: [],\n\t\t\t':@': { version: '4' },\n\t\t};\n\t\tconfig.push(projectElement);\n\t}\n\n\t// Find or create PhpServers component\n\tlet componentElement = projectElement.project?.find(\n\t\t(c: PhpStormConfigNode) =>\n\t\t\t!!c?.component && c?.[':@']?.name === 'PhpServers'\n\t);\n\tif (componentElement === undefined) {\n\t\tcomponentElement = {\n\t\t\tcomponent: [],\n\t\t\t':@': { name: 'PhpServers' },\n\t\t};\n\n\t\tif (projectElement.project === undefined) {\n\t\t\tprojectElement.project = [];\n\t\t}\n\n\t\tprojectElement.project.push(componentElement);\n\t}\n\n\t// Find or create servers element\n\tlet serversElement = componentElement.component?.find(\n\t\t(c: PhpStormConfigNode) => !!c?.servers\n\t);\n\tif (serversElement === undefined) {\n\t\tserversElement = { servers: [] };\n\n\t\tif (componentElement.component === undefined) {\n\t\t\tcomponentElement.component = [];\n\t\t}\n\n\t\tcomponentElement.component.push(serversElement);\n\t}\n\n\t// Check if server already exists\n\tconst serverElementIndex = serversElement.servers?.findIndex(\n\t\t(c: PhpStormConfigNode) => !!c?.server && c?.[':@']?.name === name\n\t);\n\n\t// Only add server if it doesn't exist\n\tif (serverElementIndex === undefined || serverElementIndex < 0) {\n\t\tif (serversElement.servers === undefined) {\n\t\t\tserversElement.servers = [];\n\t\t}\n\n\t\tserversElement.servers.push(serverElement);\n\t}\n\n\t// Find or create RunManager component\n\tlet runManagerElement = projectElement.project?.find(\n\t\t(c: PhpStormConfigNode) =>\n\t\t\t!!c?.component && c?.[':@']?.name === 'RunManager'\n\t);\n\tif (runManagerElement === undefined) {\n\t\trunManagerElement = {\n\t\t\tcomponent: [],\n\t\t\t':@': { name: 'RunManager' },\n\t\t};\n\n\t\tif (projectElement.project === undefined) {\n\t\t\tprojectElement.project = [];\n\t\t}\n\n\t\tprojectElement.project.push(runManagerElement);\n\t}\n\n\t// Check if run configuration already exists\n\tconst existingConfigIndex =\n\t\trunManagerElement.component?.findIndex(\n\t\t\t(c: PhpStormConfigNode) =>\n\t\t\t\t!!c?.configuration && c?.[':@']?.name === name\n\t\t) ?? -1;\n\n\t// Only add run configuration if it doesn't exist\n\tif (existingConfigIndex < 0) {\n\t\tconst runConfigElement: PhpStormConfigNode = {\n\t\t\tconfiguration: [\n\t\t\t\t{\n\t\t\t\t\tmethod: [],\n\t\t\t\t\t':@': { v: '2' },\n\t\t\t\t},\n\t\t\t],\n\t\t\t':@': {\n\t\t\t\tname: name,\n\t\t\t\ttype: 'PhpRemoteDebugRunConfigurationType',\n\t\t\t\tfactoryName: 'PHP Remote Debug',\n\t\t\t\tfilter_connections: 'FILTER',\n\t\t\t\tserver_name: name,\n\t\t\t\tsession_id: ideKey,\n\t\t\t},\n\t\t};\n\n\t\tif (runManagerElement.component === undefined) {\n\t\t\trunManagerElement.component = [];\n\t\t}\n\n\t\trunManagerElement.component.push(runConfigElement);\n\t}\n\n\t// Build the updated XML\n\tconst xmlBuilder = new XMLBuilder(xmlBuilderOptions);\n\tconst xml = xmlBuilder.build(config);\n\n\t// Validate the generated XML\n\ttry {\n\t\txmlParser.parse(xml, true);\n\t} catch {\n\t\tthrow new Error(\n\t\t\t'The resulting PhpStorm configuration file is not valid XML.'\n\t\t);\n\t}\n\n\treturn xml;\n}\n\nexport type VSCodeConfigOptions = {\n\tname: string;\n\tworkspaceDir: string;\n\tmappings?: Mount[];\n};\n\n/**\n * Pure function to update VS Code JSON config with Xdebug configuration.\n *\n * @param jsonContent The original JSON content of launch.json\n * @param options Configuration options\n * @returns Updated JSON content\n * @throws Error if JSON is invalid\n */\nexport function updateVSCodeConfig(\n\tjsonContent: string,\n\toptions: VSCodeConfigOptions\n): string {\n\tconst { name, mappings } = options;\n\n\tconst errors: JSONC.ParseError[] = [];\n\n\tlet content = jsonContent;\n\tlet root = JSONC.parseTree(content, errors, jsoncParseOptions);\n\n\tif (root === undefined || errors.length) {\n\t\tthrow new Error('VS Code configuration file is not valid JSON.');\n\t}\n\n\t// Find or create configurations array\n\tlet configurationsNode = JSONC.findNodeAtLocation(root, ['configurations']);\n\n\tif (\n\t\tconfigurationsNode === undefined ||\n\t\tconfigurationsNode.children === undefined\n\t) {\n\t\tconst edits = JSONC.modify(content, ['configurations'], [], {});\n\t\tcontent = JSONC.applyEdits(content, edits);\n\n\t\troot = JSONC.parseTree(content, [], jsoncParseOptions);\n\t\tconfigurationsNode = JSONC.findNodeAtLocation(root!, [\n\t\t\t'configurations',\n\t\t]);\n\t}\n\n\t// Check if configuration already exists\n\tconst configurationIndex = configurationsNode?.children?.findIndex(\n\t\t(child: any) =>\n\t\t\tJSONC.findNodeAtLocation(child, ['name'])?.value === name\n\t);\n\n\t// Only add configuration if it doesn't exist\n\tif (configurationIndex === undefined || configurationIndex < 0) {\n\t\tconst configuration: VSCodeConfigNode = {\n\t\t\tname: name,\n\t\t\ttype: 'php',\n\t\t\trequest: 'launch',\n\t\t\tport: 9003,\n\t\t};\n\n\t\tif (mappings && mappings.length) {\n\t\t\tconfiguration.pathMappings = mappings.reduce((acc, mount) => {\n\t\t\t\tacc[mount.vfsPath] = `\\${workspaceFolder}/${toPosixPath(\n\t\t\t\t\tpath.relative(options.workspaceDir, mount.hostPath)\n\t\t\t\t)}`;\n\t\t\t\treturn acc;\n\t\t\t}, {} as VSCodeConfigMetaData);\n\t\t}\n\n\t\t// Get the current length to append at the end\n\t\tconst currentLength = configurationsNode?.children?.length || 0;\n\n\t\tconst edits = JSONC.modify(\n\t\t\tcontent,\n\t\t\t['configurations', currentLength],\n\t\t\tconfiguration,\n\t\t\t{\n\t\t\t\tformattingOptions: {\n\t\t\t\t\tinsertSpaces: true,\n\t\t\t\t\ttabSize: 4,\n\t\t\t\t\teol: '\\n',\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\n\t\tcontent = jsoncApplyEdits(content, edits);\n\t}\n\n\treturn content;\n}\n\n/**\n * Implement necessary parameters and path mappings in IDE configuration files.\n *\n * @param name The configuration name.\n * @param mounts The mounts options.\n */\nexport async function addXdebugIDEConfig({\n\tname,\n\tides,\n\thost,\n\tport,\n\tcwd,\n\tmounts,\n\tideKey = DEFAULT_IDE_KEY,\n}: IDEConfig) {\n\tconst mappings = mounts ? filterLocalMounts(cwd, mounts) : [];\n\tconst modifiedConfig: Record<string, string> = {};\n\n\t// PHPstorm\n\tif (ides.includes('phpstorm')) {\n\t\tconst phpStormRelativeConfigFilePath = '.idea/workspace.xml';\n\t\tconst phpStormConfigFilePath = path.join(\n\t\t\tcwd,\n\t\t\tphpStormRelativeConfigFilePath\n\t\t);\n\n\t\t// Create a template config file if the IDE directory exists,\n\t\t// or throw an error if IDE integration is requested but the directory is missing.\n\t\tif (!fs.existsSync(phpStormConfigFilePath)) {\n\t\t\tif (fs.existsSync(path.dirname(phpStormConfigFilePath))) {\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tphpStormConfigFilePath,\n\t\t\t\t\t'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<project version=\"4\">\\n</project>'\n\t\t\t\t);\n\t\t\t} else if (ides.length == 1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`PhpStorm IDE integration requested, but no '.idea' directory was found in the current working directory.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (fs.existsSync(phpStormConfigFilePath)) {\n\t\t\tconst contents = fs.readFileSync(phpStormConfigFilePath, 'utf8');\n\t\t\tconst updatedXml = updatePhpStormConfig(contents, {\n\t\t\t\tname,\n\t\t\t\thost,\n\t\t\t\tport,\n\t\t\t\tprojectDir: cwd,\n\t\t\t\tmappings,\n\t\t\t\tideKey,\n\t\t\t});\n\t\t\tfs.writeFileSync(phpStormConfigFilePath, updatedXml);\n\t\t\tmodifiedConfig['phpstorm'] = phpStormRelativeConfigFilePath;\n\t\t}\n\t}\n\n\t// VSCode\n\tif (ides.includes('vscode')) {\n\t\tconst vsCodeRelativeConfigFilePath = '.vscode/launch.json';\n\t\tconst vsCodeConfigFilePath = path.join(\n\t\t\tcwd,\n\t\t\tvsCodeRelativeConfigFilePath\n\t\t);\n\n\t\t// Create a template config file if the IDE directory exists,\n\t\t// or throw an error if IDE integration is requested but the directory is missing.\n\t\tif (!fs.existsSync(vsCodeConfigFilePath)) {\n\t\t\tif (fs.existsSync(path.dirname(vsCodeConfigFilePath))) {\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tvsCodeConfigFilePath,\n\t\t\t\t\t'{\\n \"configurations\": []\\n}'\n\t\t\t\t);\n\t\t\t} else if (ides.length == 1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`VS Code IDE integration requested, but no '.vscode' directory was found in the current working directory.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (fs.existsSync(vsCodeConfigFilePath)) {\n\t\t\tconst content = fs.readFileSync(vsCodeConfigFilePath, 'utf-8');\n\t\t\tconst updatedJson = updateVSCodeConfig(content, {\n\t\t\t\tname,\n\t\t\t\tworkspaceDir: cwd,\n\t\t\t\tmappings,\n\t\t\t});\n\n\t\t\t// Only write and track the file if changes were made\n\t\t\tif (updatedJson !== content) {\n\t\t\t\tfs.writeFileSync(vsCodeConfigFilePath, updatedJson);\n\t\t\t\tmodifiedConfig['vscode'] = vsCodeRelativeConfigFilePath;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn modifiedConfig;\n}\n\n/**\n * Remove stale parameters and path mappings in IDE configuration files.\n *\n * @param name The configuration name.\n * @param cwd The current working directory.\n */\nexport async function clearXdebugIDEConfig(name: string, cwd: string) {\n\tconst phpStormConfigFilePath = path.join(cwd, '.idea/workspace.xml');\n\t// PhpStorm\n\tif (fs.existsSync(phpStormConfigFilePath)) {\n\t\tconst contents = fs.readFileSync(phpStormConfigFilePath, 'utf8');\n\t\tconst xmlParser = new XMLParser(xmlParserOptions);\n\t\t// NOTE: Using an IIFE so `config` can remain const.\n\t\tconst config: PhpStormConfigNode[] = (() => {\n\t\t\ttry {\n\t\t\t\treturn xmlParser.parse(contents, true);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'PhpStorm configuration file is not valid XML.'\n\t\t\t\t);\n\t\t\t}\n\t\t})();\n\n\t\tconst projectElement = config.find(\n\t\t\t(c: PhpStormConfigNode) => !!c?.project\n\t\t);\n\t\tconst componentElement = projectElement?.project?.find(\n\t\t\t(c: PhpStormConfigNode) =>\n\t\t\t\t!!c?.component && c?.[':@']?.name === 'PhpServers'\n\t\t);\n\t\tconst serversElement = componentElement?.component?.find(\n\t\t\t(c: PhpStormConfigNode) => !!c?.servers\n\t\t);\n\t\tconst serverElementIndex = serversElement?.servers?.findIndex(\n\t\t\t(c: PhpStormConfigNode) => !!c?.server && c?.[':@']?.name === name\n\t\t);\n\n\t\tif (serverElementIndex !== undefined && serverElementIndex >= 0) {\n\t\t\tserversElement!.servers!.splice(serverElementIndex, 1);\n\n\t\t\tconst xmlBuilder = new XMLBuilder(xmlBuilderOptions);\n\t\t\tconst xml = xmlBuilder.build(config);\n\n\t\t\ttry {\n\t\t\t\txmlParser.parse(xml, true);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'The resulting PhpStorm configuration file is not valid XML.'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\txml ===\n\t\t\t\t'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<project version=\"4\">\\n\t<component name=\"PhpServers\">\\n\t\t<servers></servers>\\n\t</component>\\n</project>'\n\t\t\t) {\n\t\t\t\tfs.unlinkSync(phpStormConfigFilePath);\n\t\t\t} else {\n\t\t\t\tfs.writeFileSync(phpStormConfigFilePath, xml);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst vsCodeConfigFilePath = path.join(cwd, '.vscode/launch.json');\n\t// VSCode\n\tif (fs.existsSync(vsCodeConfigFilePath)) {\n\t\tconst errors: JSONC.ParseError[] = [];\n\n\t\tconst content = fs.readFileSync(vsCodeConfigFilePath, 'utf-8');\n\t\tconst root = JSONC.parseTree(content, errors, jsoncParseOptions);\n\n\t\tif (root === undefined || errors.length) {\n\t\t\tthrow new Error('VS Code configuration file is not valid JSON.');\n\t\t}\n\n\t\tconst configurationsNode = JSONC.findNodeAtLocation(root, [\n\t\t\t'configurations',\n\t\t]);\n\n\t\tconst configurationIndex = configurationsNode?.children?.findIndex(\n\t\t\t(child: any) =>\n\t\t\t\tJSONC.findNodeAtLocation(child, ['name'])?.value === name\n\t\t);\n\n\t\tif (configurationIndex !== undefined && configurationIndex >= 0) {\n\t\t\tconst edits = JSONC.modify(\n\t\t\t\tcontent,\n\t\t\t\t['configurations', configurationIndex],\n\t\t\t\tundefined,\n\t\t\t\t{\n\t\t\t\t\tformattingOptions: {\n\t\t\t\t\t\tinsertSpaces: true,\n\t\t\t\t\t\ttabSize: 4,\n\t\t\t\t\t\teol: '\\n',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tconst json = jsoncApplyEdits(content, edits);\n\t\t\tif (json === '{\\n \"configurations\": []\\n}') {\n\t\t\t\tfs.unlinkSync(vsCodeConfigFilePath);\n\t\t\t} else {\n\t\t\t\tfs.writeFileSync(vsCodeConfigFilePath, json);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Implement path mapping and path skipping in Xdebug.\n *\n * @param name The configuration name.\n * @param mounts The mounts options.\n * @param pathSkippings The skipping paths options.\n * @returns Xdebug options\n */\nexport function makeXdebugConfig({\n\tcwd,\n\tmounts,\n\tpathSkippings,\n}: XdebugConfig): XdebugOptions {\n\tconst pathMappings =\n\t\tcwd && mounts ? filterLocalMounts(cwd, mounts) : undefined;\n\n\treturn { pathMappings, pathSkippings };\n}\n\nfunction jsoncApplyEdits(content: string, edits: JSONC.Edit[]) {\n\tconst errors: JSONC.ParseError[] = [];\n\tconst json = JSONC.applyEdits(content, edits);\n\n\terrors.length = 0;\n\n\tJSONC.parseTree(json, errors, jsoncParseOptions);\n\n\tif (errors.length) {\n\t\tconst formattedErrors = errors\n\t\t\t.map((error) => {\n\t\t\t\treturn {\n\t\t\t\t\tmessage: JSONC.printParseErrorCode(error.error),\n\t\t\t\t\toffset: error.offset,\n\t\t\t\t\tlength: error.length,\n\t\t\t\t\tfragment: json.slice(\n\t\t\t\t\t\tMath.max(0, error.offset - 20),\n\t\t\t\t\t\tMath.min(json.length, error.offset + error.length + 10)\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t})\n\t\t\t.map(\n\t\t\t\t(error) =>\n\t\t\t\t\t`${error.message} at ${error.offset}:${error.length} (${error.fragment})`\n\t\t\t);\n\t\tconst formattedEdits = edits.map(\n\t\t\t(edit) => `At ${edit.offset}:${edit.length} - (${edit.content})`\n\t\t);\n\t\tthrow new Error(\n\t\t\t`VS Code configuration file (.vscode/launch.json) is not valid a JSONC after CLI modifications. This is likely ` +\n\t\t\t\t`a CLI bug. Please report it at https://github.com/WordPress/wordpress-playground/issues and include the contents ` +\n\t\t\t\t`of your \".vscode/launch.json\" file. \\n\\n Applied edits: ${formattedEdits.join(\n\t\t\t\t\t'\\n'\n\t\t\t\t)}\\n\\n The errors are: ${formattedErrors.join('\\n')}`\n\t\t);\n\t}\n\n\treturn json;\n}\n"],"names":["DEFAULT_IDE_KEY","createTempDirSymlink","nativeDirPath","symlinkPath","platform","type","fs","removeTempDirSymlink","filterLocalMounts","cwd","mounts","mount","absoluteHostPath","path","cwdChildPrefix","xmlParserOptions","xmlBuilderOptions","jsoncParseOptions","updatePhpStormConfig","xmlContent","options","name","host","port","mappings","ideKey","xmlParser","XMLParser","config","serverElement","mapping","toPosixPath","projectElement","c","projectVersion","_a","componentElement","_b","serversElement","_c","serverElementIndex","_d","runManagerElement","_e","_f","runConfigElement","xml","XMLBuilder","updateVSCodeConfig","jsonContent","errors","content","root","JSONC","configurationsNode","edits","configurationIndex","child","configuration","acc","currentLength","jsoncApplyEdits","addXdebugIDEConfig","ides","modifiedConfig","phpStormRelativeConfigFilePath","phpStormConfigFilePath","contents","updatedXml","vsCodeRelativeConfigFilePath","vsCodeConfigFilePath","updatedJson","clearXdebugIDEConfig","json","makeXdebugConfig","pathSkippings","formattedErrors","error","formattedEdits","edit"],"mappings":"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"}
{"version":3,"file":"index.js","sources":["../../../../packages/php-wasm/cli-util/src/lib/xdebug-path-mappings.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport { toPosixPath } from '@php-wasm/util';\nimport type { Mount } from './mounts';\nimport {\n\ttype X2jOptions,\n\ttype XmlBuilderOptions,\n\tXMLParser,\n\tXMLBuilder,\n} from 'fast-xml-parser';\nimport * as JSONC from 'jsonc-parser';\n\nexport interface XdebugOptions {\n\tideKey?: string;\n\tpathMappings?: Mount[];\n\tpathSkippings?: string[];\n}\n\nexport const DEFAULT_IDE_KEY = 'PHPWASMCLI';\nexport const DEFAULT_PATH_SKIPPINGS = [\n\t'/dev/',\n\t'/home/',\n\t'/internal/',\n\t'/request/',\n\t'/proc/',\n];\n\n/**\n * Create a symlink to a tempory directory.\n *\n * The symlink is created to access the system temp dir\n * inside the current debugging directory.\n *\n * @param nativeDirPath The system temp dir path.\n * @param symlinkPath The symlink name.\n */\nexport async function createTempDirSymlink(\n\tnativeDirPath: string,\n\tsymlinkPath: string,\n\tplatform: string\n) {\n\tconst type =\n\t\tplatform === 'win32'\n\t\t\t? // On Windows, creating a 'dir' symlink can require elevated permissions.\n\t\t\t\t// In this case, let's make junction points because they function like\n\t\t\t\t// symlinks and do not require elevated permissions.\n\t\t\t\t'junction'\n\t\t\t: 'dir';\n\tfs.symlinkSync(nativeDirPath, symlinkPath, type);\n}\n\n/**\n * Remove the given temporary directory symlink if it exists.\n *\n * @param symlinkPath The symlink path.\n */\nexport async function removeTempDirSymlink(symlinkPath: string) {\n\ttry {\n\t\tconst stats = fs.lstatSync(symlinkPath);\n\t\tif (stats.isSymbolicLink()) {\n\t\t\tfs.unlinkSync(symlinkPath);\n\t\t}\n\t} catch {\n\t\t// Symlink does not exist or cannot be accessed, nothing to remove\n\t}\n}\n\n/**\n * Filters out mounts that are not in the current working directory\n *\n * @param mounts The mounts list.\n */\nfunction filterLocalMounts(cwd: string, mounts: Mount[]) {\n\treturn mounts.filter((mount) => {\n\t\tconst absoluteHostPath = path.resolve(mount.hostPath);\n\t\tconst cwdChildPrefix = path.join(cwd, path.sep);\n\t\treturn (\n\t\t\t// If auto-mounting from the current directory,\n\t\t\t// the entire project directory can be mapped.\n\t\t\tabsoluteHostPath === cwd ||\n\t\t\tabsoluteHostPath.startsWith(cwdChildPrefix)\n\t\t);\n\t});\n}\n\nexport type XdebugConfig = {\n\t/**\n\t * The current working directory to consider for debugger path mapping.\n\t */\n\tcwd?: string;\n\t/**\n\t * The mounts to consider for debugger path mapping.\n\t */\n\tmounts?: Mount[];\n\t/**\n\t * The paths to consider for debugger path skipping.\n\t */\n\tpathSkippings?: string[];\n};\n\nexport type IDEConfig = {\n\t/**\n\t * The name of the configuration within the IDE configuration.\n\t */\n\tname: string;\n\t/**\n\t * The IDEs to configure.\n\t */\n\tides: string[];\n\t/**\n\t * The web server host.\n\t */\n\thost: string;\n\t/**\n\t * The web server port.\n\t */\n\tport: number;\n\t/**\n\t * The current working directory to consider for debugger path mapping.\n\t */\n\tcwd: string;\n\t/**\n\t * The mounts to consider for debugger path mapping.\n\t */\n\tmounts?: Mount[];\n\t/**\n\t * The paths to skip when debugging.\n\t */\n\tpathSkippings?: string[];\n\t/**\n\t * The IDE key to use for the debug configuration. Defaults to 'PHPWASMCLI'.\n\t */\n\tideKey?: string;\n};\n\ntype PhpStormWorkspaceConfigMetaData = {\n\tname?: string;\n\tversion?: string;\n\thost?: string;\n\tuse_path_mappings?: string;\n\t'local-root'?: string;\n\t'remote-root'?: string;\n\ttype?: 'PhpRemoteDebugRunConfigurationType';\n\tfactoryName?: string;\n\tfilter_connections?: 'FILTER';\n\tserver_name?: string;\n\tsession_id?: string;\n\tv?: string;\n};\n\ntype PhpStormWorkspaceConfigNode = {\n\t':@'?: PhpStormWorkspaceConfigMetaData;\n\tproject?: PhpStormWorkspaceConfigNode[];\n\tcomponent?: PhpStormWorkspaceConfigNode[];\n\tservers?: PhpStormWorkspaceConfigNode[];\n\tserver?: PhpStormWorkspaceConfigNode[];\n\tpath_mappings?: PhpStormWorkspaceConfigNode[];\n\tmapping?: PhpStormWorkspaceConfigNode[];\n\tconfiguration?: PhpStormWorkspaceConfigNode[];\n\tmethod?: PhpStormWorkspaceConfigNode[];\n};\n\ntype PhpStormPHPConfigMetaData = {\n\tname?: string;\n\tversion?: string;\n\tfile?: string;\n};\n\ntype PhpStormPHPConfigNode = {\n\t':@'?: PhpStormPHPConfigMetaData;\n\tproject?: PhpStormPHPConfigNode[];\n\tcomponent?: PhpStormPHPConfigNode[];\n\tskipped_files?: PhpStormPHPConfigNode[];\n\tskipped_file?: PhpStormPHPConfigNode[];\n};\n\ntype VSCodeConfigMetaData = {\n\t[key: string]: string;\n};\n\ntype VSCodeConfigNode = {\n\tname: string;\n\ttype: string;\n\trequest: string;\n\tport: number;\n\tpathMappings?: VSCodeConfigMetaData;\n\tskipFiles?: string[];\n};\n\nconst xmlParserOptions: X2jOptions = {\n\tignoreAttributes: false,\n\tattributeNamePrefix: '',\n\tpreserveOrder: true,\n\tcdataPropName: '__cdata',\n\tcommentPropName: '__xmlComment',\n\tallowBooleanAttributes: true,\n\ttrimValues: true,\n};\nconst xmlBuilderOptions: XmlBuilderOptions = {\n\tignoreAttributes: xmlParserOptions.ignoreAttributes,\n\tattributeNamePrefix: xmlParserOptions.attributeNamePrefix,\n\tpreserveOrder: xmlParserOptions.preserveOrder,\n\tcdataPropName: xmlParserOptions.cdataPropName,\n\tcommentPropName: xmlParserOptions.commentPropName,\n\tsuppressBooleanAttributes: !xmlParserOptions.allowBooleanAttributes,\n\tformat: true,\n\tindentBy: '\\t',\n};\n\nconst jsoncParseOptions: JSONC.ParseOptions = {\n\tallowEmptyContent: true,\n\tallowTrailingComma: true,\n};\n\nexport type PhpStormWorkspaceConfigOptions = {\n\tname: string;\n\thost: string;\n\tport: number;\n\tprojectDir: string;\n\tpathMappings?: Mount[];\n\tideKey: string;\n};\n\n/**\n * Pure function to update PHPStorm XML config with Xdebug server and run configuration.\n *\n * @param xmlContent The original XML content of workspace.xml\n * @param options Configuration options for the server\n * @returns Updated XML content\n * @throws Error if XML is invalid or configuration is incompatible\n */\nexport function updatePhpStormWorkspaceConfig(\n\txmlContent: string,\n\toptions: PhpStormWorkspaceConfigOptions\n): string {\n\tconst { name, host, port, pathMappings, ideKey } = options;\n\n\tconst xmlParser = new XMLParser(xmlParserOptions);\n\n\t// Parse the XML\n\tconst config: PhpStormWorkspaceConfigNode[] = (() => {\n\t\ttry {\n\t\t\treturn xmlParser.parse(xmlContent, true);\n\t\t} catch {\n\t\t\tthrow new Error('PhpStorm configuration file is not valid XML.');\n\t\t}\n\t})();\n\n\t// Create the server element with path mappings\n\tconst serverElement: PhpStormWorkspaceConfigNode = {\n\t\tserver: [{}],\n\t\t':@': {\n\t\t\tname,\n\t\t\t// NOTE: PhpStorm quirk: Xdebug only works when the full URL (including port)\n\t\t\t// is provided in `host`. The separate `port` field is ignored or misinterpreted,\n\t\t\t// so we rely solely on host: \"host:port\".\n\t\t\thost: `${host}:${port}`,\n\t\t\tuse_path_mappings: 'true',\n\t\t},\n\t};\n\n\tif (pathMappings && pathMappings.length) {\n\t\tserverElement.server![0].path_mappings = pathMappings.map(\n\t\t\t(pathMapping) => ({\n\t\t\t\tmapping: [],\n\t\t\t\t':@': {\n\t\t\t\t\t'local-root': `$PROJECT_DIR$/${toPosixPath(\n\t\t\t\t\t\tpath.relative(options.projectDir, pathMapping.hostPath)\n\t\t\t\t\t)}`,\n\t\t\t\t\t'remote-root': pathMapping.vfsPath,\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t}\n\n\t// Find or create project element\n\tlet projectElement = config?.find(\n\t\t(c: PhpStormWorkspaceConfigNode) => !!c?.project\n\t);\n\tif (projectElement) {\n\t\tconst projectVersion = projectElement[':@']?.version;\n\t\tif (projectVersion === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm IDE integration only supports <project version=\"4\"> in workspace.xml, ' +\n\t\t\t\t\t'but the <project> configuration has no version number.'\n\t\t\t);\n\t\t} else if (projectVersion !== '4') {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm IDE integration only supports <project version=\"4\"> in workspace.xml, ' +\n\t\t\t\t\t`but we found a <project> configuration with version \"${projectVersion}\".`\n\t\t\t);\n\t\t}\n\t}\n\tif (projectElement === undefined) {\n\t\tprojectElement = {\n\t\t\tproject: [],\n\t\t\t':@': { version: '4' },\n\t\t};\n\t\tconfig.push(projectElement);\n\t}\n\n\t// Find or create PhpServers component\n\tlet componentElement = projectElement.project?.find(\n\t\t(c: PhpStormWorkspaceConfigNode) =>\n\t\t\t!!c?.component && c?.[':@']?.name === 'PhpServers'\n\t);\n\tif (componentElement === undefined) {\n\t\tcomponentElement = {\n\t\t\tcomponent: [],\n\t\t\t':@': { name: 'PhpServers' },\n\t\t};\n\n\t\tif (projectElement.project === undefined) {\n\t\t\tprojectElement.project = [];\n\t\t}\n\n\t\tprojectElement.project.push(componentElement);\n\t}\n\n\t// Find or create servers element\n\tlet serversElement = componentElement.component?.find(\n\t\t(c: PhpStormWorkspaceConfigNode) => !!c?.servers\n\t);\n\tif (serversElement === undefined) {\n\t\tserversElement = { servers: [] };\n\n\t\tif (componentElement.component === undefined) {\n\t\t\tcomponentElement.component = [];\n\t\t}\n\n\t\tcomponentElement.component.push(serversElement);\n\t}\n\n\t// Check if server already exists\n\tconst serverElementIndex = serversElement.servers?.findIndex(\n\t\t(c: PhpStormWorkspaceConfigNode) =>\n\t\t\t!!c?.server && c?.[':@']?.name === name\n\t);\n\n\t// Only add server if it doesn't exist\n\tif (serverElementIndex === undefined || serverElementIndex < 0) {\n\t\tif (serversElement.servers === undefined) {\n\t\t\tserversElement.servers = [];\n\t\t}\n\n\t\tserversElement.servers.push(serverElement);\n\t}\n\n\t// Find or create RunManager component\n\tlet runManagerElement = projectElement.project?.find(\n\t\t(c: PhpStormWorkspaceConfigNode) =>\n\t\t\t!!c?.component && c?.[':@']?.name === 'RunManager'\n\t);\n\tif (runManagerElement === undefined) {\n\t\trunManagerElement = {\n\t\t\tcomponent: [],\n\t\t\t':@': { name: 'RunManager' },\n\t\t};\n\n\t\tif (projectElement.project === undefined) {\n\t\t\tprojectElement.project = [];\n\t\t}\n\n\t\tprojectElement.project.push(runManagerElement);\n\t}\n\n\t// Check if run configuration already exists\n\tconst existingConfigIndex =\n\t\trunManagerElement.component?.findIndex(\n\t\t\t(c: PhpStormWorkspaceConfigNode) =>\n\t\t\t\t!!c?.configuration && c?.[':@']?.name === name\n\t\t) ?? -1;\n\n\t// Only add run configuration if it doesn't exist\n\tif (existingConfigIndex < 0) {\n\t\tconst runConfigElement: PhpStormWorkspaceConfigNode = {\n\t\t\tconfiguration: [\n\t\t\t\t{\n\t\t\t\t\tmethod: [],\n\t\t\t\t\t':@': { v: '2' },\n\t\t\t\t},\n\t\t\t],\n\t\t\t':@': {\n\t\t\t\tname: name,\n\t\t\t\ttype: 'PhpRemoteDebugRunConfigurationType',\n\t\t\t\tfactoryName: 'PHP Remote Debug',\n\t\t\t\tfilter_connections: 'FILTER',\n\t\t\t\tserver_name: name,\n\t\t\t\tsession_id: ideKey,\n\t\t\t},\n\t\t};\n\n\t\tif (runManagerElement.component === undefined) {\n\t\t\trunManagerElement.component = [];\n\t\t}\n\n\t\trunManagerElement.component.push(runConfigElement);\n\t}\n\n\t// Build the updated XML\n\tconst xmlBuilder = new XMLBuilder(xmlBuilderOptions);\n\tconst xml = xmlBuilder.build(config);\n\n\t// Validate the generated XML\n\ttry {\n\t\txmlParser.parse(xml, true);\n\t} catch {\n\t\tthrow new Error(\n\t\t\t'The resulting PhpStorm configuration file is not valid XML.'\n\t\t);\n\t}\n\n\treturn xml;\n}\n\nexport type PhpStormPHPConfigOptions = {\n\tpathSkippings?: string[];\n};\n\n/**\n * Pure function to update PhpStorm php.xml config with skipped files.\n *\n * @param xmlContent The original XML content of php.xml\n * @param options Configuration options for skipped files\n * @returns Updated XML content\n * @throws Error if XML is invalid or configuration is incompatible\n */\nexport function updatePhpStormPHPConfig(\n\txmlContent: string,\n\toptions: PhpStormPHPConfigOptions\n): string {\n\tconst { pathSkippings } = options;\n\n\tconst xmlParser = new XMLParser(xmlParserOptions);\n\n\tconst config: PhpStormPHPConfigNode[] = (() => {\n\t\ttry {\n\t\t\treturn xmlParser.parse(xmlContent, true);\n\t\t} catch {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm PHP configuration file is not valid XML.'\n\t\t\t);\n\t\t}\n\t})();\n\n\t// Find or create project element\n\tlet projectElement = config?.find(\n\t\t(c: PhpStormPHPConfigNode) => !!c?.project\n\t);\n\tif (projectElement) {\n\t\tconst projectVersion = projectElement[':@']?.version;\n\t\tif (projectVersion === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm IDE integration only supports ' +\n\t\t\t\t\t'<project version=\"4\"> in php.xml, ' +\n\t\t\t\t\t'but the <project> configuration has no version number.'\n\t\t\t);\n\t\t} else if (projectVersion !== '4') {\n\t\t\tthrow new Error(\n\t\t\t\t'PhpStorm IDE integration only supports ' +\n\t\t\t\t\t'<project version=\"4\"> in php.xml, ' +\n\t\t\t\t\t`but we found a <project> configuration ` +\n\t\t\t\t\t`with version \"${projectVersion}\".`\n\t\t\t);\n\t\t}\n\t}\n\tif (projectElement === undefined) {\n\t\tprojectElement = {\n\t\t\tproject: [],\n\t\t\t':@': { version: '4' },\n\t\t};\n\t\tconfig.push(projectElement);\n\t}\n\n\t// Find or create PhpStepFilterConfiguration component\n\tlet componentElement = projectElement.project?.find(\n\t\t(c: PhpStormPHPConfigNode) =>\n\t\t\t!!c?.component && c?.[':@']?.name === 'PhpStepFilterConfiguration'\n\t);\n\tif (componentElement === undefined) {\n\t\tcomponentElement = {\n\t\t\tcomponent: [],\n\t\t\t':@': { name: 'PhpStepFilterConfiguration' },\n\t\t};\n\n\t\tif (projectElement.project === undefined) {\n\t\t\tprojectElement.project = [];\n\t\t}\n\n\t\tprojectElement.project.push(componentElement);\n\t}\n\n\t// Find or create skipped_files element\n\tlet skippedFilesElement = componentElement.component?.find(\n\t\t(c: PhpStormPHPConfigNode) => !!c?.skipped_files\n\t);\n\tif (skippedFilesElement === undefined) {\n\t\tskippedFilesElement = { skipped_files: [] };\n\n\t\tif (componentElement.component === undefined) {\n\t\t\tcomponentElement.component = [];\n\t\t}\n\n\t\tcomponentElement.component.push(skippedFilesElement);\n\t}\n\n\t// Add skipped files\n\tif (pathSkippings && pathSkippings.length) {\n\t\tfor (const skippedPath of pathSkippings) {\n\t\t\tconst normalizedPath = skippedPath.endsWith('/')\n\t\t\t\t? skippedPath.slice(0, -1)\n\t\t\t\t: skippedPath;\n\t\t\tconst filePath = `$PROJECT_DIR$${normalizedPath}`;\n\n\t\t\t// Check if already exists\n\t\t\tconst exists = skippedFilesElement.skipped_files?.some(\n\t\t\t\t(c: PhpStormPHPConfigNode) =>\n\t\t\t\t\t!!c?.skipped_file && c?.[':@']?.file === filePath\n\t\t\t);\n\n\t\t\tif (!exists) {\n\t\t\t\tif (skippedFilesElement.skipped_files === undefined) {\n\t\t\t\t\tskippedFilesElement.skipped_files = [];\n\t\t\t\t}\n\n\t\t\t\tskippedFilesElement.skipped_files.push({\n\t\t\t\t\tskipped_file: [],\n\t\t\t\t\t':@': { file: filePath },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Build the updated XML\n\tconst xmlBuilder = new XMLBuilder(xmlBuilderOptions);\n\tconst xml = xmlBuilder.build(config);\n\n\t// Validate the generated XML\n\ttry {\n\t\txmlParser.parse(xml, true);\n\t} catch {\n\t\tthrow new Error(\n\t\t\t'The resulting PhpStorm PHP configuration file ' +\n\t\t\t\t'is not valid XML.'\n\t\t);\n\t}\n\n\treturn xml;\n}\n\nexport type VSCodeConfigOptions = {\n\tname: string;\n\tworkspaceDir: string;\n\tpathMappings?: Mount[];\n\tpathSkippings?: string[];\n};\n\n/**\n * Pure function to update VS Code JSON config with Xdebug configuration.\n *\n * @param jsonContent The original JSON content of launch.json\n * @param options Configuration options\n * @returns Updated JSON content\n * @throws Error if JSON is invalid\n */\nexport function updateVSCodeConfig(\n\tjsonContent: string,\n\toptions: VSCodeConfigOptions\n): string {\n\tconst { name, pathMappings, pathSkippings } = options;\n\n\tconst errors: JSONC.ParseError[] = [];\n\n\tlet content = jsonContent;\n\tlet root = JSONC.parseTree(content, errors, jsoncParseOptions);\n\n\tif (root === undefined || errors.length) {\n\t\tthrow new Error('VS Code configuration file is not valid JSON.');\n\t}\n\n\t// Find or create configurations array\n\tlet configurationsNode = JSONC.findNodeAtLocation(root, ['configurations']);\n\n\tif (\n\t\tconfigurationsNode === undefined ||\n\t\tconfigurationsNode.children === undefined\n\t) {\n\t\tconst edits = JSONC.modify(content, ['configurations'], [], {});\n\t\tcontent = JSONC.applyEdits(content, edits);\n\n\t\troot = JSONC.parseTree(content, [], jsoncParseOptions);\n\t\tconfigurationsNode = JSONC.findNodeAtLocation(root!, [\n\t\t\t'configurations',\n\t\t]);\n\t}\n\n\t// Check if configuration already exists\n\tconst configurationIndex = configurationsNode?.children?.findIndex(\n\t\t(child: any) =>\n\t\t\tJSONC.findNodeAtLocation(child, ['name'])?.value === name\n\t);\n\n\t// Only add configuration if it doesn't exist\n\tif (configurationIndex === undefined || configurationIndex < 0) {\n\t\tconst configuration: VSCodeConfigNode = {\n\t\t\tname: name,\n\t\t\ttype: 'php',\n\t\t\trequest: 'launch',\n\t\t\tport: 9003,\n\t\t};\n\n\t\tif (pathMappings && pathMappings.length) {\n\t\t\tconfiguration.pathMappings = pathMappings.reduce((acc, mount) => {\n\t\t\t\tacc[mount.vfsPath] = `\\${workspaceFolder}/${toPosixPath(\n\t\t\t\t\tpath.relative(options.workspaceDir, mount.hostPath)\n\t\t\t\t)}`;\n\t\t\t\treturn acc;\n\t\t\t}, {} as VSCodeConfigMetaData);\n\t\t}\n\n\t\tif (pathSkippings && pathSkippings.length) {\n\t\t\tconfiguration.skipFiles = pathSkippings.map((skippedPath) =>\n\t\t\t\tskippedPath.endsWith('/') ? `${skippedPath}**` : skippedPath\n\t\t\t);\n\t\t}\n\n\t\t// Get the current length to append at the end\n\t\tconst currentLength = configurationsNode?.children?.length || 0;\n\n\t\tconst edits = JSONC.modify(\n\t\t\tcontent,\n\t\t\t['configurations', currentLength],\n\t\t\tconfiguration,\n\t\t\t{\n\t\t\t\tformattingOptions: {\n\t\t\t\t\tinsertSpaces: true,\n\t\t\t\t\ttabSize: 4,\n\t\t\t\t\teol: '\\n',\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\n\t\tcontent = jsoncApplyEdits(content, edits);\n\t}\n\n\treturn content;\n}\n\n/**\n * Implement necessary parameters and path mappings in IDE configuration files.\n *\n * @param name The configuration name.\n * @param mounts The mounts options.\n */\nexport async function addXdebugIDEConfig({\n\tname,\n\tides,\n\thost,\n\tport,\n\tcwd,\n\tmounts,\n\tpathSkippings,\n\tideKey = DEFAULT_IDE_KEY,\n}: IDEConfig) {\n\tconst pathMappings = mounts ? filterLocalMounts(cwd, mounts) : [];\n\tconst modifiedConfig: Record<string, string> = {};\n\n\t// PHPstorm\n\tif (ides.includes('phpstorm')) {\n\t\tconst phpStormRelativeConfigFilePath = '.idea/workspace.xml';\n\t\tconst phpStormConfigFilePath = path.join(\n\t\t\tcwd,\n\t\t\tphpStormRelativeConfigFilePath\n\t\t);\n\n\t\t// Create a template config file if the IDE directory exists,\n\t\t// or throw an error if IDE integration is requested but the directory is missing.\n\t\tif (!fs.existsSync(phpStormConfigFilePath)) {\n\t\t\tif (fs.existsSync(path.dirname(phpStormConfigFilePath))) {\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tphpStormConfigFilePath,\n\t\t\t\t\t'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<project version=\"4\">\\n</project>'\n\t\t\t\t);\n\t\t\t} else if (ides.length == 1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`PhpStorm IDE integration requested, but no '.idea' directory was found in the current working directory.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (fs.existsSync(phpStormConfigFilePath)) {\n\t\t\tconst contents = fs.readFileSync(phpStormConfigFilePath, 'utf8');\n\t\t\tconst updatedXml = updatePhpStormWorkspaceConfig(contents, {\n\t\t\t\tname,\n\t\t\t\thost,\n\t\t\t\tport,\n\t\t\t\tprojectDir: cwd,\n\t\t\t\tpathMappings,\n\t\t\t\tideKey,\n\t\t\t});\n\t\t\tfs.writeFileSync(phpStormConfigFilePath, updatedXml);\n\t\t\tmodifiedConfig['phpstorm'] = phpStormRelativeConfigFilePath;\n\t\t}\n\n\t\t// PhpStorm php.xml (path skippings)\n\t\tif (pathSkippings && pathSkippings.length) {\n\t\t\tconst phpStormRelativePHPConfigFilePath = '.idea/php.xml';\n\t\t\tconst phpStormPHPConfigFilePath = path.join(\n\t\t\t\tcwd,\n\t\t\t\tphpStormRelativePHPConfigFilePath\n\t\t\t);\n\n\t\t\tif (!fs.existsSync(phpStormPHPConfigFilePath)) {\n\t\t\t\tif (fs.existsSync(path.dirname(phpStormPHPConfigFilePath))) {\n\t\t\t\t\tfs.writeFileSync(\n\t\t\t\t\t\tphpStormPHPConfigFilePath,\n\t\t\t\t\t\t'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<project version=\"4\">\\n</project>'\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (fs.existsSync(phpStormPHPConfigFilePath)) {\n\t\t\t\tconst contents = fs.readFileSync(\n\t\t\t\t\tphpStormPHPConfigFilePath,\n\t\t\t\t\t'utf8'\n\t\t\t\t);\n\t\t\t\tconst updatedXml = updatePhpStormPHPConfig(contents, {\n\t\t\t\t\tpathSkippings,\n\t\t\t\t});\n\t\t\t\tfs.writeFileSync(phpStormPHPConfigFilePath, updatedXml);\n\t\t\t\tmodifiedConfig['phpstorm-php'] =\n\t\t\t\t\tphpStormRelativePHPConfigFilePath;\n\t\t\t}\n\t\t}\n\t}\n\n\t// VSCode\n\tif (ides.includes('vscode')) {\n\t\tconst vsCodeRelativeConfigFilePath = '.vscode/launch.json';\n\t\tconst vsCodeConfigFilePath = path.join(\n\t\t\tcwd,\n\t\t\tvsCodeRelativeConfigFilePath\n\t\t);\n\n\t\t// Create a template config file if the IDE directory exists,\n\t\t// or throw an error if IDE integration is requested but the directory is missing.\n\t\tif (!fs.existsSync(vsCodeConfigFilePath)) {\n\t\t\tif (fs.existsSync(path.dirname(vsCodeConfigFilePath))) {\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tvsCodeConfigFilePath,\n\t\t\t\t\t'{\\n \"configurations\": []\\n}'\n\t\t\t\t);\n\t\t\t} else if (ides.length == 1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`VS Code IDE integration requested, but no '.vscode' directory was found in the current working directory.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (fs.existsSync(vsCodeConfigFilePath)) {\n\t\t\tconst content = fs.readFileSync(vsCodeConfigFilePath, 'utf-8');\n\t\t\tconst updatedJson = updateVSCodeConfig(content, {\n\t\t\t\tname,\n\t\t\t\tworkspaceDir: cwd,\n\t\t\t\tpathMappings,\n\t\t\t\tpathSkippings,\n\t\t\t});\n\n\t\t\t// Only write and track the file if changes were made\n\t\t\tif (updatedJson !== content) {\n\t\t\t\tfs.writeFileSync(vsCodeConfigFilePath, updatedJson);\n\t\t\t\tmodifiedConfig['vscode'] = vsCodeRelativeConfigFilePath;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn modifiedConfig;\n}\n\n/**\n * Remove stale parameters and path mappings in IDE configuration files.\n *\n * @param name The configuration name.\n * @param cwd The current working directory.\n */\nexport async function clearXdebugIDEConfig(name: string, cwd: string) {\n\tconst phpStormConfigFilePath = path.join(cwd, '.idea/workspace.xml');\n\t// PhpStorm\n\tif (fs.existsSync(phpStormConfigFilePath)) {\n\t\tconst contents = fs.readFileSync(phpStormConfigFilePath, 'utf8');\n\t\tconst xmlParser = new XMLParser(xmlParserOptions);\n\t\t// NOTE: Using an IIFE so `config` can remain const.\n\t\tconst config: PhpStormWorkspaceConfigNode[] = (() => {\n\t\t\ttry {\n\t\t\t\treturn xmlParser.parse(contents, true);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'PhpStorm configuration file is not valid XML.'\n\t\t\t\t);\n\t\t\t}\n\t\t})();\n\n\t\tconst projectElement = config.find(\n\t\t\t(c: PhpStormWorkspaceConfigNode) => !!c?.project\n\t\t);\n\t\tconst componentElement = projectElement?.project?.find(\n\t\t\t(c: PhpStormWorkspaceConfigNode) =>\n\t\t\t\t!!c?.component && c?.[':@']?.name === 'PhpServers'\n\t\t);\n\t\tconst serversElement = componentElement?.component?.find(\n\t\t\t(c: PhpStormWorkspaceConfigNode) => !!c?.servers\n\t\t);\n\t\tconst serverElementIndex = serversElement?.servers?.findIndex(\n\t\t\t(c: PhpStormWorkspaceConfigNode) =>\n\t\t\t\t!!c?.server && c?.[':@']?.name === name\n\t\t);\n\n\t\tif (serverElementIndex !== undefined && serverElementIndex >= 0) {\n\t\t\tserversElement!.servers!.splice(serverElementIndex, 1);\n\n\t\t\tconst xmlBuilder = new XMLBuilder(xmlBuilderOptions);\n\t\t\tconst xml = xmlBuilder.build(config);\n\n\t\t\ttry {\n\t\t\t\txmlParser.parse(xml, true);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'The resulting PhpStorm configuration file is not valid XML.'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\txml ===\n\t\t\t\t'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<project version=\"4\">\\n\t<component name=\"PhpServers\">\\n\t\t<servers></servers>\\n\t</component>\\n</project>'\n\t\t\t) {\n\t\t\t\tfs.unlinkSync(phpStormConfigFilePath);\n\t\t\t} else {\n\t\t\t\tfs.writeFileSync(phpStormConfigFilePath, xml);\n\t\t\t}\n\t\t}\n\t}\n\n\t// PhpStorm php.xml (path skippings)\n\tconst phpStormPHPConfigFilePath = path.join(cwd, '.idea/php.xml');\n\tif (fs.existsSync(phpStormPHPConfigFilePath)) {\n\t\tconst contents = fs.readFileSync(phpStormPHPConfigFilePath, 'utf8');\n\t\tconst xmlParser = new XMLParser(xmlParserOptions);\n\t\tconst config: PhpStormPHPConfigNode[] = (() => {\n\t\t\ttry {\n\t\t\t\treturn xmlParser.parse(contents, true);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'PhpStorm PHP configuration file is not valid XML.'\n\t\t\t\t);\n\t\t\t}\n\t\t})();\n\n\t\tconst projectElement = config.find(\n\t\t\t(c: PhpStormPHPConfigNode) => !!c?.project\n\t\t);\n\t\tconst componentIndex = projectElement?.project?.findIndex(\n\t\t\t(c: PhpStormPHPConfigNode) =>\n\t\t\t\t!!c?.component &&\n\t\t\t\tc?.[':@']?.name === 'PhpStepFilterConfiguration'\n\t\t);\n\n\t\tif (componentIndex !== undefined && componentIndex >= 0) {\n\t\t\tprojectElement!.project!.splice(componentIndex, 1);\n\n\t\t\tconst xmlBuilder = new XMLBuilder(xmlBuilderOptions);\n\t\t\tconst xml = xmlBuilder.build(config);\n\n\t\t\ttry {\n\t\t\t\txmlParser.parse(xml, true);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'The resulting PhpStorm PHP configuration file ' +\n\t\t\t\t\t\t'is not valid XML.'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\txml ===\n\t\t\t\t'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<project version=\"4\">\\n</project>'\n\t\t\t) {\n\t\t\t\tfs.unlinkSync(phpStormPHPConfigFilePath);\n\t\t\t} else {\n\t\t\t\tfs.writeFileSync(phpStormPHPConfigFilePath, xml);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst vsCodeConfigFilePath = path.join(cwd, '.vscode/launch.json');\n\t// VSCode\n\tif (fs.existsSync(vsCodeConfigFilePath)) {\n\t\tconst errors: JSONC.ParseError[] = [];\n\n\t\tconst content = fs.readFileSync(vsCodeConfigFilePath, 'utf-8');\n\t\tconst root = JSONC.parseTree(content, errors, jsoncParseOptions);\n\n\t\tif (root === undefined || errors.length) {\n\t\t\tthrow new Error('VS Code configuration file is not valid JSON.');\n\t\t}\n\n\t\tconst configurationsNode = JSONC.findNodeAtLocation(root, [\n\t\t\t'configurations',\n\t\t]);\n\n\t\tconst configurationIndex = configurationsNode?.children?.findIndex(\n\t\t\t(child: any) =>\n\t\t\t\tJSONC.findNodeAtLocation(child, ['name'])?.value === name\n\t\t);\n\n\t\tif (configurationIndex !== undefined && configurationIndex >= 0) {\n\t\t\tconst edits = JSONC.modify(\n\t\t\t\tcontent,\n\t\t\t\t['configurations', configurationIndex],\n\t\t\t\tundefined,\n\t\t\t\t{\n\t\t\t\t\tformattingOptions: {\n\t\t\t\t\t\tinsertSpaces: true,\n\t\t\t\t\t\ttabSize: 4,\n\t\t\t\t\t\teol: '\\n',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tconst json = jsoncApplyEdits(content, edits);\n\t\t\tif (json === '{\\n \"configurations\": []\\n}') {\n\t\t\t\tfs.unlinkSync(vsCodeConfigFilePath);\n\t\t\t} else {\n\t\t\t\tfs.writeFileSync(vsCodeConfigFilePath, json);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Implement path mapping and path skipping in Xdebug.\n *\n * @param name The configuration name.\n * @param mounts The mounts options.\n * @param pathSkippings The skipping paths options.\n * @returns Xdebug options\n */\nexport function makeXdebugConfig({\n\tcwd,\n\tmounts,\n\tpathSkippings,\n}: XdebugConfig): XdebugOptions {\n\tconst pathMappings =\n\t\tcwd && mounts ? filterLocalMounts(cwd, mounts) : undefined;\n\n\treturn { pathMappings, pathSkippings };\n}\n\nfunction jsoncApplyEdits(content: string, edits: JSONC.Edit[]) {\n\tconst errors: JSONC.ParseError[] = [];\n\tconst json = JSONC.applyEdits(content, edits);\n\n\terrors.length = 0;\n\n\tJSONC.parseTree(json, errors, jsoncParseOptions);\n\n\tif (errors.length) {\n\t\tconst formattedErrors = errors\n\t\t\t.map((error) => {\n\t\t\t\treturn {\n\t\t\t\t\tmessage: JSONC.printParseErrorCode(error.error),\n\t\t\t\t\toffset: error.offset,\n\t\t\t\t\tlength: error.length,\n\t\t\t\t\tfragment: json.slice(\n\t\t\t\t\t\tMath.max(0, error.offset - 20),\n\t\t\t\t\t\tMath.min(json.length, error.offset + error.length + 10)\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t})\n\t\t\t.map(\n\t\t\t\t(error) =>\n\t\t\t\t\t`${error.message} at ${error.offset}:${error.length} (${error.fragment})`\n\t\t\t);\n\t\tconst formattedEdits = edits.map(\n\t\t\t(edit) => `At ${edit.offset}:${edit.length} - (${edit.content})`\n\t\t);\n\t\tthrow new Error(\n\t\t\t`VS Code configuration file (.vscode/launch.json) is not valid a JSONC after CLI modifications. This is likely ` +\n\t\t\t\t`a CLI bug. Please report it at https://github.com/WordPress/wordpress-playground/issues and include the contents ` +\n\t\t\t\t`of your \".vscode/launch.json\" file. \\n\\n Applied edits: ${formattedEdits.join(\n\t\t\t\t\t'\\n'\n\t\t\t\t)}\\n\\n The errors are: ${formattedErrors.join('\\n')}`\n\t\t);\n\t}\n\n\treturn json;\n}\n"],"names":["DEFAULT_IDE_KEY","DEFAULT_PATH_SKIPPINGS","createTempDirSymlink","nativeDirPath","symlinkPath","platform","type","fs","removeTempDirSymlink","filterLocalMounts","cwd","mounts","mount","absoluteHostPath","path","cwdChildPrefix","xmlParserOptions","xmlBuilderOptions","jsoncParseOptions","updatePhpStormWorkspaceConfig","xmlContent","options","name","host","port","pathMappings","ideKey","xmlParser","XMLParser","config","serverElement","pathMapping","toPosixPath","projectElement","c","projectVersion","_a","componentElement","_b","serversElement","_c","serverElementIndex","_d","runManagerElement","_e","_f","runConfigElement","xml","XMLBuilder","updatePhpStormPHPConfig","pathSkippings","skippedFilesElement","skippedPath","filePath","updateVSCodeConfig","jsonContent","errors","content","root","JSONC","configurationsNode","edits","configurationIndex","child","configuration","acc","currentLength","jsoncApplyEdits","addXdebugIDEConfig","ides","modifiedConfig","phpStormRelativeConfigFilePath","phpStormConfigFilePath","contents","updatedXml","phpStormRelativePHPConfigFilePath","phpStormPHPConfigFilePath","vsCodeRelativeConfigFilePath","vsCodeConfigFilePath","updatedJson","clearXdebugIDEConfig","componentIndex","json","makeXdebugConfig","formattedErrors","error","formattedEdits","edit"],"mappings":"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"}

@@ -8,2 +8,3 @@ import type { Mount } from './mounts';

export declare const DEFAULT_IDE_KEY = "PHPWASMCLI";
export declare const DEFAULT_PATH_SKIPPINGS: string[];
/**

@@ -65,2 +66,6 @@ * Create a symlink to a tempory directory.

/**
* The paths to skip when debugging.
*/
pathSkippings?: string[];
/**
* The IDE key to use for the debug configuration. Defaults to 'PHPWASMCLI'.

@@ -70,3 +75,3 @@ */

};
export type PhpStormConfigOptions = {
export type PhpStormWorkspaceConfigOptions = {
name: string;

@@ -76,3 +81,3 @@ host: string;

projectDir: string;
mappings?: Mount[];
pathMappings?: Mount[];
ideKey: string;

@@ -88,7 +93,20 @@ };

*/
export declare function updatePhpStormConfig(xmlContent: string, options: PhpStormConfigOptions): string;
export declare function updatePhpStormWorkspaceConfig(xmlContent: string, options: PhpStormWorkspaceConfigOptions): string;
export type PhpStormPHPConfigOptions = {
pathSkippings?: string[];
};
/**
* Pure function to update PhpStorm php.xml config with skipped files.
*
* @param xmlContent The original XML content of php.xml
* @param options Configuration options for skipped files
* @returns Updated XML content
* @throws Error if XML is invalid or configuration is incompatible
*/
export declare function updatePhpStormPHPConfig(xmlContent: string, options: PhpStormPHPConfigOptions): string;
export type VSCodeConfigOptions = {
name: string;
workspaceDir: string;
mappings?: Mount[];
pathMappings?: Mount[];
pathSkippings?: string[];
};

@@ -110,3 +128,3 @@ /**

*/
export declare function addXdebugIDEConfig({ name, ides, host, port, cwd, mounts, ideKey, }: IDEConfig): Promise<Record<string, string>>;
export declare function addXdebugIDEConfig({ name, ides, host, port, cwd, mounts, pathSkippings, ideKey, }: IDEConfig): Promise<Record<string, string>>;
/**

@@ -113,0 +131,0 @@ * Remove stale parameters and path mappings in IDE configuration files.

{
"name": "@php-wasm/cli-util",
"version": "3.1.18",
"version": "3.1.19",
"description": "Utilities for PHP.wasm related CLIs",

@@ -34,3 +34,3 @@ "repository": {

"license": "GPL-2.0-or-later",
"gitHead": "556d5464c00b85ced0a505a31968b3fa1753eb28",
"gitHead": "be542ee28a5966eeb28154cd8e3723db5ff9df07",
"engines": {

@@ -43,3 +43,3 @@ "node": ">=20.10.0",

"jsonc-parser": "3.3.1",
"@php-wasm/util": "3.1.18"
"@php-wasm/util": "3.1.19"
},

@@ -46,0 +46,0 @@ "packageManager": "npm@10.9.2",