@php-wasm/cli-util 3.1.2 → 3.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs CHANGED
@@ -1,21 +1,21 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("fs"),P=require("path"),T=require("@php-wasm/util"),j=require("fast-xml-parser"),A=require("jsonc-parser");function X(s){const a=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const n in s)if(n!=="default"){const c=Object.getOwnPropertyDescriptor(s,n);Object.defineProperty(a,n,c.get?c:{enumerable:!0,get:()=>s[n]})}}return a.default=s,Object.freeze(a)}const v=X(A);async function _(s,a,n){const c=n==="win32"?"junction":"dir";f.symlinkSync(s,a,c)}async function B(s){try{f.lstatSync(s).isSymbolicLink()&&f.unlinkSync(s)}catch{}}function R(s,a){return a.filter(n=>{const c=P.resolve(n.hostPath),h=P.join(s,P.sep);return c===s||c.startsWith(h)})}const x={ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,cdataPropName:"__cdata",commentPropName:"__xmlComment",allowBooleanAttributes:!0,trimValues:!0},k={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 M(s,a){var E,I,D,F,L,O;const{name:n,host:c,port:h,mappings:p,ideKey:o}=a,u=new j.XMLParser(x),g=(()=>{try{return u.parse(s,!0)}catch{throw new Error("PhpStorm configuration file is not valid XML.")}})(),m={server:[{}],":@":{name:n,host:`${c}:${h}`,use_path_mappings:"true"}};p&&p.length&&(m.server[0].path_mappings=p.map(e=>({mapping:[],":@":{"local-root":`$PROJECT_DIR$/${T.toPosixPath(P.relative(a.projectDir,e.hostPath))}`,"remote-root":e.vfsPath}})));let t=g==null?void 0:g.find(e=>!!(e!=null&&e.project));if(t){const e=(E=t[":@"])==null?void 0:E.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}".`)}t===void 0&&(t={project:[],":@":{version:"4"}},g.push(t));let r=(I=t.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"});r===void 0&&(r={component:[],":@":{name:"PhpServers"}},t.project===void 0&&(t.project=[]),t.project.push(r));let l=(D=r.component)==null?void 0:D.find(e=>!!(e!=null&&e.servers));l===void 0&&(l={servers:[]},r.component===void 0&&(r.component=[]),r.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)===n});(y===void 0||y<0)&&(l.servers===void 0&&(l.servers=[]),l.servers.push(m));let d=(L=t.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"}},t.project===void 0&&(t.project=[]),t.project.push(d)),(((O=d.component)==null?void 0:O.findIndex(e=>{var S;return!!(e!=null&&e.configuration)&&((S=e==null?void 0:e[":@"])==null?void 0:S.name)===n}))??-1)<0){const e={configuration:[{method:[],":@":{v:"2"}}],":@":{name:n,type:"PhpRemoteDebugRunConfigurationType",factoryName:"PHP Remote Debug",filter_connections:"FILTER",server_name:n,session_id:o}};d.component===void 0&&(d.component=[]),d.component.push(e)}const b=new j.XMLBuilder(k).build(g);try{u.parse(b,!0)}catch{throw new Error("The resulting PhpStorm configuration file is not valid XML.")}return b}function N(s,a){var m,t;const{name:n,mappings:c}=a,h=[];let p=s,o=v.parseTree(p,h,C);if(o===void 0||h.length)throw new Error("VS Code configuration file is not valid JSON.");let u=v.findNodeAtLocation(o,["configurations"]);if(u===void 0||u.children===void 0){const r=v.modify(p,["configurations"],[],{});p=v.applyEdits(p,r),o=v.parseTree(p,[],C),u=v.findNodeAtLocation(o,["configurations"])}const g=(m=u==null?void 0:u.children)==null?void 0:m.findIndex(r=>{var l;return((l=v.findNodeAtLocation(r,["name"]))==null?void 0:l.value)===n});if(g===void 0||g<0){const r={name:n,type:"php",request:"launch",port:9003};c&&c.length&&(r.pathMappings=c.reduce((d,i)=>(d[i.vfsPath]=`\${workspaceFolder}/${T.toPosixPath(P.relative(a.workspaceDir,i.hostPath))}`,d),{}));const l=((t=u==null?void 0:u.children)==null?void 0:t.length)||0,y=v.modify(p,["configurations",l],r,{formattingOptions:{insertSpaces:!0,tabSize:4,eol:`
2
- `}});p=$(p,y)}return p}async function q({name:s,ides:a,host:n,port:c,cwd:h,mounts:p,ideKey:o="PHPWASMCLI"}){const u=p?R(h,p):[],g={};if(a.includes("phpstorm")){const m=".idea/workspace.xml",t=P.join(h,m);if(!f.existsSync(t)){if(f.existsSync(P.dirname(t)))f.writeFileSync(t,`<?xml version="1.0" encoding="UTF-8"?>
1
+ "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:`
2
+ `}});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"?>
3
3
  <project version="4">
4
- </project>`);else if(a.length==1)throw new Error("PhpStorm IDE integration requested, but no '.idea' directory was found in the current working directory.")}if(f.existsSync(t)){const r=f.readFileSync(t,"utf8"),l=M(r,{name:s,host:n,port:c,projectDir:h,mappings:u,ideKey:o});f.writeFileSync(t,l),g.phpstorm=m}}if(a.includes("vscode")){const m=".vscode/launch.json",t=P.join(h,m);if(!f.existsSync(t)){if(f.existsSync(P.dirname(t)))f.writeFileSync(t,`{
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,`{
5
5
  "configurations": []
6
- }`);else if(a.length==1)throw new Error("VS Code IDE integration requested, but no '.vscode' directory was found in the current working directory.")}if(f.existsSync(t)){const r=f.readFileSync(t,"utf-8"),l=N(r,{name:s,workspaceDir:h,mappings:u});l!==r&&(f.writeFileSync(t,l),g.vscode=m)}}return g}async function V(s,a){var h,p,o,u;const n=P.join(a,".idea/workspace.xml");if(f.existsSync(n)){const g=f.readFileSync(n,"utf8"),m=new j.XMLParser(x),t=(()=>{try{return m.parse(g,!0)}catch{throw new Error("PhpStorm configuration file is not valid XML.")}})(),r=t.find(i=>!!(i!=null&&i.project)),l=(h=r==null?void 0:r.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"}),y=(p=l==null?void 0:l.component)==null?void 0:p.find(i=>!!(i!=null&&i.servers)),d=(o=y==null?void 0:y.servers)==null?void 0:o.findIndex(i=>{var w;return!!(i!=null&&i.server)&&((w=i==null?void 0:i[":@"])==null?void 0:w.name)===s});if(d!==void 0&&d>=0){y.servers.splice(d,1);const w=new j.XMLBuilder(k).build(t);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"?>
6
+ }`);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"?>
7
7
  <project version="4">
8
8
  <component name="PhpServers">
9
9
  <servers></servers>
10
10
  </component>
11
- </project>`?f.unlinkSync(n):f.writeFileSync(n,w)}}const c=P.join(a,".vscode/launch.json");if(f.existsSync(c)){const g=[],m=f.readFileSync(c,"utf-8"),t=v.parseTree(m,g,C);if(t===void 0||g.length)throw new Error("VS Code configuration file is not valid JSON.");const r=v.findNodeAtLocation(t,["configurations"]),l=(u=r==null?void 0:r.children)==null?void 0:u.findIndex(y=>{var d;return((d=v.findNodeAtLocation(y,["name"]))==null?void 0:d.value)===s});if(l!==void 0&&l>=0){const y=v.modify(m,["configurations",l],void 0,{formattingOptions:{insertSpaces:!0,tabSize:4,eol:`
11
+ </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:`
12
12
  `}}),d=$(m,y);d===`{
13
13
  "configurations": []
14
- }`?f.unlinkSync(c):f.writeFileSync(c,d)}}}function $(s,a){const n=[],c=v.applyEdits(s,a);if(n.length=0,v.parseTree(c,n,C),n.length){const h=n.map(o=>({message:v.printParseErrorCode(o.error),offset:o.offset,length:o.length,fragment:c.slice(Math.max(0,o.offset-20),Math.min(c.length,o.offset+o.length+10))})).map(o=>`${o.message} at ${o.offset}:${o.length} (${o.fragment})`),p=a.map(o=>`At ${o.offset}:${o.length} - (${o.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.
14
+ }`?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.
15
15
 
16
- Applied edits: ${p.join(`
16
+ Applied edits: ${f.join(`
17
17
  `)}
18
18
 
19
19
  The errors are: ${h.join(`
20
- `)}`)}return c}exports.addXdebugIDEConfig=q;exports.clearXdebugIDEConfig=V;exports.createTempDirSymlink=_;exports.removeTempDirSymlink=B;exports.updatePhpStormConfig=M;exports.updateVSCodeConfig=N;
20
+ `)}`)}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;
21
21
  //# sourceMappingURL=index.cjs.map
