@php-wasm/cli-util 3.0.27
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/README.md +11 -0
- package/index.cjs +21 -0
- package/index.cjs.map +1 -0
- package/index.d.ts +1 -0
- package/index.js +393 -0
- package/index.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/mounts.d.ts +4 -0
- package/lib/xdebug-path-mappings.d.ts +92 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# php-wasm-cli-util
|
|
2
|
+
|
|
3
|
+
This library was generated with [Nx](https://nx.dev).
|
|
4
|
+
|
|
5
|
+
## Building
|
|
6
|
+
|
|
7
|
+
Run `nx build php-wasm-cli-util` to build the library.
|
|
8
|
+
|
|
9
|
+
## Running unit tests
|
|
10
|
+
|
|
11
|
+
Run `nx test php-wasm-cli-util` to execute the unit tests via [Vitest](https://vitest.dev).
|
package/index.cjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("fs"),S=require("path"),j=require("fast-xml-parser"),A=require("jsonc-parser");function X(o){const a=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(o){for(const t in o)if(t!=="default"){const c=Object.getOwnPropertyDescriptor(o,t);Object.defineProperty(a,t,c.get?c:{enumerable:!0,get:()=>o[t]})}}return a.default=o,Object.freeze(a)}const v=X(A);async function _(o,a,t){const c=t==="win32"?"junction":"dir";p.symlinkSync(o,a,c)}async function B(o){try{p.lstatSync(o).isSymbolicLink()&&p.unlinkSync(o)}catch{}}function R(o,a){return a.filter(t=>{const c=S.resolve(t.hostPath),h=S.join(o,S.sep);return c===o||c.startsWith(h)})}const x={ignoreAttributes:!1,attributeNamePrefix:"",preserveOrder:!0,cdataPropName:"__cdata",commentPropName:"__xmlComment",allowBooleanAttributes:!0,trimValues:!0},T={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 k(o,a){var E,I,D,F,L,O;const{name:t,host:c,port:h,mappings:f,ideKey:r}=a,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:`${c}:${h}`,use_path_mappings:"true"}};f&&f.length&&(m.server[0].path_mappings=f.map(e=>({mapping:[],":@":{"local-root":`$PROJECT_DIR$/${$(S.relative(a.projectDir,e.hostPath))}`,"remote-root":e.vfsPath}})));let n=g==null?void 0:g.find(e=>!!(e!=null&&e.project));if(n){const e=(E=n[":@"])==null?void 0:E.version;if(e===void 0)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 i=(I=n.project)==null?void 0:I.find(e=>{var P;return!!(e!=null&&e.component)&&((P=e==null?void 0:e[":@"])==null?void 0:P.name)==="PhpServers"});i===void 0&&(i={component:[],":@":{name:"PhpServers"}},n.project===void 0&&(n.project=[]),n.project.push(i));let l=(D=i.component)==null?void 0:D.find(e=>!!(e!=null&&e.servers));l===void 0&&(l={servers:[]},i.component===void 0&&(i.component=[]),i.component.push(l));const y=(F=l.servers)==null?void 0:F.findIndex(e=>{var P;return!!(e!=null&&e.server)&&((P=e==null?void 0:e[":@"])==null?void 0:P.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 P;return!!(e!=null&&e.component)&&((P=e==null?void 0:e[":@"])==null?void 0:P.name)==="RunManager"});if(d===void 0&&(d={component:[],":@":{name:"RunManager"}},n.project===void 0&&(n.project=[]),n.project.push(d)),(((O=d.component)==null?void 0:O.findIndex(e=>{var P;return!!(e!=null&&e.configuration)&&((P=e==null?void 0:e[":@"])==null?void 0:P.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:r}};d.component===void 0&&(d.component=[]),d.component.push(e)}const b=new j.XMLBuilder(T).build(g);try{u.parse(b,!0)}catch{throw new Error("The resulting PhpStorm configuration file is not valid XML.")}return b}function M(o,a){var m,n;const{name:t,mappings:c}=a,h=[];let f=o,r=v.parseTree(f,h,C);if(r===void 0||h.length)throw new Error("VS Code configuration file is not valid JSON.");let u=v.findNodeAtLocation(r,["configurations"]);if(u===void 0||u.children===void 0){const i=v.modify(f,["configurations"],[],{});f=v.applyEdits(f,i),r=v.parseTree(f,[],C),u=v.findNodeAtLocation(r,["configurations"])}const g=(m=u==null?void 0:u.children)==null?void 0:m.findIndex(i=>{var l;return((l=v.findNodeAtLocation(i,["name"]))==null?void 0:l.value)===t});if(g===void 0||g<0){const i={name:t,type:"php",request:"launch",port:9003};c&&c.length&&(i.pathMappings=c.reduce((d,s)=>(d[s.vfsPath]=`\${workspaceFolder}/${$(S.relative(a.workspaceDir,s.hostPath))}`,d),{}));const l=((n=u==null?void 0:u.children)==null?void 0:n.length)||0,y=v.modify(f,["configurations",l],i,{formattingOptions:{insertSpaces:!0,tabSize:4,eol:`
|
|
2
|
+
`}});f=N(f,y)}return f}async function V({name:o,ides:a,host:t,port:c,cwd:h,mounts:f,ideKey:r="PHPWASMCLI"}){const u=f?R(h,f):[],g={};if(a.includes("phpstorm")){const m=".idea/workspace.xml",n=S.join(h,m);if(!p.existsSync(n)){if(p.existsSync(S.dirname(n)))p.writeFileSync(n,`<?xml version="1.0" encoding="UTF-8"?>
|
|
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(p.existsSync(n)){const i=p.readFileSync(n,"utf8"),l=k(i,{name:o,host:t,port:c,projectDir:h,mappings:u,ideKey:r});p.writeFileSync(n,l),g.phpstorm=m}}if(a.includes("vscode")){const m=".vscode/launch.json",n=S.join(h,m);if(!p.existsSync(n)){if(p.existsSync(S.dirname(n)))p.writeFileSync(n,`{
|
|
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(p.existsSync(n)){const i=p.readFileSync(n,"utf-8"),l=M(i,{name:o,workspaceDir:h,mappings:u});l!==i&&(p.writeFileSync(n,l),g.vscode=m)}}return g}async function q(o,a){var h,f,r,u;const t=S.join(a,".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.")}})(),i=n.find(s=>!!(s!=null&&s.project)),l=(h=i==null?void 0:i.project)==null?void 0:h.find(s=>{var w;return!!(s!=null&&s.component)&&((w=s==null?void 0:s[":@"])==null?void 0:w.name)==="PhpServers"}),y=(f=l==null?void 0:l.component)==null?void 0:f.find(s=>!!(s!=null&&s.servers)),d=(r=y==null?void 0:y.servers)==null?void 0:r.findIndex(s=>{var w;return!!(s!=null&&s.server)&&((w=s==null?void 0:s[":@"])==null?void 0:w.name)===o});if(d!==void 0&&d>=0){y.servers.splice(d,1);const w=new j.XMLBuilder(T).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
|
+
<project version="4">
|
|
8
|
+
<component name="PhpServers">
|
|
9
|
+
<servers></servers>
|
|
10
|
+
</component>
|
|
11
|
+
</project>`?p.unlinkSync(t):p.writeFileSync(t,w)}}const c=S.join(a,".vscode/launch.json");if(p.existsSync(c)){const g=[],m=p.readFileSync(c,"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 i=v.findNodeAtLocation(n,["configurations"]),l=(u=i==null?void 0:i.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
|
+
`}}),d=N(m,y);d===`{
|
|
13
|
+
"configurations": []
|
|
14
|
+
}`?p.unlinkSync(c):p.writeFileSync(c,d)}}}function N(o,a){const t=[],c=v.applyEdits(o,a);if(t.length=0,v.parseTree(c,t,C),t.length){const h=t.map(r=>({message:v.printParseErrorCode(r.error),offset:r.offset,length:r.length,fragment:c.slice(Math.max(0,r.offset-20),Math.min(c.length,r.offset+r.length+10))})).map(r=>`${r.message} at ${r.offset}:${r.length} (${r.fragment})`),f=a.map(r=>`At ${r.offset}:${r.length} - (${r.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
|
+
|
|
16
|
+
Applied edits: ${f.join(`
|
|
17
|
+
`)}
|
|
18
|
+
|
|
19
|
+
The errors are: ${h.join(`
|
|
20
|
+
`)}`)}return c}function $(o){return o.replaceAll(S.sep,S.posix.sep)}exports.addXdebugIDEConfig=V;exports.clearXdebugIDEConfig=q;exports.createTempDirSymlink=_;exports.removeTempDirSymlink=B;exports.updatePhpStormConfig=k;exports.updateVSCodeConfig=M;
|
|
21
|
+
//# sourceMappingURL=index.cjs.map
|
package/index.cjs.map
ADDED
|
@@ -0,0 +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 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\nfunction toPosixPath(pathStr: string) {\n\treturn pathStr.replaceAll(path.sep, path.posix.sep);\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","pathStr"],"mappings":"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"}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib';
|
package/index.js
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import a from "fs";
|
|
2
|
+
import S from "path";
|
|
3
|
+
import { XMLParser as k, XMLBuilder as A } from "fast-xml-parser";
|
|
4
|
+
import * as v from "jsonc-parser";
|
|
5
|
+
async function V(l, c, s) {
|
|
6
|
+
const p = s === "win32" ? (
|
|
7
|
+
// On Windows, creating a 'dir' symlink can require elevated permissions.
|
|
8
|
+
// In this case, let's make junction points because they function like
|
|
9
|
+
// symlinks and do not require elevated permissions.
|
|
10
|
+
"junction"
|
|
11
|
+
) : "dir";
|
|
12
|
+
a.symlinkSync(l, c, p);
|
|
13
|
+
}
|
|
14
|
+
async function J(l) {
|
|
15
|
+
try {
|
|
16
|
+
a.lstatSync(l).isSymbolicLink() && a.unlinkSync(l);
|
|
17
|
+
} catch {
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function M(l, c) {
|
|
21
|
+
return c.filter((s) => {
|
|
22
|
+
const p = S.resolve(s.hostPath), h = S.join(l, S.sep);
|
|
23
|
+
return (
|
|
24
|
+
// If auto-mounting from the current directory,
|
|
25
|
+
// the entire project directory can be mapped.
|
|
26
|
+
p === l || p.startsWith(h)
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const x = {
|
|
31
|
+
ignoreAttributes: !1,
|
|
32
|
+
attributeNamePrefix: "",
|
|
33
|
+
preserveOrder: !0,
|
|
34
|
+
cdataPropName: "__cdata",
|
|
35
|
+
commentPropName: "__xmlComment",
|
|
36
|
+
allowBooleanAttributes: !0,
|
|
37
|
+
trimValues: !0
|
|
38
|
+
}, T = {
|
|
39
|
+
ignoreAttributes: x.ignoreAttributes,
|
|
40
|
+
attributeNamePrefix: x.attributeNamePrefix,
|
|
41
|
+
preserveOrder: x.preserveOrder,
|
|
42
|
+
cdataPropName: x.cdataPropName,
|
|
43
|
+
commentPropName: x.commentPropName,
|
|
44
|
+
suppressBooleanAttributes: !x.allowBooleanAttributes,
|
|
45
|
+
format: !0,
|
|
46
|
+
indentBy: " "
|
|
47
|
+
}, j = {
|
|
48
|
+
allowEmptyContent: !0,
|
|
49
|
+
allowTrailingComma: !0
|
|
50
|
+
};
|
|
51
|
+
function O(l, c) {
|
|
52
|
+
var E, b, I, F, L, $;
|
|
53
|
+
const { name: s, host: p, port: h, mappings: f, ideKey: t } = c, u = new k(x), g = (() => {
|
|
54
|
+
try {
|
|
55
|
+
return u.parse(l, !0);
|
|
56
|
+
} catch {
|
|
57
|
+
throw new Error("PhpStorm configuration file is not valid XML.");
|
|
58
|
+
}
|
|
59
|
+
})(), m = {
|
|
60
|
+
server: [{}],
|
|
61
|
+
":@": {
|
|
62
|
+
name: s,
|
|
63
|
+
// NOTE: PhpStorm quirk: Xdebug only works when the full URL (including port)
|
|
64
|
+
// is provided in `host`. The separate `port` field is ignored or misinterpreted,
|
|
65
|
+
// so we rely solely on host: "host:port".
|
|
66
|
+
host: `${p}:${h}`,
|
|
67
|
+
use_path_mappings: "true"
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
f && f.length && (m.server[0].path_mappings = f.map((e) => ({
|
|
71
|
+
mapping: [],
|
|
72
|
+
":@": {
|
|
73
|
+
"local-root": `$PROJECT_DIR$/${N(
|
|
74
|
+
S.relative(c.projectDir, e.hostPath)
|
|
75
|
+
)}`,
|
|
76
|
+
"remote-root": e.vfsPath
|
|
77
|
+
}
|
|
78
|
+
})));
|
|
79
|
+
let n = g == null ? void 0 : g.find((e) => !!(e != null && e.project));
|
|
80
|
+
if (n) {
|
|
81
|
+
const e = (E = n[":@"]) == null ? void 0 : E.version;
|
|
82
|
+
if (e === void 0)
|
|
83
|
+
throw new Error(
|
|
84
|
+
'PhpStorm IDE integration only supports <project version="4"> in workspace.xml, but the <project> configuration has no version number.'
|
|
85
|
+
);
|
|
86
|
+
if (e !== "4")
|
|
87
|
+
throw new Error(
|
|
88
|
+
`PhpStorm IDE integration only supports <project version="4"> in workspace.xml, but we found a <project> configuration with version "${e}".`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
n === void 0 && (n = {
|
|
92
|
+
project: [],
|
|
93
|
+
":@": { version: "4" }
|
|
94
|
+
}, g.push(n));
|
|
95
|
+
let o = (b = n.project) == null ? void 0 : b.find(
|
|
96
|
+
(e) => {
|
|
97
|
+
var P;
|
|
98
|
+
return !!(e != null && e.component) && ((P = e == null ? void 0 : e[":@"]) == null ? void 0 : P.name) === "PhpServers";
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
o === void 0 && (o = {
|
|
102
|
+
component: [],
|
|
103
|
+
":@": { name: "PhpServers" }
|
|
104
|
+
}, n.project === void 0 && (n.project = []), n.project.push(o));
|
|
105
|
+
let i = (I = o.component) == null ? void 0 : I.find(
|
|
106
|
+
(e) => !!(e != null && e.servers)
|
|
107
|
+
);
|
|
108
|
+
i === void 0 && (i = { servers: [] }, o.component === void 0 && (o.component = []), o.component.push(i));
|
|
109
|
+
const y = (F = i.servers) == null ? void 0 : F.findIndex(
|
|
110
|
+
(e) => {
|
|
111
|
+
var P;
|
|
112
|
+
return !!(e != null && e.server) && ((P = e == null ? void 0 : e[":@"]) == null ? void 0 : P.name) === s;
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
(y === void 0 || y < 0) && (i.servers === void 0 && (i.servers = []), i.servers.push(m));
|
|
116
|
+
let d = (L = n.project) == null ? void 0 : L.find(
|
|
117
|
+
(e) => {
|
|
118
|
+
var P;
|
|
119
|
+
return !!(e != null && e.component) && ((P = e == null ? void 0 : e[":@"]) == null ? void 0 : P.name) === "RunManager";
|
|
120
|
+
}
|
|
121
|
+
);
|
|
122
|
+
if (d === void 0 && (d = {
|
|
123
|
+
component: [],
|
|
124
|
+
":@": { name: "RunManager" }
|
|
125
|
+
}, n.project === void 0 && (n.project = []), n.project.push(d)), ((($ = d.component) == null ? void 0 : $.findIndex(
|
|
126
|
+
(e) => {
|
|
127
|
+
var P;
|
|
128
|
+
return !!(e != null && e.configuration) && ((P = e == null ? void 0 : e[":@"]) == null ? void 0 : P.name) === s;
|
|
129
|
+
}
|
|
130
|
+
)) ?? -1) < 0) {
|
|
131
|
+
const e = {
|
|
132
|
+
configuration: [
|
|
133
|
+
{
|
|
134
|
+
method: [],
|
|
135
|
+
":@": { v: "2" }
|
|
136
|
+
}
|
|
137
|
+
],
|
|
138
|
+
":@": {
|
|
139
|
+
name: s,
|
|
140
|
+
type: "PhpRemoteDebugRunConfigurationType",
|
|
141
|
+
factoryName: "PHP Remote Debug",
|
|
142
|
+
filter_connections: "FILTER",
|
|
143
|
+
server_name: s,
|
|
144
|
+
session_id: t
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
d.component === void 0 && (d.component = []), d.component.push(e);
|
|
148
|
+
}
|
|
149
|
+
const C = new A(T).build(g);
|
|
150
|
+
try {
|
|
151
|
+
u.parse(C, !0);
|
|
152
|
+
} catch {
|
|
153
|
+
throw new Error(
|
|
154
|
+
"The resulting PhpStorm configuration file is not valid XML."
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
return C;
|
|
158
|
+
}
|
|
159
|
+
function _(l, c) {
|
|
160
|
+
var m, n;
|
|
161
|
+
const { name: s, mappings: p } = c, h = [];
|
|
162
|
+
let f = l, t = v.parseTree(f, h, j);
|
|
163
|
+
if (t === void 0 || h.length)
|
|
164
|
+
throw new Error("VS Code configuration file is not valid JSON.");
|
|
165
|
+
let u = v.findNodeAtLocation(t, ["configurations"]);
|
|
166
|
+
if (u === void 0 || u.children === void 0) {
|
|
167
|
+
const o = v.modify(f, ["configurations"], [], {});
|
|
168
|
+
f = v.applyEdits(f, o), t = v.parseTree(f, [], j), u = v.findNodeAtLocation(t, [
|
|
169
|
+
"configurations"
|
|
170
|
+
]);
|
|
171
|
+
}
|
|
172
|
+
const g = (m = u == null ? void 0 : u.children) == null ? void 0 : m.findIndex(
|
|
173
|
+
(o) => {
|
|
174
|
+
var i;
|
|
175
|
+
return ((i = v.findNodeAtLocation(o, ["name"])) == null ? void 0 : i.value) === s;
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
if (g === void 0 || g < 0) {
|
|
179
|
+
const o = {
|
|
180
|
+
name: s,
|
|
181
|
+
type: "php",
|
|
182
|
+
request: "launch",
|
|
183
|
+
port: 9003
|
|
184
|
+
};
|
|
185
|
+
p && p.length && (o.pathMappings = p.reduce((d, r) => (d[r.vfsPath] = `\${workspaceFolder}/${N(
|
|
186
|
+
S.relative(c.workspaceDir, r.hostPath)
|
|
187
|
+
)}`, d), {}));
|
|
188
|
+
const i = ((n = u == null ? void 0 : u.children) == null ? void 0 : n.length) || 0, y = v.modify(
|
|
189
|
+
f,
|
|
190
|
+
["configurations", i],
|
|
191
|
+
o,
|
|
192
|
+
{
|
|
193
|
+
formattingOptions: {
|
|
194
|
+
insertSpaces: !0,
|
|
195
|
+
tabSize: 4,
|
|
196
|
+
eol: `
|
|
197
|
+
`
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
f = D(f, y);
|
|
202
|
+
}
|
|
203
|
+
return f;
|
|
204
|
+
}
|
|
205
|
+
async function q({
|
|
206
|
+
name: l,
|
|
207
|
+
ides: c,
|
|
208
|
+
host: s,
|
|
209
|
+
port: p,
|
|
210
|
+
cwd: h,
|
|
211
|
+
mounts: f,
|
|
212
|
+
ideKey: t = "PHPWASMCLI"
|
|
213
|
+
}) {
|
|
214
|
+
const u = f ? M(h, f) : [], g = {};
|
|
215
|
+
if (c.includes("phpstorm")) {
|
|
216
|
+
const m = ".idea/workspace.xml", n = S.join(
|
|
217
|
+
h,
|
|
218
|
+
m
|
|
219
|
+
);
|
|
220
|
+
if (!a.existsSync(n)) {
|
|
221
|
+
if (a.existsSync(S.dirname(n)))
|
|
222
|
+
a.writeFileSync(
|
|
223
|
+
n,
|
|
224
|
+
`<?xml version="1.0" encoding="UTF-8"?>
|
|
225
|
+
<project version="4">
|
|
226
|
+
</project>`
|
|
227
|
+
);
|
|
228
|
+
else if (c.length == 1)
|
|
229
|
+
throw new Error(
|
|
230
|
+
"PhpStorm IDE integration requested, but no '.idea' directory was found in the current working directory."
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
if (a.existsSync(n)) {
|
|
234
|
+
const o = a.readFileSync(n, "utf8"), i = O(o, {
|
|
235
|
+
name: l,
|
|
236
|
+
host: s,
|
|
237
|
+
port: p,
|
|
238
|
+
projectDir: h,
|
|
239
|
+
mappings: u,
|
|
240
|
+
ideKey: t
|
|
241
|
+
});
|
|
242
|
+
a.writeFileSync(n, i), g.phpstorm = m;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (c.includes("vscode")) {
|
|
246
|
+
const m = ".vscode/launch.json", n = S.join(
|
|
247
|
+
h,
|
|
248
|
+
m
|
|
249
|
+
);
|
|
250
|
+
if (!a.existsSync(n)) {
|
|
251
|
+
if (a.existsSync(S.dirname(n)))
|
|
252
|
+
a.writeFileSync(
|
|
253
|
+
n,
|
|
254
|
+
`{
|
|
255
|
+
"configurations": []
|
|
256
|
+
}`
|
|
257
|
+
);
|
|
258
|
+
else if (c.length == 1)
|
|
259
|
+
throw new Error(
|
|
260
|
+
"VS Code IDE integration requested, but no '.vscode' directory was found in the current working directory."
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
if (a.existsSync(n)) {
|
|
264
|
+
const o = a.readFileSync(n, "utf-8"), i = _(o, {
|
|
265
|
+
name: l,
|
|
266
|
+
workspaceDir: h,
|
|
267
|
+
mappings: u
|
|
268
|
+
});
|
|
269
|
+
i !== o && (a.writeFileSync(n, i), g.vscode = m);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return g;
|
|
273
|
+
}
|
|
274
|
+
async function H(l, c) {
|
|
275
|
+
var h, f, t, u;
|
|
276
|
+
const s = S.join(c, ".idea/workspace.xml");
|
|
277
|
+
if (a.existsSync(s)) {
|
|
278
|
+
const g = a.readFileSync(s, "utf8"), m = new k(x), n = (() => {
|
|
279
|
+
try {
|
|
280
|
+
return m.parse(g, !0);
|
|
281
|
+
} catch {
|
|
282
|
+
throw new Error(
|
|
283
|
+
"PhpStorm configuration file is not valid XML."
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
})(), o = n.find(
|
|
287
|
+
(r) => !!(r != null && r.project)
|
|
288
|
+
), i = (h = o == null ? void 0 : o.project) == null ? void 0 : h.find(
|
|
289
|
+
(r) => {
|
|
290
|
+
var w;
|
|
291
|
+
return !!(r != null && r.component) && ((w = r == null ? void 0 : r[":@"]) == null ? void 0 : w.name) === "PhpServers";
|
|
292
|
+
}
|
|
293
|
+
), y = (f = i == null ? void 0 : i.component) == null ? void 0 : f.find(
|
|
294
|
+
(r) => !!(r != null && r.servers)
|
|
295
|
+
), d = (t = y == null ? void 0 : y.servers) == null ? void 0 : t.findIndex(
|
|
296
|
+
(r) => {
|
|
297
|
+
var w;
|
|
298
|
+
return !!(r != null && r.server) && ((w = r == null ? void 0 : r[":@"]) == null ? void 0 : w.name) === l;
|
|
299
|
+
}
|
|
300
|
+
);
|
|
301
|
+
if (d !== void 0 && d >= 0) {
|
|
302
|
+
y.servers.splice(d, 1);
|
|
303
|
+
const w = new A(T).build(n);
|
|
304
|
+
try {
|
|
305
|
+
m.parse(w, !0);
|
|
306
|
+
} catch {
|
|
307
|
+
throw new Error(
|
|
308
|
+
"The resulting PhpStorm configuration file is not valid XML."
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
w === `<?xml version="1.0" encoding="UTF-8"?>
|
|
312
|
+
<project version="4">
|
|
313
|
+
<component name="PhpServers">
|
|
314
|
+
<servers></servers>
|
|
315
|
+
</component>
|
|
316
|
+
</project>` ? a.unlinkSync(s) : a.writeFileSync(s, w);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
const p = S.join(c, ".vscode/launch.json");
|
|
320
|
+
if (a.existsSync(p)) {
|
|
321
|
+
const g = [], m = a.readFileSync(p, "utf-8"), n = v.parseTree(m, g, j);
|
|
322
|
+
if (n === void 0 || g.length)
|
|
323
|
+
throw new Error("VS Code configuration file is not valid JSON.");
|
|
324
|
+
const o = v.findNodeAtLocation(n, [
|
|
325
|
+
"configurations"
|
|
326
|
+
]), i = (u = o == null ? void 0 : o.children) == null ? void 0 : u.findIndex(
|
|
327
|
+
(y) => {
|
|
328
|
+
var d;
|
|
329
|
+
return ((d = v.findNodeAtLocation(y, ["name"])) == null ? void 0 : d.value) === l;
|
|
330
|
+
}
|
|
331
|
+
);
|
|
332
|
+
if (i !== void 0 && i >= 0) {
|
|
333
|
+
const y = v.modify(
|
|
334
|
+
m,
|
|
335
|
+
["configurations", i],
|
|
336
|
+
void 0,
|
|
337
|
+
{
|
|
338
|
+
formattingOptions: {
|
|
339
|
+
insertSpaces: !0,
|
|
340
|
+
tabSize: 4,
|
|
341
|
+
eol: `
|
|
342
|
+
`
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
), d = D(m, y);
|
|
346
|
+
d === `{
|
|
347
|
+
"configurations": []
|
|
348
|
+
}` ? a.unlinkSync(p) : a.writeFileSync(p, d);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
function D(l, c) {
|
|
353
|
+
const s = [], p = v.applyEdits(l, c);
|
|
354
|
+
if (s.length = 0, v.parseTree(p, s, j), s.length) {
|
|
355
|
+
const h = s.map((t) => ({
|
|
356
|
+
message: v.printParseErrorCode(t.error),
|
|
357
|
+
offset: t.offset,
|
|
358
|
+
length: t.length,
|
|
359
|
+
fragment: p.slice(
|
|
360
|
+
Math.max(0, t.offset - 20),
|
|
361
|
+
Math.min(p.length, t.offset + t.length + 10)
|
|
362
|
+
)
|
|
363
|
+
})).map(
|
|
364
|
+
(t) => `${t.message} at ${t.offset}:${t.length} (${t.fragment})`
|
|
365
|
+
), f = c.map(
|
|
366
|
+
(t) => `At ${t.offset}:${t.length} - (${t.content})`
|
|
367
|
+
);
|
|
368
|
+
throw new Error(
|
|
369
|
+
`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.
|
|
370
|
+
|
|
371
|
+
Applied edits: ${f.join(
|
|
372
|
+
`
|
|
373
|
+
`
|
|
374
|
+
)}
|
|
375
|
+
|
|
376
|
+
The errors are: ${h.join(`
|
|
377
|
+
`)}`
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
return p;
|
|
381
|
+
}
|
|
382
|
+
function N(l) {
|
|
383
|
+
return l.replaceAll(S.sep, S.posix.sep);
|
|
384
|
+
}
|
|
385
|
+
export {
|
|
386
|
+
q as addXdebugIDEConfig,
|
|
387
|
+
H as clearXdebugIDEConfig,
|
|
388
|
+
V as createTempDirSymlink,
|
|
389
|
+
J as removeTempDirSymlink,
|
|
390
|
+
O as updatePhpStormConfig,
|
|
391
|
+
_ as updateVSCodeConfig
|
|
392
|
+
};
|
|
393
|
+
//# sourceMappingURL=index.js.map
|
package/index.js.map
ADDED
|
@@ -0,0 +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 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\nfunction toPosixPath(pathStr: string) {\n\treturn pathStr.replaceAll(path.sep, path.posix.sep);\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","pathStr"],"mappings":"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"}
|
package/lib/index.d.ts
ADDED
package/lib/mounts.d.ts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { Mount } from './mounts';
|
|
2
|
+
/**
|
|
3
|
+
* Create a symlink to a tempory directory.
|
|
4
|
+
*
|
|
5
|
+
* The symlink is created to access the system temp dir
|
|
6
|
+
* inside the current debugging directory.
|
|
7
|
+
*
|
|
8
|
+
* @param nativeDirPath The system temp dir path.
|
|
9
|
+
* @param symlinkPath The symlink name.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createTempDirSymlink(nativeDirPath: string, symlinkPath: string, platform: string): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Remove the given temporary directory symlink if it exists.
|
|
14
|
+
*
|
|
15
|
+
* @param symlinkPath The symlink path.
|
|
16
|
+
*/
|
|
17
|
+
export declare function removeTempDirSymlink(symlinkPath: string): Promise<void>;
|
|
18
|
+
export type IDEConfig = {
|
|
19
|
+
/**
|
|
20
|
+
* The name of the configuration within the IDE configuration.
|
|
21
|
+
*/
|
|
22
|
+
name: string;
|
|
23
|
+
/**
|
|
24
|
+
* The IDEs to configure.
|
|
25
|
+
*/
|
|
26
|
+
ides: string[];
|
|
27
|
+
/**
|
|
28
|
+
* The web server host.
|
|
29
|
+
*/
|
|
30
|
+
host: string;
|
|
31
|
+
/**
|
|
32
|
+
* The web server port.
|
|
33
|
+
*/
|
|
34
|
+
port: number;
|
|
35
|
+
/**
|
|
36
|
+
* The current working directory to consider for debugger path mapping.
|
|
37
|
+
*/
|
|
38
|
+
cwd: string;
|
|
39
|
+
/**
|
|
40
|
+
* The mounts to consider for debugger path mapping.
|
|
41
|
+
*/
|
|
42
|
+
mounts?: Mount[];
|
|
43
|
+
/**
|
|
44
|
+
* The IDE key to use for the debug configuration. Defaults to 'PLAYGROUNDCLI'.
|
|
45
|
+
*/
|
|
46
|
+
ideKey?: string;
|
|
47
|
+
};
|
|
48
|
+
export type PhpStormConfigOptions = {
|
|
49
|
+
name: string;
|
|
50
|
+
host: string;
|
|
51
|
+
port: number;
|
|
52
|
+
projectDir: string;
|
|
53
|
+
mappings?: Mount[];
|
|
54
|
+
ideKey: string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Pure function to update PHPStorm XML config with XDebug server and run configuration.
|
|
58
|
+
*
|
|
59
|
+
* @param xmlContent The original XML content of workspace.xml
|
|
60
|
+
* @param options Configuration options for the server
|
|
61
|
+
* @returns Updated XML content
|
|
62
|
+
* @throws Error if XML is invalid or configuration is incompatible
|
|
63
|
+
*/
|
|
64
|
+
export declare function updatePhpStormConfig(xmlContent: string, options: PhpStormConfigOptions): string;
|
|
65
|
+
export type VSCodeConfigOptions = {
|
|
66
|
+
name: string;
|
|
67
|
+
workspaceDir: string;
|
|
68
|
+
mappings?: Mount[];
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Pure function to update VS Code launch.json config with XDebug configuration.
|
|
72
|
+
*
|
|
73
|
+
* @param jsonContent The original JSON content of launch.json
|
|
74
|
+
* @param options Configuration options
|
|
75
|
+
* @returns Updated JSON content
|
|
76
|
+
* @throws Error if JSON is invalid
|
|
77
|
+
*/
|
|
78
|
+
export declare function updateVSCodeConfig(jsonContent: string, options: VSCodeConfigOptions): string;
|
|
79
|
+
/**
|
|
80
|
+
* Implement necessary parameters and path mappings in IDE configuration files.
|
|
81
|
+
*
|
|
82
|
+
* @param name The configuration name.
|
|
83
|
+
* @param mounts The mounts options.
|
|
84
|
+
*/
|
|
85
|
+
export declare function addXdebugIDEConfig({ name, ides, host, port, cwd, mounts, ideKey, }: IDEConfig): Promise<Record<string, string>>;
|
|
86
|
+
/**
|
|
87
|
+
* Remove stale parameters and path mappings in IDE configuration files.
|
|
88
|
+
*
|
|
89
|
+
* @param name The configuration name.
|
|
90
|
+
* @param cwd The current working directory.
|
|
91
|
+
*/
|
|
92
|
+
export declare function clearXdebugIDEConfig(name: string, cwd: string): Promise<void>;
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@php-wasm/cli-util",
|
|
3
|
+
"version": "3.0.27",
|
|
4
|
+
"description": "Utilities for PHP.wasm related CLIs",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/WordPress/wordpress-playground"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://developer.wordpress.org/playground",
|
|
10
|
+
"author": "The WordPress contributors",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./index.js",
|
|
14
|
+
"require": "./index.cjs"
|
|
15
|
+
},
|
|
16
|
+
"./package.json": "./package.json",
|
|
17
|
+
"./README.md": "./README.md"
|
|
18
|
+
},
|
|
19
|
+
"main": "./index.cjs",
|
|
20
|
+
"module": "./index.js",
|
|
21
|
+
"type": "module",
|
|
22
|
+
"types": "index.d.ts",
|
|
23
|
+
"typedoc": {
|
|
24
|
+
"entryPoint": "./src/index.ts",
|
|
25
|
+
"readmeFile": "./README.md",
|
|
26
|
+
"displayName": "@php-wasm/cli-util",
|
|
27
|
+
"tsconfig": "./tsconfig.lib.json"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public",
|
|
31
|
+
"directory": "../../../dist/packages/php-wasm/cli-util"
|
|
32
|
+
},
|
|
33
|
+
"license": "GPL-2.0-or-later",
|
|
34
|
+
"gitHead": "2f8d8f3cea548fbd75111e8659a92f601cddc593",
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=20.18.3",
|
|
37
|
+
"npm": ">=10.1.0"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"fast-xml-parser": "5.3.0",
|
|
41
|
+
"jsonc-parser": "3.3.1"
|
|
42
|
+
},
|
|
43
|
+
"packageManager": "npm@10.9.2",
|
|
44
|
+
"overrides": {
|
|
45
|
+
"rollup": "^4.34.6",
|
|
46
|
+
"react": "18.3.1",
|
|
47
|
+
"react-dom": "18.3.1",
|
|
48
|
+
"typescript": "5.4.5",
|
|
49
|
+
"@playwright/test": "1.55.1",
|
|
50
|
+
"ws": "8.18.3",
|
|
51
|
+
"tmp": "0.2.5",
|
|
52
|
+
"form-data": "^4.0.4"
|
|
53
|
+
},
|
|
54
|
+
"optionalDependencies": {
|
|
55
|
+
"fs-ext": "2.1.1"
|
|
56
|
+
}
|
|
57
|
+
}
|