package/index.cjs.map CHANGED
@@ -1 +1 @@
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\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 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 'PLAYGROUNDCLI'.\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 launch.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 = 'PHPWASMCLI',\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\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":["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","formattedErrors","error","formattedEdits","edit"],"mappings":"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"}
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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"}
package/index.js CHANGED
@@ -1,30 +1,31 @@
1
- import a from "fs";
1
+ import f from "fs";
2
2
  import P from "path";
3
- import { toPosixPath as k } from "@php-wasm/util";
4
- import { XMLParser as T, XMLBuilder as A } from "fast-xml-parser";
3
+ import { toPosixPath as D } from "@php-wasm/util";
4
+ import { XMLParser as T, XMLBuilder as $ } from "fast-xml-parser";
5
5
  import * as v from "jsonc-parser";
6
- async function J(d, f, s) {
7
- const p = s === "win32" ? (
6
+ const O = "PHPWASMCLI";
7
+ async function q(c, a, r) {
8
+ const p = r === "win32" ? (
8
9
  // On Windows, creating a 'dir' symlink can require elevated permissions.
9
10
  // In this case, let's make junction points because they function like
10
11
  // symlinks and do not require elevated permissions.
11
12
  "junction"
12
13
  ) : "dir";
13
- a.symlinkSync(d, f, p);
14
+ f.symlinkSync(c, a, p);
14
15
  }
15
- async function q(d) {
16
+ async function H(c) {
16
17
  try {
17
- a.lstatSync(d).isSymbolicLink() && a.unlinkSync(d);
18
+ f.lstatSync(c).isSymbolicLink() && f.unlinkSync(c);
18
19
  } catch {
19
20
  }
20
21
  }
21
- function M(d, f) {
22
- return f.filter((s) => {
23
- const p = P.resolve(s.hostPath), h = P.join(d, P.sep);
22
+ function A(c, a) {
23
+ return a.filter((r) => {
24
+ const p = P.resolve(r.hostPath), h = P.join(c, P.sep);
24
25
  return (
25
26
  // If auto-mounting from the current directory,
26
27
  // the entire project directory can be mapped.
27
- p === d || p.startsWith(h)
28
+ p === c || p.startsWith(h)
28
29
  );
29
30
  });
30
31
  }
@@ -36,7 +37,7 @@ const x = {
36
37
  commentPropName: "__xmlComment",
37
38
  allowBooleanAttributes: !0,
38
39
  trimValues: !0
39
- }, D = {
40
+ }, M = {
40
41
  ignoreAttributes: x.ignoreAttributes,
41
42
  attributeNamePrefix: x.attributeNamePrefix,
42
43
  preserveOrder: x.preserveOrder,
@@ -49,18 +50,18 @@ const x = {
49
50
  allowEmptyContent: !0,
50
51
  allowTrailingComma: !0
51
52
  };
52
- function O(d, f) {
53
- var E, b, I, F, L, $;
54
- const { name: s, host: p, port: h, mappings: l, ideKey: t } = f, m = new T(x), g = (() => {
53
+ function _(c, a) {
54
+ var E, b, I, F, L, k;
55
+ const { name: r, host: p, port: h, mappings: l, ideKey: t } = a, m = new T(x), g = (() => {
55
56
  try {
56
- return m.parse(d, !0);
57
+ return m.parse(c, !0);
57
58
  } catch {
58
59
  throw new Error("PhpStorm configuration file is not valid XML.");
59
60
  }
60
61
  })(), u = {
61
62
  server: [{}],
62
63
  ":@": {
63
- name: s,
64
+ name: r,
64
65
  // NOTE: PhpStorm quirk: Xdebug only works when the full URL (including port)
65
66
  // is provided in `host`. The separate `port` field is ignored or misinterpreted,
66
67
  // so we rely solely on host: "host:port".
@@ -71,8 +72,8 @@ function O(d, f) {
71
72
  l && l.length && (u.server[0].path_mappings = l.map((e) => ({
72
73
  mapping: [],
73
74
  ":@": {
74
- "local-root": `$PROJECT_DIR$/${k(
75
- P.relative(f.projectDir, e.hostPath)
75
+ "local-root": `$PROJECT_DIR$/${D(
76
+ P.relative(a.projectDir, e.hostPath)
76
77
  )}`,
77
78
  "remote-root": e.vfsPath
78
79
  }
@@ -103,30 +104,30 @@ function O(d, f) {
103
104
  component: [],
104
105
  ":@": { name: "PhpServers" }
105
106
  }, n.project === void 0 && (n.project = []), n.project.push(o));
106
- let i = (I = o.component) == null ? void 0 : I.find(
107
+ let s = (I = o.component) == null ? void 0 : I.find(
107
108
  (e) => !!(e != null && e.servers)
108
109
  );
109
- i === void 0 && (i = { servers: [] }, o.component === void 0 && (o.component = []), o.component.push(i));
110
- const y = (F = i.servers) == null ? void 0 : F.findIndex(
110
+ s === void 0 && (s = { servers: [] }, o.component === void 0 && (o.component = []), o.component.push(s));
111
+ const y = (F = s.servers) == null ? void 0 : F.findIndex(
111
112
  (e) => {
112
113
  var S;
113
- return !!(e != null && e.server) && ((S = e == null ? void 0 : e[":@"]) == null ? void 0 : S.name) === s;
114
+ return !!(e != null && e.server) && ((S = e == null ? void 0 : e[":@"]) == null ? void 0 : S.name) === r;
114
115
  }
115
116
  );
116
- (y === void 0 || y < 0) && (i.servers === void 0 && (i.servers = []), i.servers.push(u));
117
- let c = (L = n.project) == null ? void 0 : L.find(
117
+ (y === void 0 || y < 0) && (s.servers === void 0 && (s.servers = []), s.servers.push(u));
118
+ let d = (L = n.project) == null ? void 0 : L.find(
118
119
  (e) => {
119
120
  var S;
120
121
  return !!(e != null && e.component) && ((S = e == null ? void 0 : e[":@"]) == null ? void 0 : S.name) === "RunManager";
121
122
  }
122
123
  );
123
- if (c === void 0 && (c = {
124
+ if (d === void 0 && (d = {
124
125
  component: [],
125
126
  ":@": { name: "RunManager" }
126
- }, n.project === void 0 && (n.project = []), n.project.push(c)), ((($ = c.component) == null ? void 0 : $.findIndex(
127
+ }, n.project === void 0 && (n.project = []), n.project.push(d)), (((k = d.component) == null ? void 0 : k.findIndex(
127
128
  (e) => {
128
129
  var S;
129
- return !!(e != null && e.configuration) && ((S = e == null ? void 0 : e[":@"]) == null ? void 0 : S.name) === s;
130
+ return !!(e != null && e.configuration) && ((S = e == null ? void 0 : e[":@"]) == null ? void 0 : S.name) === r;
130
131
  }
131
132
  )) ?? -1) < 0) {
132
133
  const e = {
@@ -137,17 +138,17 @@ function O(d, f) {
137
138
  }
138
139
  ],
139
140
  ":@": {
140
- name: s,
141
+ name: r,
141
142
  type: "PhpRemoteDebugRunConfigurationType",
142
143
  factoryName: "PHP Remote Debug",
143
144
  filter_connections: "FILTER",
144
- server_name: s,
145
+ server_name: r,
145
146
  session_id: t
146
147
  }
147
148
  };
148
- c.component === void 0 && (c.component = []), c.component.push(e);
149
+ d.component === void 0 && (d.component = []), d.component.push(e);
149
150
  }
150
- const C = new A(D).build(g);
151
+ const C = new $(M).build(g);
151
152
  try {
152
153
  m.parse(C, !0);
153
154
  } catch {
@@ -157,10 +158,10 @@ function O(d, f) {
157
158
  }
158
159
  return C;
159
160
  }
160
- function _(d, f) {
161
+ function B(c, a) {
161
162
  var u, n;
162
- const { name: s, mappings: p } = f, h = [];
163
- let l = d, t = v.parseTree(l, h, j);
163
+ const { name: r, mappings: p } = a, h = [];
164
+ let l = c, t = v.parseTree(l, h, j);
164
165
  if (t === void 0 || h.length)
165
166
  throw new Error("VS Code configuration file is not valid JSON.");
166
167
  let m = v.findNodeAtLocation(t, ["configurations"]);
@@ -172,23 +173,23 @@ function _(d, f) {
172
173
  }
173
174
  const g = (u = m == null ? void 0 : m.children) == null ? void 0 : u.findIndex(
174
175
  (o) => {
175
- var i;
176
- return ((i = v.findNodeAtLocation(o, ["name"])) == null ? void 0 : i.value) === s;
176
+ var s;
177
+ return ((s = v.findNodeAtLocation(o, ["name"])) == null ? void 0 : s.value) === r;
177
178
  }
178
179
  );
179
180
  if (g === void 0 || g < 0) {
180
181
  const o = {
181
- name: s,
182
+ name: r,
182
183
  type: "php",
183
184
  request: "launch",
184
185
  port: 9003
185
186
  };
186
- p && p.length && (o.pathMappings = p.reduce((c, r) => (c[r.vfsPath] = `\${workspaceFolder}/${k(
187
- P.relative(f.workspaceDir, r.hostPath)
188
- )}`, c), {}));
189
- const i = ((n = m == null ? void 0 : m.children) == null ? void 0 : n.length) || 0, y = v.modify(
187
+ p && p.length && (o.pathMappings = p.reduce((d, i) => (d[i.vfsPath] = `\${workspaceFolder}/${D(
188
+ P.relative(a.workspaceDir, i.hostPath)
189
+ )}`, d), {}));
190
+ const s = ((n = m == null ? void 0 : m.children) == null ? void 0 : n.length) || 0, y = v.modify(
190
191
  l,
191
- ["configurations", i],
192
+ ["configurations", s],
192
193
  o,
193
194
  {
194
195
  formattingOptions: {
@@ -203,80 +204,80 @@ function _(d, f) {
203
204
  }
204
205
  return l;
205
206
  }
206
- async function H({
207
- name: d,
208
- ides: f,
209
- host: s,
207
+ async function U({
208
+ name: c,
209
+ ides: a,
210
+ host: r,
210
211
  port: p,
211
212
  cwd: h,
212
213
  mounts: l,
213
- ideKey: t = "PHPWASMCLI"
214
+ ideKey: t = O
214
215
  }) {
215
- const m = l ? M(h, l) : [], g = {};
216
- if (f.includes("phpstorm")) {
216
+ const m = l ? A(h, l) : [], g = {};
217
+ if (a.includes("phpstorm")) {
217
218
  const u = ".idea/workspace.xml", n = P.join(
218
219
  h,
219
220
  u
220
221
  );
221
- if (!a.existsSync(n)) {
222
- if (a.existsSync(P.dirname(n)))
223
- a.writeFileSync(
222
+ if (!f.existsSync(n)) {
223
+ if (f.existsSync(P.dirname(n)))
224
+ f.writeFileSync(
224
225
  n,
225
226
  `<?xml version="1.0" encoding="UTF-8"?>
226
227
  <project version="4">
227
228
  </project>`
228
229
  );
229
- else if (f.length == 1)
230
+ else if (a.length == 1)
230
231
  throw new Error(
231
232
  "PhpStorm IDE integration requested, but no '.idea' directory was found in the current working directory."
232
233
  );
233
234
  }
234
- if (a.existsSync(n)) {
235
- const o = a.readFileSync(n, "utf8"), i = O(o, {
236
- name: d,
237
- host: s,
235
+ if (f.existsSync(n)) {
236
+ const o = f.readFileSync(n, "utf8"), s = _(o, {
237
+ name: c,
238
+ host: r,
238
239
  port: p,
239
240
  projectDir: h,
240
241
  mappings: m,
241
242
  ideKey: t
242
243
  });
243
- a.writeFileSync(n, i), g.phpstorm = u;
244
+ f.writeFileSync(n, s), g.phpstorm = u;
244
245
  }
245
246
  }
246
- if (f.includes("vscode")) {
247
+ if (a.includes("vscode")) {
247
248
  const u = ".vscode/launch.json", n = P.join(
248
249
  h,
249
250
  u
250
251
  );
251
- if (!a.existsSync(n)) {
252
- if (a.existsSync(P.dirname(n)))
253
- a.writeFileSync(
252
+ if (!f.existsSync(n)) {
253
+ if (f.existsSync(P.dirname(n)))
254
+ f.writeFileSync(
254
255
  n,
255
256
  `{
256
257
  "configurations": []
257
258
  }`
258
259
  );
259
- else if (f.length == 1)
260
+ else if (a.length == 1)
260
261
  throw new Error(
261
262
  "VS Code IDE integration requested, but no '.vscode' directory was found in the current working directory."
262
263
  );
263
264
  }
264
- if (a.existsSync(n)) {
265
- const o = a.readFileSync(n, "utf-8"), i = _(o, {
266
- name: d,
265
+ if (f.existsSync(n)) {
266
+ const o = f.readFileSync(n, "utf-8"), s = B(o, {
267
+ name: c,
267
268
  workspaceDir: h,
268
269
  mappings: m
269
270
  });
270
- i !== o && (a.writeFileSync(n, i), g.vscode = u);
271
+ s !== o && (f.writeFileSync(n, s), g.vscode = u);
271
272
  }
272
273
  }
273
274
  return g;
274
275
  }
275
- async function W(d, f) {
276
+ async function W(c, a) {
276
277
  var h, l, t, m;
277
- const s = P.join(f, ".idea/workspace.xml");
278
- if (a.existsSync(s)) {
279
- const g = a.readFileSync(s, "utf8"), u = new T(x), n = (() => {
278
+ const r = P.join(a, ".idea/workspace.xml");
279
+ if (f.existsSync(r)) {
280
+ const g = f.readFileSync(r, "utf8"), u = new T(x), n = (() => {
280
281
  try {
281
282
  return u.parse(g, !0);
282
283
  } catch {
@@ -285,23 +286,23 @@ async function W(d, f) {
285
286
  );
286
287
  }
287
288
  })(), o = n.find(
288
- (r) => !!(r != null && r.project)
289
- ), i = (h = o == null ? void 0 : o.project) == null ? void 0 : h.find(
290
- (r) => {
289
+ (i) => !!(i != null && i.project)
290
+ ), s = (h = o == null ? void 0 : o.project) == null ? void 0 : h.find(
291
+ (i) => {
291
292
  var w;
292
- return !!(r != null && r.component) && ((w = r == null ? void 0 : r[":@"]) == null ? void 0 : w.name) === "PhpServers";
293
+ return !!(i != null && i.component) && ((w = i == null ? void 0 : i[":@"]) == null ? void 0 : w.name) === "PhpServers";
293
294
  }
294
- ), y = (l = i == null ? void 0 : i.component) == null ? void 0 : l.find(
295
- (r) => !!(r != null && r.servers)
296
- ), c = (t = y == null ? void 0 : y.servers) == null ? void 0 : t.findIndex(
297
- (r) => {
295
+ ), y = (l = s == null ? void 0 : s.component) == null ? void 0 : l.find(
296
+ (i) => !!(i != null && i.servers)
297
+ ), d = (t = y == null ? void 0 : y.servers) == null ? void 0 : t.findIndex(
298
+ (i) => {
298
299
  var w;
299
- return !!(r != null && r.server) && ((w = r == null ? void 0 : r[":@"]) == null ? void 0 : w.name) === d;
300
+ return !!(i != null && i.server) && ((w = i == null ? void 0 : i[":@"]) == null ? void 0 : w.name) === c;
300
301
  }
301
302
  );
302
- if (c !== void 0 && c >= 0) {
303
- y.servers.splice(c, 1);
304
- const w = new A(D).build(n);
303
+ if (d !== void 0 && d >= 0) {
304
+ y.servers.splice(d, 1);
305
+ const w = new $(M).build(n);
305
306
  try {
306
307
  u.parse(w, !0);
307
308
  } catch {
@@ -314,26 +315,26 @@ async function W(d, f) {
314
315
  <component name="PhpServers">
315
316
  <servers></servers>
316
317
  </component>
317
- </project>` ? a.unlinkSync(s) : a.writeFileSync(s, w);
318
+ </project>` ? f.unlinkSync(r) : f.writeFileSync(r, w);
318
319
  }
319
320
  }
320
- const p = P.join(f, ".vscode/launch.json");
321
- if (a.existsSync(p)) {
322
- const g = [], u = a.readFileSync(p, "utf-8"), n = v.parseTree(u, g, j);
321
+ const p = P.join(a, ".vscode/launch.json");
322
+ if (f.existsSync(p)) {
323
+ const g = [], u = f.readFileSync(p, "utf-8"), n = v.parseTree(u, g, j);
323
324
  if (n === void 0 || g.length)
324
325
  throw new Error("VS Code configuration file is not valid JSON.");
325
326
  const o = v.findNodeAtLocation(n, [
326
327
  "configurations"
327
- ]), i = (m = o == null ? void 0 : o.children) == null ? void 0 : m.findIndex(
328
+ ]), s = (m = o == null ? void 0 : o.children) == null ? void 0 : m.findIndex(
328
329
  (y) => {
329
- var c;
330
- return ((c = v.findNodeAtLocation(y, ["name"])) == null ? void 0 : c.value) === d;
330
+ var d;
331
+ return ((d = v.findNodeAtLocation(y, ["name"])) == null ? void 0 : d.value) === c;
331
332
  }
332
333
  );
333
- if (i !== void 0 && i >= 0) {
334
+ if (s !== void 0 && s >= 0) {
334
335
  const y = v.modify(
335
336
  u,
336
- ["configurations", i],
337
+ ["configurations", s],
337
338
  void 0,
338
339
  {
339
340
  formattingOptions: {
@@ -343,17 +344,24 @@ async function W(d, f) {
343
344
  `
344
345
  }
345
346
  }
346
- ), c = N(u, y);
347
- c === `{
347
+ ), d = N(u, y);
348
+ d === `{
348
349
  "configurations": []
349
- }` ? a.unlinkSync(p) : a.writeFileSync(p, c);
350
+ }` ? f.unlinkSync(p) : f.writeFileSync(p, d);
350
351
  }
351
352
  }
352
353
  }
353
- function N(d, f) {
354
- const s = [], p = v.applyEdits(d, f);
355
- if (s.length = 0, v.parseTree(p, s, j), s.length) {
356
- const h = s.map((t) => ({
354
+ function z({
355
+ cwd: c,
356
+ mounts: a,
357
+ pathSkippings: r
358
+ }) {
359
+ return { pathMappings: c && a ? A(c, a) : void 0, pathSkippings: r };
360
+ }
361
+ function N(c, a) {
362
+ const r = [], p = v.applyEdits(c, a);
363
+ if (r.length = 0, v.parseTree(p, r, j), r.length) {
364
+ const h = r.map((t) => ({
357
365
  message: v.printParseErrorCode(t.error),
358
366
  offset: t.offset,
359
367
  length: t.length,
@@ -363,7 +371,7 @@ function N(d, f) {
363
371
  )
364
372
  })).map(
365
373
  (t) => `${t.message} at ${t.offset}:${t.length} (${t.fragment})`
366
- ), l = f.map(
374
+ ), l = a.map(
367
375
  (t) => `At ${t.offset}:${t.length} - (${t.content})`
368
376
  );
369
377
  throw new Error(
@@ -381,11 +389,13 @@ function N(d, f) {
381
389
  return p;
382
390
  }
383
391
  export {
384
- H as addXdebugIDEConfig,
392
+ O as DEFAULT_IDE_KEY,
393
+ U as addXdebugIDEConfig,
385
394
  W as clearXdebugIDEConfig,
386
- J as createTempDirSymlink,
387
- q as removeTempDirSymlink,
388
- O as updatePhpStormConfig,
389
- _ as updateVSCodeConfig
395
+ q as createTempDirSymlink,
396
+ z as makeXdebugConfig,
397
+ H as removeTempDirSymlink,
398
+ _ as updatePhpStormConfig,
399
+ B as updateVSCodeConfig
390
400
  };
391
401
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1 +1 @@
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\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 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 'PLAYGROUNDCLI'.\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 launch.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 = 'PHPWASMCLI',\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\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":["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","formattedErrors","error","formattedEdits","edit"],"mappings":"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"}
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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"}
@@ -1,4 +1,10 @@
1
1
  import type { Mount } from './mounts';
2
+ export interface XdebugOptions {
3
+ ideKey?: string;
4
+ pathMappings?: Mount[];
5
+ pathSkippings?: string[];
6
+ }
7
+ export declare const DEFAULT_IDE_KEY = "PHPWASMCLI";
2
8
  /**
3
9
  * Create a symlink to a tempory directory.
4
10
  *
@@ -15,6 +21,20 @@ export declare function createTempDirSymlink(nativeDirPath: string, symlinkPath:
15
21
  * @param symlinkPath The symlink path.
16
22
  */
17
23
  export declare function removeTempDirSymlink(symlinkPath: string): Promise<void>;
24
+ export type XdebugConfig = {
25
+ /**
26
+ * The current working directory to consider for debugger path mapping.
27
+ */
28
+ cwd?: string;
29
+ /**
30
+ * The mounts to consider for debugger path mapping.
31
+ */
32
+ mounts?: Mount[];
33
+ /**
34
+ * The paths to consider for debugger path skipping.
35
+ */
36
+ pathSkippings?: string[];
37
+ };
18
38
  export type IDEConfig = {
19
39
  /**
20
40
  * The name of the configuration within the IDE configuration.
@@ -41,7 +61,7 @@ export type IDEConfig = {
41
61
  */
42
62
  mounts?: Mount[];
43
63
  /**
44
- * The IDE key to use for the debug configuration. Defaults to 'PLAYGROUNDCLI'.
64
+ * The IDE key to use for the debug configuration. Defaults to 'PHPWASMCLI'.
45
65
  */
46
66
  ideKey?: string;
47
67
  };
@@ -54,7 +74,7 @@ export type PhpStormConfigOptions = {
54
74
  ideKey: string;
55
75
  };
56
76
  /**
57
- * Pure function to update PHPStorm XML config with XDebug server and run configuration.
77
+ * Pure function to update PHPStorm XML config with Xdebug server and run configuration.
58
78
  *
59
79
  * @param xmlContent The original XML content of workspace.xml
60
80
  * @param options Configuration options for the server
@@ -68,7 +88,7 @@ export type VSCodeConfigOptions = {
68
88
  mappings?: Mount[];
69
89
  };
70
90
  /**
71
- * Pure function to update VS Code launch.json config with XDebug configuration.
91
+ * Pure function to update VS Code JSON config with Xdebug configuration.
72
92
  *
73
93
  * @param jsonContent The original JSON content of launch.json
74
94
  * @param options Configuration options
@@ -90,3 +110,12 @@ export declare function addXdebugIDEConfig({ name, ides, host, port, cwd, mounts
90
110
  * @param cwd The current working directory.
91
111
  */
92
112
  export declare function clearXdebugIDEConfig(name: string, cwd: string): Promise<void>;
113
+ /**
114
+ * Implement path mapping and path skipping in Xdebug.
115
+ *
116
+ * @param name The configuration name.
117
+ * @param mounts The mounts options.
118
+ * @param pathSkippings The skipping paths options.
119
+ * @returns Xdebug options
120
+ */
121
+ export declare function makeXdebugConfig({ cwd, mounts, pathSkippings, }: XdebugConfig): XdebugOptions;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@php-wasm/cli-util",
3
- "version": "3.1.2",
3
+ "version": "3.1.3",
4
4
  "description": "Utilities for PHP.wasm related CLIs",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,7 +31,7 @@
31
31
  "directory": "../../../dist/packages/php-wasm/cli-util"
32
32
  },
33
33
  "license": "GPL-2.0-or-later",
34
- "gitHead": "4a2f8903e9d4a58e33382f8f888ef94d42d913dc",
34
+ "gitHead": "54bb87ba4c9624ec02f60194a2f1938b3f42477b",
35
35
  "engines": {
36
36
  "node": ">=20.10.0",
37
37
  "npm": ">=10.2.3"
@@ -39,7 +39,7 @@
39
39
  "dependencies": {
40
40
  "fast-xml-parser": "^5.3.4",
41
41
  "jsonc-parser": "3.3.1",
42
- "@php-wasm/util": "3.1.2"
42
+ "@php-wasm/util": "3.1.3"
43
43
  },
44
44
  "packageManager": "npm@10.9.2",
45
45
  "overrides": {