@php-wasm/util 3.0.46 → 3.0.51

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,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=Symbol("SleepFinished");function P(i){return new Promise(e=>{setTimeout(()=>e(d),i)})}class g extends Error{constructor(){super("Acquiring lock timed out")}}class E{constructor({concurrency:e,timeout:t}){this._running=0,this.concurrency=e,this.timeout=t,this.queue=[]}get remaining(){return this.concurrency-this.running}get running(){return this._running}async acquire(){for(;;)if(this._running>=this.concurrency){const e=new Promise(t=>{this.queue.push(t)});this.timeout!==void 0?await Promise.race([e,P(this.timeout)]).then(t=>{if(t===d)throw new g}):await e}else{this._running++;let e=!1;return()=>{e||(e=!0,this._running--,this.queue.length>0&&this.queue.shift()())}}}async run(e){const t=await this.acquire();try{return await e()}finally{t()}}}class S extends Error{constructor(e,t){super(e),this.userFriendlyMessage=t??e}}function p(...i){function e(l){return l.substring(l.length-1)==="/"}let t=i.join("/");const r=t[0]==="/",s=e(t);return t=u(t),!t&&!r&&(t="."),t&&s&&!e(t)&&(t+="/"),t}function O(i){if(i==="/")return"/";i=u(i);const e=i.lastIndexOf("/");return e===-1?"":e===0?"/":i.substr(0,e)}function T(i){if(i==="/")return"/";i=u(i);const e=i.lastIndexOf("/");return e===-1?i:i.substr(e+1)}function u(i){const e=i[0]==="/";return i=x(i.split("/").filter(t=>!!t),!e).join("/"),(e?"/":"")+i.replace(/\/$/,"")}function x(i,e){let t=0;for(let r=i.length-1;r>=0;r--){const s=i[r];s==="."?i.splice(r,1):s===".."?(i.splice(r,1),t++):t&&(i.splice(r,1),t--)}if(e)for(;t;t--)i.unshift("..");return i}function _(i,e){return i==="/"?!0:(i=u(i),e=u(e),e.startsWith(i+"/")||e===i)}function A(i){return p("/",u(i||"/"))}class h{constructor(){this.listeners={}}emit(e,t){this.listeners[e]&&this.listeners[e].forEach(function(r){r(t)})}on(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)}once(e,t){const r=(...s)=>{this.off(e,r),t(...s)};this.on(e,r)}off(e,t){this.listeners[e]&&(this.listeners[e]=this.listeners[e].filter(r=>r!==t))}}function y(i){let r=0,s="";const l=[];let n="";for(let o=0;o<i.length;o++){const f=i[o];f==="\\"?((i[o+1]==='"'||i[o+1]==="'")&&o++,n+=i[o]):r===0?f==='"'||f==="'"?(r=1,s=f):f.match(/\s/)?(n.trim().length&&l.push(n.trim()),n=f):l.length&&!n?n=l.pop()+f:n+=f:r===1&&(f===s?(r=0,s=""):n+=f)}return n&&l.push(n.trim()),l}class c extends h{constructor(e){if(super(),this.buffer=[],this.writing=!1,this.ended=!1,this.length=0,!e.write)throw new Error("WritablePolyfill requires write option");this._write=e.write,this.highWaterMark=e.highWaterMark??16*1024,this.decodeStrings=e.decodeStrings??!0,this.defaultEncoding=e.defaultEncoding??"utf8",this.defer=typeof queueMicrotask=="function"?queueMicrotask:t=>setTimeout(t,0)}write(e,t=this.defaultEncoding,r=()=>{}){if(typeof t=="function"&&(r=t,t=this.defaultEncoding),this.ended){const l=new Error("write after end"),n=this.defer;return n(()=>r(l)),this.emit("error",l),!1}if(this.decodeStrings&&typeof e=="string"){if(typeof Buffer<"u"&&typeof Buffer.from=="function")e=Buffer.from(e,t);else if(typeof TextEncoder<"u")e=new TextEncoder().encode(e);else throw new Error("String chunks are not supported in this environment: Buffer and TextEncoder are unavailable.");t="buffer"}this.length+=e.length??1;const s=this.length>=this.highWaterMark;return this.buffer.push({chunk:e,encoding:t,cb:r}),this.writing||this._clearBuffer(),!s}end(e,t,r){typeof e=="function"?(r=e,e=void 0):typeof t=="function"&&(r=t,t=void 0),e!==void 0&&this.write(e,t,()=>{}),this.ended=!0,this.writing||this._clearBuffer(),r&&this.defer(r)}cork(){}uncork(){}setDefaultEncoding(e){return this.defaultEncoding=e,this}_clearBuffer(){const e=this.buffer.shift();if(!e){this.ended&&this.emit("finish");return}this.writing=!0,this._write(e.chunk,e.encoding,t=>{this.writing=!1,this.length-=e.chunk.length??1,t&&this.emit("error",t),e.cb(t),this.buffer.length?this._clearBuffer():(this.length<this.highWaterMark&&this.emit("drain"),this.ended&&this.emit("finish"))})}}function k(i){return function(e,t=[],r={}){const s=new U,l=new M(s);return setTimeout(async()=>{let n=[];if(t.length)n=[e,...t];else if(typeof e=="string")n=y(e);else if(Array.isArray(e))n=e;else throw new Error("Invalid command ",e);try{const o=i(n,l,r);if(typeof o!="object"||o===null||!("then"in o))throw new Error(`The program callback passed to createSpawnHandler() did not return a promise. It indicates there's a bug in your code. The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() call. All the streams would be closed already. Make sure to put an "await new Promise(resolve => setTimeout(resolve, 1))before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`);if(l.exited)throw new Error(`The program callback passed to createSpawnHandler() exited synchronously. It indicates there's a bug in your code. The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() call. All the streams would be closed already. Make sure to put an "await new Promise(resolve => setTimeout(resolve, 1))before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`);s.emit("spawn",!0),await o}catch(o){s.emit("error",o),typeof o=="object"&&o!==null&&"message"in o&&typeof o.message=="string"&&l.stderr(o.message),l.exit(1)}}),s}}class M extends h{constructor(e){super(),this.exited=!1,this.stdinBuffer=[],this.childProcess=e,e.on("stdin",t=>{this.stdinBuffer?this.stdinBuffer.push(t.slice()):this.emit("stdin",t)})}stdinEnd(){this.childProcess.stdin.ended||this.childProcess.stdin.end()}stdout(e){this.childProcess.stdout.write(e)}stdoutEnd(){this.childProcess.stdout.ended||this.childProcess.stdout.end()}stderr(e){this.childProcess.stderr.write(e)}stderrEnd(){this.childProcess.stderr.ended||this.childProcess.stderr.end()}notifySpawn(){this.childProcess.emit("spawn",!0)}exit(e){this.exited||(this.exited=!0,this.stdinEnd(),this.stdoutEnd(),this.stderrEnd(),this.childProcess.emit("exit",e))}on(e,t){if(super.on(e,t),e==="stdin"&&this.stdinBuffer){for(let r=0;r<this.stdinBuffer.length;r++)this.emit("stdin",this.stdinBuffer[r]);this.stdinBuffer=null}}}let B=9743;class U extends h{constructor(e=B++){super(),this.pid=e;const t=this;this.stdout=new c({write(r,s,l){t.stdout.emit("data",r),l()}}),this.stderr=new c({write:(r,s,l)=>{t.stderr.emit("data",r),l()}}),this.stdin=new c({write:(r,s,l)=>{t.emit("stdin",r),l()}})}}function w(i=36,e="!@#$%^&*()_+=-[]/.,<>?"){const t="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"+e;let r="";for(let s=i;s>0;--s)r+=t[Math.floor(Math.random()*t.length)];return r}function q(){return w(36,"-_")}function m(i){return`json_decode(base64_decode('${j(JSON.stringify(i))}'), true)`}function D(i){const e={};for(const t in i)e[t]=m(i[t]);return e}function j(i){return I(new TextEncoder().encode(i))}function I(i){const e=String.fromCodePoint(...i);return btoa(e)}function W(i,...e){let t="",r=0;for(let s=0;s<i.length;s++)if(i[s]==="%"&&s+1<i.length){s++;const l=i[s];switch(l){case"s":{const n=e[r++];let o;if(typeof n=="object")try{o=JSON.stringify(n,(f,a)=>typeof a=="bigint"?`0x${a.toString(16)}`:a,2)}catch{}else o=String(n);t+=o;break}case"d":{const n=e[r++];typeof n=="bigint"?t+=n.toString():t+=Math.floor(Number(n));break}case"f":{const n=e[r++];t+=Number(n);break}case"x":{const n=e[r++];typeof n=="bigint"?t+=n.toString(16):t+=Math.floor(Number(n)).toString(16);break}case"%":{t+="%";break}default:t+="%"+l}}else t+=i[s];return t}function H(i){const e=new Set,t=new Set,r=n=>globalThis[n.constructor.name]!==n.constructor;let s=i;for(;s!==null&&!r(s);){const n=[...Object.getOwnPropertyNames(s),...Object.getOwnPropertySymbols(s)];for(const o of n)!e.has(o)&&!t.has(o)&&typeof s[o]=="function"&&t.add(o),e.add(o);s=Object.getPrototypeOf(s)}const l=Object.create(i);for(const n of t)l[n]=function(...o){return Promise.resolve(i[n](...o))};return l}function b(i){let e=0;i.forEach(s=>e+=s.length);const t=new Uint8Array(e);let r=0;return i.forEach(s=>{t.set(s,r),r+=s.length}),t}function N(i){return b(i.map(e=>new Uint8Array(e))).buffer}exports.AcquireTimeoutError=g;exports.EventEmitterPolyfill=h;exports.PhpWasmError=S;exports.Semaphore=E;exports.WritablePolyfill=c;exports.basename=T;exports.concatArrayBuffers=N;exports.concatUint8Arrays=b;exports.createSpawnHandler=k;exports.dirname=O;exports.ensureAbsolutePath=A;exports.isParentOf=_;exports.joinPaths=p;exports.normalizePath=u;exports.phpVar=m;exports.phpVars=D;exports.randomFilename=q;exports.randomString=w;exports.splitShellCommand=y;exports.sprintf=W;exports.wrapSynchronousInterfaceAsPromised=H;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=Symbol("SleepFinished");function b(i){return new Promise(e=>{setTimeout(()=>e(d),i)})}class g extends Error{constructor(){super("Acquiring lock timed out")}}class E{constructor({concurrency:e,timeout:t}){this._running=0,this.concurrency=e,this.timeout=t,this.queue=[]}get remaining(){return this.concurrency-this.running}get running(){return this._running}async acquire(){if(this._running>=this.concurrency){const t=new Promise(r=>{this.queue.push(r)});if(this.timeout!==void 0){const r=this.queue.at(-1);if(await Promise.race([t,b(this.timeout)])===d)throw this.queue.splice(this.queue.indexOf(r),1),new g}else await t}this._running++;let e=!1;return()=>{e||(e=!0,this._running--,this.queue.length>0&&this.queue.shift()())}}async run(e){const t=await this.acquire();try{return await e()}finally{t()}}}class S extends Error{constructor(e,t){super(e),this.userFriendlyMessage=t??e}}function p(...i){function e(l){return l.substring(l.length-1)==="/"}let t=i.join("/");const r=t[0]==="/",s=e(t);return t=f(t),!t&&!r&&(t="."),t&&s&&!e(t)&&(t+="/"),t}function O(i){if(i==="/")return"/";i=f(i);const e=i.lastIndexOf("/");return e===-1?"":e===0?"/":i.substr(0,e)}function x(i){if(i==="/")return"/";i=f(i);const e=i.lastIndexOf("/");return e===-1?i:i.substr(e+1)}function f(i){const e=i[0]==="/";return i=T(i.split("/").filter(t=>!!t),!e).join("/"),(e?"/":"")+i.replace(/\/$/,"")}function T(i,e){let t=0;for(let r=i.length-1;r>=0;r--){const s=i[r];s==="."?i.splice(r,1):s===".."?(i.splice(r,1),t++):t&&(i.splice(r,1),t--)}if(e)for(;t;t--)i.unshift("..");return i}function A(i,e){return i==="/"?!0:(i=f(i),e=f(e),e.startsWith(i+"/")||e===i)}function _(i){return p("/",f(i||"/"))}function k(i){let e=i.replaceAll("\\","/");const t=e.match(/^([A-Za-z]):\//);return t&&(e="/"+t[1]+e.slice(2)),e}class a{constructor(){this.listeners={}}emit(e,t){this.listeners[e]&&this.listeners[e].forEach(function(r){r(t)})}on(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)}once(e,t){const r=(...s)=>{this.off(e,r),t(...s)};this.on(e,r)}off(e,t){this.listeners[e]&&(this.listeners[e]=this.listeners[e].filter(r=>r!==t))}}function y(i){let r=0,s="";const l=[];let n="";for(let o=0;o<i.length;o++){const u=i[o];u==="\\"?((i[o+1]==='"'||i[o+1]==="'")&&o++,n+=i[o]):r===0?u==='"'||u==="'"?(r=1,s=u):u.match(/\s/)?(n.trim().length&&l.push(n.trim()),n=u):l.length&&!n?n=l.pop()+u:n+=u:r===1&&(u===s?(r=0,s=""):n+=u)}return n&&l.push(n.trim()),l}class c extends a{constructor(e){if(super(),this.buffer=[],this.writing=!1,this.ended=!1,this.length=0,!e.write)throw new Error("WritablePolyfill requires write option");this._write=e.write,this.highWaterMark=e.highWaterMark??16*1024,this.decodeStrings=e.decodeStrings??!0,this.defaultEncoding=e.defaultEncoding??"utf8",this.defer=typeof queueMicrotask=="function"?queueMicrotask:t=>setTimeout(t,0)}write(e,t=this.defaultEncoding,r=()=>{}){if(typeof t=="function"&&(r=t,t=this.defaultEncoding),this.ended){const l=new Error("write after end"),n=this.defer;return n(()=>r(l)),this.emit("error",l),!1}if(this.decodeStrings&&typeof e=="string"){if(typeof Buffer<"u"&&typeof Buffer.from=="function")e=Buffer.from(e,t);else if(typeof TextEncoder<"u")e=new TextEncoder().encode(e);else throw new Error("String chunks are not supported in this environment: Buffer and TextEncoder are unavailable.");t="buffer"}this.length+=e.length??1;const s=this.length>=this.highWaterMark;return this.buffer.push({chunk:e,encoding:t,cb:r}),this.writing||this._clearBuffer(),!s}end(e,t,r){typeof e=="function"?(r=e,e=void 0):typeof t=="function"&&(r=t,t=void 0),e!==void 0&&this.write(e,t,()=>{}),this.ended=!0,this.writing||this._clearBuffer(),r&&this.defer(r)}cork(){}uncork(){}setDefaultEncoding(e){return this.defaultEncoding=e,this}_clearBuffer(){const e=this.buffer.shift();if(!e){this.ended&&this.emit("finish");return}this.writing=!0,this._write(e.chunk,e.encoding,t=>{this.writing=!1,this.length-=e.chunk.length??1,t&&this.emit("error",t),e.cb(t),this.buffer.length?this._clearBuffer():(this.length<this.highWaterMark&&this.emit("drain"),this.ended&&this.emit("finish"))})}}function M(i){return function(e,t=[],r={}){const s=new U,l=new B(s);return setTimeout(async()=>{let n=[];if(t.length)n=[e,...t];else if(typeof e=="string")n=y(e);else if(Array.isArray(e))n=e;else throw new Error("Invalid command ",e);try{const o=i(n,l,r);if(typeof o!="object"||o===null||!("then"in o))throw new Error(`The program callback passed to createSpawnHandler() did not return a promise. It indicates there's a bug in your code. The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() call. All the streams would be closed already. Make sure to put an "await new Promise(resolve => setTimeout(resolve, 1))before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`);if(l.exited)throw new Error(`The program callback passed to createSpawnHandler() exited synchronously. It indicates there's a bug in your code. The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() call. All the streams would be closed already. Make sure to put an "await new Promise(resolve => setTimeout(resolve, 1))before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`);s.emit("spawn",!0),await o}catch(o){s.emit("error",o),typeof o=="object"&&o!==null&&"message"in o&&typeof o.message=="string"&&l.stderr(o.message),l.exit(1)}}),s}}class B extends a{constructor(e){super(),this.exited=!1,this.stdinBuffer=[],this.childProcess=e,e.on("stdin",t=>{this.stdinBuffer?this.stdinBuffer.push(t.slice()):this.emit("stdin",t)})}stdinEnd(){this.childProcess.stdin.ended||this.childProcess.stdin.end()}stdout(e){this.childProcess.stdout.write(e)}stdoutEnd(){this.childProcess.stdout.ended||this.childProcess.stdout.end()}stderr(e){this.childProcess.stderr.write(e)}stderrEnd(){this.childProcess.stderr.ended||this.childProcess.stderr.end()}notifySpawn(){this.childProcess.emit("spawn",!0)}exit(e){this.exited||(this.exited=!0,this.stdinEnd(),this.stdoutEnd(),this.stderrEnd(),this.childProcess.emit("exit",e))}on(e,t){if(super.on(e,t),e==="stdin"&&this.stdinBuffer){for(let r=0;r<this.stdinBuffer.length;r++)this.emit("stdin",this.stdinBuffer[r]);this.stdinBuffer=null}}}let q=9743;class U extends a{constructor(e=q++){super(),this.pid=e;const t=this;this.stdout=new c({write(r,s,l){t.stdout.emit("data",r),l()}}),this.stderr=new c({write:(r,s,l)=>{t.stderr.emit("data",r),l()}}),this.stdin=new c({write:(r,s,l)=>{t.emit("stdin",r),l()}})}}function w(i=36,e="!@#$%^&*()_+=-[]/.,<>?"){const t="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"+e;let r="";for(let s=i;s>0;--s)r+=t[Math.floor(Math.random()*t.length)];return r}function D(){return w(36,"-_")}function m(i){return`json_decode(base64_decode('${I(JSON.stringify(i))}'), true)`}function j(i){const e={};for(const t in i)e[t]=m(i[t]);return e}function I(i){return W(new TextEncoder().encode(i))}function W(i){const e=String.fromCodePoint(...i);return btoa(e)}function H(i,...e){let t="",r=0;for(let s=0;s<i.length;s++)if(i[s]==="%"&&s+1<i.length){s++;const l=i[s];switch(l){case"s":{const n=e[r++];let o;if(typeof n=="object")try{o=JSON.stringify(n,(u,h)=>typeof h=="bigint"?`0x${h.toString(16)}`:h,2)}catch{}else o=String(n);t+=o;break}case"d":{const n=e[r++];typeof n=="bigint"?t+=n.toString():t+=Math.floor(Number(n));break}case"f":{const n=e[r++];t+=Number(n);break}case"x":{const n=e[r++];typeof n=="bigint"?t+=n.toString(16):t+=Math.floor(Number(n)).toString(16);break}case"%":{t+="%";break}default:t+="%"+l}}else t+=i[s];return t}function v(i){const e=new Set,t=new Set,r=n=>globalThis[n.constructor.name]!==n.constructor;let s=i;for(;s!==null&&!r(s);){const n=[...Object.getOwnPropertyNames(s),...Object.getOwnPropertySymbols(s)];for(const o of n)!e.has(o)&&!t.has(o)&&typeof s[o]=="function"&&t.add(o),e.add(o);s=Object.getPrototypeOf(s)}const l=Object.create(i);for(const n of t)l[n]=function(...o){return Promise.resolve(i[n](...o))};return l}function P(i){let e=0;i.forEach(s=>e+=s.length);const t=new Uint8Array(e);let r=0;return i.forEach(s=>{t.set(s,r),r+=s.length}),t}function N(i){return P(i.map(e=>new Uint8Array(e))).buffer}exports.AcquireTimeoutError=g;exports.EventEmitterPolyfill=a;exports.PhpWasmError=S;exports.Semaphore=E;exports.WritablePolyfill=c;exports.basename=x;exports.concatArrayBuffers=N;exports.concatUint8Arrays=P;exports.createSpawnHandler=M;exports.dirname=O;exports.ensureAbsolutePath=_;exports.isParentOf=A;exports.joinPaths=p;exports.normalizePath=f;exports.phpVar=m;exports.phpVars=j;exports.randomFilename=D;exports.randomString=w;exports.splitShellCommand=y;exports.sprintf=H;exports.toPosixPath=k;exports.wrapSynchronousInterfaceAsPromised=v;
2
2
  //# sourceMappingURL=index.cjs.map
package/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../../packages/php-wasm/util/src/lib/sleep.ts","../../../../packages/php-wasm/util/src/lib/semaphore.ts","../../../../packages/php-wasm/util/src/lib/php-wasm-error.ts","../../../../packages/php-wasm/util/src/lib/paths.ts","../../../../packages/php-wasm/util/src/lib/event-emitter-polyfill.ts","../../../../packages/php-wasm/util/src/lib/split-shell-command.ts","../../../../packages/php-wasm/util/src/lib/writable-polyfill.ts","../../../../packages/php-wasm/util/src/lib/create-spawn-handler.ts","../../../../packages/php-wasm/util/src/lib/random-string.ts","../../../../packages/php-wasm/util/src/lib/random-filename.ts","../../../../packages/php-wasm/util/src/lib/php-vars.ts","../../../../packages/php-wasm/util/src/lib/sprintf.ts","../../../../packages/php-wasm/util/src/lib/promised.ts","../../../../packages/php-wasm/util/src/lib/index.ts"],"sourcesContent":["export const SleepFinished = Symbol('SleepFinished');\n\nexport function sleep(ms: number): Promise<typeof SleepFinished> {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(() => resolve(SleepFinished), ms);\n\t});\n}\n","import { SleepFinished, sleep } from './sleep';\n\nexport interface SemaphoreOptions {\n\t/**\n\t * The maximum number of concurrent locks.\n\t */\n\tconcurrency: number;\n\t/**\n\t * The maximum time to wait for a lock to become available.\n\t */\n\ttimeout?: number;\n}\n\nexport class AcquireTimeoutError extends Error {\n\tconstructor() {\n\t\tsuper('Acquiring lock timed out');\n\t}\n}\n\nexport default class Semaphore {\n\tprivate _running = 0;\n\tprivate concurrency: number;\n\tprivate timeout?: number;\n\tprivate queue: (() => void)[];\n\n\tconstructor({ concurrency, timeout }: SemaphoreOptions) {\n\t\tthis.concurrency = concurrency;\n\t\tthis.timeout = timeout;\n\t\tthis.queue = [];\n\t}\n\n\tget remaining(): number {\n\t\treturn this.concurrency - this.running;\n\t}\n\n\tget running(): number {\n\t\treturn this._running;\n\t}\n\n\tasync acquire(): Promise<() => void> {\n\t\twhile (true) {\n\t\t\tif (this._running >= this.concurrency) {\n\t\t\t\t// Concurrency exhausted – wait until a lock is released:\n\t\t\t\tconst acquired = new Promise<void>((resolve) => {\n\t\t\t\t\tthis.queue.push(resolve);\n\t\t\t\t});\n\t\t\t\tif (this.timeout !== undefined) {\n\t\t\t\t\tawait Promise.race([acquired, sleep(this.timeout)]).then(\n\t\t\t\t\t\t(value) => {\n\t\t\t\t\t\t\tif (value === SleepFinished) {\n\t\t\t\t\t\t\t\tthrow new AcquireTimeoutError();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tawait acquired;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Acquire the lock:\n\t\t\t\tthis._running++;\n\t\t\t\tlet released = false;\n\t\t\t\treturn () => {\n\t\t\t\t\tif (released) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\treleased = true;\n\t\t\t\t\tthis._running--;\n\t\t\t\t\t// Release the lock:\n\t\t\t\t\tif (this.queue.length > 0) {\n\t\t\t\t\t\tthis.queue.shift()!();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\tasync run<T>(fn: () => T | Promise<T>): Promise<T> {\n\t\tconst release = await this.acquire();\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} finally {\n\t\t\trelease();\n\t\t}\n\t}\n}\n","export class PhpWasmError extends Error {\n\tuserFriendlyMessage?: string;\n\tconstructor(message: string, userFriendlyMessage?: string) {\n\t\tsuper(message);\n\t\tthis.userFriendlyMessage = userFriendlyMessage ?? message;\n\t}\n}\n","/**\n * The functions in this module are mostly copied from the generated\n * Emscripten PHP module. This enables features like filesystem journaling,\n * which use some low-level Emscripten APIs and need access to the\n * same path helpers.\n */\n\n/**\n * Joins paths together.\n *\n * For example:\n *\n * > joinPaths('wordpress', 'wp-content')\n * 'wordpress/wp-content'\n *\n * Use this for all PHP paths and **do not** use path.join().\n * This is important because Emscripten paths are **always**\n * POSIX-style paths. Imagine joining paths on Windows:\n *\n * > path.join('wordpress', 'wp-content')\n * '\\\\wordpress\\\\wp-content' // invalid in PHP.wasm\n *\n * See the path.join issue for more details:\n *\n * https://github.com/WordPress/playground-tools/issues/11#issuecomment-1579074763\n *\n * @param paths Paths segments to join\n * @returns A joined path\n */\nexport function joinPaths(...paths: string[]) {\n\tfunction hasTrailingSlash(p: string) {\n\t\treturn p.substring(p.length - 1) === '/';\n\t}\n\n\tlet path = paths.join('/');\n\tconst isAbsolute = path[0] === '/';\n\tconst trailingSlash = hasTrailingSlash(path);\n\tpath = normalizePath(path);\n\tif (!path && !isAbsolute) {\n\t\tpath = '.';\n\t}\n\tif (path && trailingSlash && !hasTrailingSlash(path)) {\n\t\tpath += '/';\n\t}\n\treturn path;\n}\n\n/**\n * Returns the directory name of a path.\n *\n * @param path\n * @returns\n */\nexport function dirname(path: string) {\n\tif (path === '/') {\n\t\treturn '/';\n\t}\n\n\tpath = normalizePath(path);\n\n\tconst lastSlash = path.lastIndexOf('/');\n\tif (lastSlash === -1) {\n\t\treturn '';\n\t} else if (lastSlash === 0) {\n\t\treturn '/';\n\t}\n\treturn path.substr(0, lastSlash);\n}\n\n/**\n * Returns the last portion of a path.\n *\n * @param path - The path to extract the basename from.\n * @returns The basename of the path.\n */\nexport function basename(path: string) {\n\tif (path === '/') {\n\t\treturn '/';\n\t}\n\n\tpath = normalizePath(path);\n\n\tconst lastSlash = path.lastIndexOf('/');\n\tif (lastSlash === -1) {\n\t\treturn path;\n\t}\n\treturn path.substr(lastSlash + 1);\n}\n\n/**\n * Normalizes a path.\n *\n * For example:\n *\n * > normalizePath('wordpress/wp-content/../')\n * 'wordpress'\n *\n * @param path\n * @returns\n */\nexport function normalizePath(path: string) {\n\tconst isAbsolute = path[0] === '/';\n\tpath = normalizePathsArray(\n\t\tpath.split('/').filter((p: any) => !!p),\n\t\t!isAbsolute\n\t).join('/');\n\treturn (isAbsolute ? '/' : '') + path.replace(/\\/$/, '');\n}\n\n/**\n * Normalizes paths.\n *\n * For example:\n *\n * > normalizePathsArray(['wordpress', 'wp-content', '..', '', '.',\n * 'wp-includes']) ['wordpress', 'wp-includes']\n *\n * @param parts parts of the path to normalize\n * @param allowAboveRoot allow paths above the root\n * @returns normalized paths\n */\nexport function normalizePathsArray(parts: string[], allowAboveRoot: boolean) {\n\tlet up = 0;\n\tfor (let i = parts.length - 1; i >= 0; i--) {\n\t\tconst last = parts[i];\n\t\tif (last === '.') {\n\t\t\tparts.splice(i, 1);\n\t\t} else if (last === '..') {\n\t\t\tparts.splice(i, 1);\n\t\t\tup++;\n\t\t} else if (up) {\n\t\t\tparts.splice(i, 1);\n\t\t\tup--;\n\t\t}\n\t}\n\tif (allowAboveRoot) {\n\t\tfor (; up; up--) {\n\t\t\tparts.unshift('..');\n\t\t}\n\t}\n\treturn parts;\n}\n\n/**\n * Checks if the given parent path is an ancestor of the given child path.\n *\n * @param parent The parent path to check.\n * @param child The child path to verify against the parent.\n * @returns Whether the `parent` path is an ancestor of the `child` path.\n */\nexport function isParentOf(parent: string, child: string) {\n\tif (parent === '/') {\n\t\treturn true;\n\t}\n\tparent = normalizePath(parent);\n\tchild = normalizePath(child);\n\treturn child.startsWith(parent + '/') || child === parent;\n}\n\n/**\n * Guarantees a path is absolute by prepending `/` if needed.\n *\n * Useful when working with user-provided paths that might be relative,\n * or when you need to normalize edge cases like empty strings.\n *\n * For example:\n *\n * > ensureAbsolutePath('wp-content/uploads')\n * '/wp-content/uploads'\n *\n * > ensureAbsolutePath('/already/absolute')\n * '/already/absolute'\n *\n * > ensureAbsolutePath('')\n * '/'\n *\n * @param path - The path to make absolute.\n * @returns An absolute, normalized path starting with `/`.\n */\nexport function ensureAbsolutePath(path: string) {\n\treturn joinPaths('/', normalizePath(path || '/'));\n}\n","/**\n * Polyfills Node.js EventEmitter API. The main goal is to enable\n * using a child_process.spawn()-like API in both Node.js and the browser.\n *\n * @see https://nodejs.org/api/events.html#events_class_eventemitter\n */\ntype Listener = (...args: any[]) => any;\n\nexport class EventEmitterPolyfill {\n\tlisteners: Record<string, Listener[]> = {};\n\temit(eventName: string, data?: any) {\n\t\tif (this.listeners[eventName]) {\n\t\t\tthis.listeners[eventName].forEach(function (listener) {\n\t\t\t\tlistener(data);\n\t\t\t});\n\t\t}\n\t}\n\ton(eventName: string, listener: Listener) {\n\t\tif (!this.listeners[eventName]) {\n\t\t\tthis.listeners[eventName] = [];\n\t\t}\n\t\tthis.listeners[eventName].push(listener);\n\t}\n\tonce(eventName: string, listener: Listener) {\n\t\tconst wrappedListener = (...args: any[]) => {\n\t\t\tthis.off(eventName, wrappedListener);\n\t\t\tlistener(...args);\n\t\t};\n\t\tthis.on(eventName, wrappedListener);\n\t}\n\toff(eventName: string, listener: Listener) {\n\t\tif (this.listeners[eventName]) {\n\t\t\tthis.listeners[eventName] = this.listeners[eventName].filter(\n\t\t\t\t(l) => l !== listener\n\t\t\t);\n\t\t}\n\t}\n}\n","/**\n * Naive shell command parser.\n * Ensures that commands like `wp option set blogname \"My blog name\"` are split\n * into `['wp', 'option', 'set', 'blogname', 'My blog name']` instead of\n * `['wp', 'option', 'set', 'blogname', 'My', 'blog', 'name']`.\n *\n * @param command\n * @returns\n */\nexport function splitShellCommand(command: string) {\n\tconst MODE_UNQUOTED = 0;\n\tconst MODE_IN_QUOTE = 1;\n\n\tlet mode = MODE_UNQUOTED;\n\tlet quote = '';\n\n\tconst parts: string[] = [];\n\tlet currentPart = '';\n\tfor (let i = 0; i < command.length; i++) {\n\t\tconst char = command[i];\n\t\tif (char === '\\\\') {\n\t\t\t// Escaped quotes are treated as normal characters\n\t\t\t// This is a very naive approach to escaping, but it's good enough for\n\t\t\t// now. @TODO: Iterate on this later, perhaps using bun shell. @see https://github.com/WordPress/wordpress-playground/issues/1062\n\t\t\tif (command[i + 1] === '\"' || command[i + 1] === \"'\") {\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcurrentPart += command[i];\n\t\t} else if (mode === MODE_UNQUOTED) {\n\t\t\tif (char === '\"' || char === \"'\") {\n\t\t\t\tmode = MODE_IN_QUOTE;\n\t\t\t\tquote = char;\n\t\t\t} else if (char.match(/\\s/)) {\n\t\t\t\tif (currentPart.trim().length) {\n\t\t\t\t\tparts.push(currentPart.trim());\n\t\t\t\t}\n\t\t\t\tcurrentPart = char;\n\t\t\t} else if (parts.length && !currentPart) {\n\t\t\t\t// We just closed a quote to continue the same\n\t\t\t\t// argument with different escaping style, e.g.:\n\t\t\t\t// php -r 'require '\\''vendor/autoload.php'\\''\n\t\t\t\tcurrentPart = parts.pop()! + char;\n\t\t\t} else {\n\t\t\t\tcurrentPart += char;\n\t\t\t}\n\t\t} else if (mode === MODE_IN_QUOTE) {\n\t\t\tif (char === quote) {\n\t\t\t\tmode = MODE_UNQUOTED;\n\t\t\t\tquote = '';\n\t\t\t} else {\n\t\t\t\tcurrentPart += char;\n\t\t\t}\n\t\t}\n\t}\n\tif (currentPart) {\n\t\tparts.push(currentPart.trim());\n\t}\n\treturn parts;\n}\n","/**\n * Polyfills Node.js WritableStream API. The main goal is to enable\n * using a child_process.spawn()-like API in both Node.js and the browser.\n *\n * @see https://nodejs.org/api/stream.html#stream_writable_end_chunk_encoding_callback\n */\nimport { EventEmitterPolyfill } from './event-emitter-polyfill';\n\nexport interface WritableOptions {\n\thighWaterMark?: number;\n\tdecodeStrings?: boolean;\n\tdefaultEncoding?: BufferEncoding;\n\twrite: (chunk: any, encoding: BufferEncoding, cb: WriteCallback) => void;\n}\n\nexport type WriteCallback = (error?: Error | null) => void;\n\nexport class WritablePolyfill extends EventEmitterPolyfill {\n\tprivate buffer: Array<{\n\t\tchunk: any;\n\t\tencoding: BufferEncoding;\n\t\tcb: WriteCallback;\n\t}> = [];\n\tprivate writing = false;\n\tpublic ended = false;\n\tprivate length = 0;\n\tprivate highWaterMark: number;\n\tprivate decodeStrings: boolean;\n\tprivate defaultEncoding: BufferEncoding;\n\tprivate defer: (fn: () => void) => void;\n\tprivate _write: (\n\t\tchunk: any,\n\t\tencoding: BufferEncoding,\n\t\tcb: WriteCallback\n\t) => void;\n\n\tconstructor(opts: WritableOptions) {\n\t\tsuper();\n\t\tif (!opts.write) {\n\t\t\tthrow new Error('WritablePolyfill requires write option');\n\t\t}\n\t\tthis._write = opts.write;\n\t\tthis.highWaterMark = opts.highWaterMark ?? 16 * 1024;\n\t\tthis.decodeStrings = opts.decodeStrings ?? true;\n\t\tthis.defaultEncoding = opts.defaultEncoding ?? 'utf8';\n\t\t// queueMicrotask keeps browser support; fallback for older environments.\n\t\tthis.defer =\n\t\t\ttypeof queueMicrotask === 'function'\n\t\t\t\t? queueMicrotask\n\t\t\t\t: (fn) => setTimeout(fn, 0);\n\t}\n\n\twrite(\n\t\tchunk: any,\n\t\tencoding: BufferEncoding | WriteCallback = this.defaultEncoding,\n\t\tcb: WriteCallback = () => {}\n\t): boolean {\n\t\tif (typeof encoding === 'function') {\n\t\t\tcb = encoding as WriteCallback;\n\t\t\tencoding = this.defaultEncoding;\n\t\t}\n\n\t\tif (this.ended) {\n\t\t\tconst err = new Error('write after end');\n\t\t\t// We can't call this.defer() directly. If this.defer is\n\t\t\t// `queueMicrotask`, a `this.defer()` call will pass the\n\t\t\t// WritablePolyfill instance as `this` argument and cause\n\t\t\t// the browser to throw an error similar to \"Invalid\n\t\t\t// invocation\".\n\t\t\tconst defer = this.defer;\n\t\t\tdefer(() => cb(err));\n\t\t\tthis.emit('error', err);\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.decodeStrings && typeof chunk === 'string') {\n\t\t\tif (\n\t\t\t\ttypeof Buffer !== 'undefined' &&\n\t\t\t\ttypeof (Buffer as any).from === 'function'\n\t\t\t) {\n\t\t\t\tchunk = Buffer.from(chunk, encoding as BufferEncoding);\n\t\t\t} else if (typeof TextEncoder !== 'undefined') {\n\t\t\t\tchunk = new TextEncoder().encode(chunk);\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'String chunks are not supported in this environment: Buffer and TextEncoder are unavailable.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tencoding = 'buffer' as BufferEncoding;\n\t\t}\n\n\t\tthis.length += chunk.length ?? 1;\n\t\tconst needDrain = this.length >= this.highWaterMark;\n\n\t\tthis.buffer.push({ chunk, encoding: encoding as BufferEncoding, cb });\n\n\t\tif (!this.writing) this._clearBuffer();\n\n\t\treturn !needDrain;\n\t}\n\n\tend(\n\t\tchunk?: any,\n\t\tencoding?: BufferEncoding | WriteCallback,\n\t\tcb?: WriteCallback\n\t): void {\n\t\tif (typeof chunk === 'function') {\n\t\t\tcb = chunk;\n\t\t\tchunk = undefined;\n\t\t} else if (typeof encoding === 'function') {\n\t\t\tcb = encoding as WriteCallback;\n\t\t\tencoding = undefined;\n\t\t}\n\n\t\tif (chunk !== undefined)\n\t\t\tthis.write(chunk, encoding as BufferEncoding, () => {});\n\t\tthis.ended = true;\n\t\tif (!this.writing) this._clearBuffer();\n\t\tif (cb) this.defer(cb);\n\t}\n\n\t// Stubs kept for API parity; add logic if you depend on corking.\n\tcork(): void {}\n\tuncork(): void {}\n\n\tsetDefaultEncoding(enc: BufferEncoding): this {\n\t\tthis.defaultEncoding = enc;\n\t\treturn this;\n\t}\n\n\tprivate _clearBuffer(): void {\n\t\tconst entry = this.buffer.shift();\n\t\tif (!entry) {\n\t\t\tif (this.ended) this.emit('finish');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.writing = true;\n\t\tthis._write(entry.chunk, entry.encoding, (err?: Error | null) => {\n\t\t\tthis.writing = false;\n\t\t\tthis.length -= entry.chunk.length ?? 1;\n\t\t\tif (err) this.emit('error', err);\n\t\t\tentry.cb(err);\n\n\t\t\tif (this.buffer.length) {\n\t\t\t\tthis._clearBuffer();\n\t\t\t} else {\n\t\t\t\tif (this.length < this.highWaterMark) this.emit('drain');\n\t\t\t\tif (this.ended) this.emit('finish');\n\t\t\t}\n\t\t});\n\t}\n}\n","import { EventEmitterPolyfill } from './event-emitter-polyfill';\nimport { splitShellCommand } from './split-shell-command';\nimport { WritablePolyfill, type WriteCallback } from './writable-polyfill';\n\ntype Listener = (...args: any[]) => any;\n\nexport interface ProcessOptions {\n\tcwd?: string;\n\tenv?: Record<string, string>;\n}\n\n/**\n * Usage:\n * ```ts\n * php.setSpawnHandler(\n * createSpawnHandler(function (command, processApi) {\n * console.log(processApi.flushStdin());\n * processApi.stdout('/\\n/tmp\\n/home');\n *\t processApi.exit(0);\n * })\n * );\n * ```\n * @param program\n * @returns\n */\nexport function createSpawnHandler(\n\tprogram: (\n\t\tcommand: string[],\n\t\tprocessApi: ProcessApi,\n\t\toptions: ProcessOptions\n\t) => void | Promise<void>\n): any {\n\treturn function (\n\t\tcommand: string | string[],\n\t\targsArray: string[] = [],\n\t\toptions: ProcessOptions = {}\n\t) {\n\t\tconst childProcess = new ChildProcess();\n\t\tconst processApi = new ProcessApi(childProcess);\n\t\t// Give PHP a chance to register listeners\n\t\tsetTimeout(async () => {\n\t\t\tlet commandArray = [];\n\t\t\tif (argsArray.length) {\n\t\t\t\tcommandArray = [command as string, ...argsArray];\n\t\t\t} else if (typeof command === 'string') {\n\t\t\t\tcommandArray = splitShellCommand(command);\n\t\t\t} else if (Array.isArray(command)) {\n\t\t\t\tcommandArray = command;\n\t\t\t} else {\n\t\t\t\tthrow new Error('Invalid command ', command);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst promise = program(commandArray, processApi, options);\n\t\t\t\tif (\n\t\t\t\t\ttypeof promise !== 'object' ||\n\t\t\t\t\tpromise === null ||\n\t\t\t\t\t!('then' in promise)\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`The program callback passed to createSpawnHandler() did not return a promise. It indicates there's a bug in your code. ` +\n\t\t\t\t\t\t\t`The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() ` +\n\t\t\t\t\t\t\t`call. All the streams would be closed already. Make sure to put an \"await new Promise(resolve => setTimeout(resolve, 1))` +\n\t\t\t\t\t\t\t`before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`\n\t\t\t\t\t);\n\t\t\t\t} else if (processApi.exited) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`The program callback passed to createSpawnHandler() exited synchronously. It indicates there's a bug in your code. ` +\n\t\t\t\t\t\t\t`The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() ` +\n\t\t\t\t\t\t\t`call. All the streams would be closed already. Make sure to put an \"await new Promise(resolve => setTimeout(resolve, 1))` +\n\t\t\t\t\t\t\t`before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tchildProcess.emit('spawn', true);\n\t\t\t\tawait promise;\n\t\t\t} catch (e) {\n\t\t\t\tchildProcess.emit('error', e);\n\t\t\t\tif (\n\t\t\t\t\ttypeof e === 'object' &&\n\t\t\t\t\te !== null &&\n\t\t\t\t\t'message' in e &&\n\t\t\t\t\ttypeof e.message === 'string'\n\t\t\t\t) {\n\t\t\t\t\tprocessApi.stderr(e.message);\n\t\t\t\t}\n\t\t\t\tprocessApi.exit(1);\n\t\t\t}\n\t\t});\n\t\treturn childProcess;\n\t};\n}\n\nexport class ProcessApi extends EventEmitterPolyfill {\n\tpublic exited = false;\n\t/**\n\t * Keeps track of the data that was written to stdin before the\n\t * first listener was registered.\n\t */\n\tprivate stdinBuffer: Uint8Array[] | null = [];\n\tpublic childProcess: ChildProcess;\n\tconstructor(childProcess: ChildProcess) {\n\t\tsuper();\n\t\tthis.childProcess = childProcess;\n\t\tchildProcess.on('stdin', (data: Uint8Array) => {\n\t\t\tif (this.stdinBuffer) {\n\t\t\t\t// Need to clone the data buffer as it's reused by PHP\n\t\t\t\t// and the next data chunk will overwrite the previous one.\n\t\t\t\tthis.stdinBuffer.push(data.slice());\n\t\t\t} else {\n\t\t\t\tthis.emit('stdin', data);\n\t\t\t}\n\t\t});\n\t}\n\tstdinEnd() {\n\t\tif (!this.childProcess.stdin.ended) {\n\t\t\tthis.childProcess.stdin.end();\n\t\t}\n\t}\n\tstdout(data: string | ArrayBuffer) {\n\t\tthis.childProcess.stdout.write(data);\n\t}\n\tstdoutEnd() {\n\t\tif (!this.childProcess.stdout.ended) {\n\t\t\tthis.childProcess.stdout.end();\n\t\t}\n\t}\n\tstderr(data: string | ArrayBuffer) {\n\t\tthis.childProcess.stderr.write(data);\n\t}\n\tstderrEnd() {\n\t\tif (!this.childProcess.stderr.ended) {\n\t\t\tthis.childProcess.stderr.end();\n\t\t}\n\t}\n\tnotifySpawn() {\n\t\tthis.childProcess.emit('spawn', true);\n\t}\n\texit(code: number) {\n\t\tif (!this.exited) {\n\t\t\tthis.exited = true;\n\t\t\tthis.stdinEnd();\n\t\t\tthis.stdoutEnd();\n\t\t\tthis.stderrEnd();\n\t\t\tthis.childProcess.emit('exit', code);\n\t\t}\n\t}\n\toverride on(eventName: string, listener: Listener) {\n\t\tsuper.on(eventName, listener);\n\t\t/**\n\t\t * If it's the first stdin listener, flush all the data we've\n\t\t * buffered so far.\n\t\t */\n\t\tif (eventName === 'stdin' && this.stdinBuffer) {\n\t\t\tfor (let i = 0; i < this.stdinBuffer.length; i++) {\n\t\t\t\tthis.emit('stdin', this.stdinBuffer[i]);\n\t\t\t}\n\t\t\tthis.stdinBuffer = null;\n\t\t}\n\t}\n}\n\nlet lastPid = 9743;\nexport class ChildProcess extends EventEmitterPolyfill {\n\tstdout: WritablePolyfill;\n\tstderr: WritablePolyfill;\n\tstdin: WritablePolyfill;\n\tpid: number;\n\tconstructor(pid = lastPid++) {\n\t\tsuper();\n\t\tthis.pid = pid;\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this;\n\t\tthis.stdout = new WritablePolyfill({\n\t\t\twrite(data: any, encoding: BufferEncoding, cb: WriteCallback) {\n\t\t\t\tself.stdout.emit('data', data);\n\t\t\t\tcb();\n\t\t\t},\n\t\t});\n\t\tthis.stderr = new WritablePolyfill({\n\t\t\twrite: (data: any, encoding: BufferEncoding, cb: WriteCallback) => {\n\t\t\t\tself.stderr.emit('data', data);\n\t\t\t\tcb();\n\t\t\t},\n\t\t});\n\t\tthis.stdin = new WritablePolyfill({\n\t\t\twrite: (data: any, encoding: BufferEncoding, cb: WriteCallback) => {\n\t\t\t\tself.emit('stdin', data);\n\t\t\t\tcb();\n\t\t\t},\n\t\t});\n\t}\n}\n","export function randomString(\n\tlength = 36,\n\tspecialChars = '!@#$%^&*()_+=-[]/.,<>?'\n) {\n\tconst chars =\n\t\t'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' +\n\t\tspecialChars;\n\tlet result = '';\n\tfor (let i = length; i > 0; --i)\n\t\tresult += chars[Math.floor(Math.random() * chars.length)];\n\treturn result;\n}\n","import { randomString } from './random-string';\n\nexport function randomFilename() {\n\treturn randomString(36, '-_');\n}\n","export function phpVar(value: unknown): string {\n\treturn `json_decode(base64_decode('${stringToBase64(\n\t\tJSON.stringify(value)\n\t)}'), true)`;\n}\n\nexport function phpVars<T extends Record<string, unknown>>(\n\tvars: T\n): Record<keyof T, string> {\n\tconst result: Record<string, string> = {};\n\tfor (const key in vars) {\n\t\tresult[key] = phpVar(vars[key]);\n\t}\n\treturn result as Record<keyof T, string>;\n}\n\nfunction stringToBase64(str: string) {\n\treturn bytesToBase64(new TextEncoder().encode(str));\n}\n\nfunction bytesToBase64(bytes: Uint8Array) {\n\tconst binString = String.fromCodePoint(...bytes);\n\treturn btoa(binString);\n}\n","/**\n * Formats a string like sprintf().\n *\n * This function:\n * - Supports basic format specifiers: %s, %d, %f, %x, %%\n * - Supports bigint values\n *\n * The purpose of this function is for use in optional php-wasm tracing.\n * If we use printf-style formatting for trace messages, we let the trace\n * function decide whether to format and do not have to pay for formatting\n * unless tracing is enabled.\n */\nexport function sprintf(format: string, ...args: any[]): string {\n\tlet result = '';\n\tlet argIndex = 0;\n\n\tfor (let i = 0; i < format.length; i++) {\n\t\tif (format[i] === '%' && i + 1 < format.length) {\n\t\t\ti++;\n\t\t\tconst specifier = format[i];\n\n\t\t\tswitch (specifier) {\n\t\t\t\tcase 's': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tlet str;\n\t\t\t\t\tif (typeof arg === 'object') {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// If an object doesn't provide its own toString(),\n\t\t\t\t\t\t\t// try to represent it as JSON.\n\t\t\t\t\t\t\tstr = JSON.stringify(\n\t\t\t\t\t\t\t\targ,\n\t\t\t\t\t\t\t\t// Represent bigint values as strings in JSON.stringify().\n\t\t\t\t\t\t\t\t(key, value) => {\n\t\t\t\t\t\t\t\t\tif (typeof value === 'bigint') {\n\t\t\t\t\t\t\t\t\t\treturn `0x${value.toString(16)}`;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t2\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Ignore error and use default representation.\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = String(arg);\n\t\t\t\t\t}\n\n\t\t\t\t\tresult += str;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'd': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tif (typeof arg === 'bigint') {\n\t\t\t\t\t\tresult += arg.toString();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += Math.floor(Number(arg));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'f': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tif (typeof arg === 'bigint') {\n\t\t\t\t\t\tresult += Number(arg);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += Number(arg);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'x': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tif (typeof arg === 'bigint') {\n\t\t\t\t\t\tresult += arg.toString(16);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += Math.floor(Number(arg)).toString(16);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase '%': {\n\t\t\t\t\tresult += '%';\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tresult += '%' + specifier;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tresult += format[i];\n\t\t}\n\t}\n\n\treturn result;\n}\n","// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\ntype PromisedMethod<T extends (...args: any[]) => any> = (\n\t...args: Parameters<T>\n) => Promise<ReturnType<T>>;\n\nexport type Promised<T> = {\n\t[P in keyof T]: T[P] extends (...args: any[]) => any\n\t\t? PromisedMethod<T[P]>\n\t\t: T[P];\n};\n\n/**\n * Wraps a synchronous interface as a promised interface.\n *\n * This function tries to avoid wrapping methods inherited from\n * built-in JS object types (e.g., `Object`, `Array`, `Function`, etc.).\n *\n * The initial use case for this function is for unit testing\n * file locking in php-wasm. Php-wasm for JSPI expects the file lock manager\n * to be a promised interface used via comlink,\n * but the interface itself is synchronous.\n *\n * @param obj\n * @returns A promised interface that wraps the synchronous interface.\n */\nexport function wrapSynchronousInterfaceAsPromised<T extends object>(\n\tobj: T\n): Promised<T> {\n\tconst keysAlreadySeen = new Set<string | symbol>();\n\tconst keysToMakePromised = new Set<string | symbol>();\n\tconst looksLikeBuiltInObject =\n\t\t// NOTE: We don't generally add custom things to the global scope,\n\t\t// so let's use this as a heuristic to determine if an object is a built-in object type.\n\t\t(obj: object) =>\n\t\t\t(globalThis as any)[obj.constructor.name] !== obj.constructor;\n\n\tlet proto: object = obj;\n\twhile (proto !== null && !looksLikeBuiltInObject(proto)) {\n\t\tconst allKeys = [\n\t\t\t...Object.getOwnPropertyNames(proto),\n\t\t\t...Object.getOwnPropertySymbols(proto),\n\t\t];\n\t\tfor (const key of allKeys) {\n\t\t\tif (\n\t\t\t\t// Track keys already seen so an inherited method property\n\t\t\t\t// masked by a descendant property of the same name is not considered.\n\t\t\t\t!keysAlreadySeen.has(key) &&\n\t\t\t\t!keysToMakePromised.has(key) &&\n\t\t\t\ttypeof (proto as any)[key] === 'function'\n\t\t\t) {\n\t\t\t\tkeysToMakePromised.add(key);\n\t\t\t}\n\t\t\tkeysAlreadySeen.add(key);\n\t\t}\n\t\tproto = Object.getPrototypeOf(proto);\n\t}\n\n\t// NOTE: We could use Proxy here instead,\n\t// but providing a regular object is ultimately simpler.\n\tconst promisifiedObj = Object.create(obj);\n\tfor (const key of keysToMakePromised) {\n\t\tpromisifiedObj[key] = function (...args: any[]) {\n\t\t\treturn Promise.resolve((obj as any)[key](...args));\n\t\t};\n\t}\n\treturn promisifiedObj;\n}\n","import Semaphore, { AcquireTimeoutError } from './semaphore';\nexport { Semaphore, AcquireTimeoutError };\nexport { PhpWasmError } from './php-wasm-error';\nexport type { SemaphoreOptions } from './semaphore';\nexport {\n\tdirname,\n\tjoinPaths,\n\tbasename,\n\tnormalizePath,\n\tisParentOf,\n\tensureAbsolutePath,\n} from './paths';\nexport { createSpawnHandler } from './create-spawn-handler';\nexport { randomString } from './random-string';\nexport { randomFilename } from './random-filename';\nexport { splitShellCommand } from './split-shell-command';\nexport { WritablePolyfill, type WritableOptions } from './writable-polyfill';\nexport { EventEmitterPolyfill } from './event-emitter-polyfill';\nexport * from './php-vars';\n\nexport * from './sprintf';\n\nexport function concatUint8Arrays(arrays: Uint8Array[]): Uint8Array {\n\tlet totalLength = 0;\n\tarrays.forEach((a) => (totalLength += a.length));\n\tconst result = new Uint8Array(totalLength);\n\tlet offset = 0;\n\tarrays.forEach((a) => {\n\t\tresult.set(a, offset);\n\t\toffset += a.length;\n\t});\n\treturn result;\n}\n\nexport function concatArrayBuffers(buffers: ArrayBuffer[]): ArrayBuffer {\n\treturn concatUint8Arrays(buffers.map((b) => new Uint8Array(b)))\n\t\t.buffer as ArrayBuffer;\n}\n\nexport * from './promised';\n"],"names":["SleepFinished","sleep","ms","resolve","AcquireTimeoutError","Semaphore","concurrency","timeout","acquired","value","released","fn","release","PhpWasmError","message","userFriendlyMessage","joinPaths","paths","hasTrailingSlash","p","path","isAbsolute","trailingSlash","normalizePath","dirname","lastSlash","basename","normalizePathsArray","parts","allowAboveRoot","up","i","last","isParentOf","parent","child","ensureAbsolutePath","EventEmitterPolyfill","eventName","data","listener","wrappedListener","args","l","splitShellCommand","command","mode","quote","currentPart","char","WritablePolyfill","opts","chunk","encoding","cb","err","defer","needDrain","enc","entry","createSpawnHandler","program","argsArray","options","childProcess","ChildProcess","processApi","ProcessApi","commandArray","promise","e","code","lastPid","pid","self","randomString","length","specialChars","chars","result","randomFilename","phpVar","stringToBase64","phpVars","vars","key","str","bytesToBase64","bytes","binString","sprintf","format","argIndex","specifier","arg","wrapSynchronousInterfaceAsPromised","obj","keysAlreadySeen","keysToMakePromised","looksLikeBuiltInObject","proto","allKeys","promisifiedObj","concatUint8Arrays","arrays","totalLength","a","offset","concatArrayBuffers","buffers","b"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../../packages/php-wasm/util/src/lib/sleep.ts","../../../../packages/php-wasm/util/src/lib/semaphore.ts","../../../../packages/php-wasm/util/src/lib/php-wasm-error.ts","../../../../packages/php-wasm/util/src/lib/paths.ts","../../../../packages/php-wasm/util/src/lib/event-emitter-polyfill.ts","../../../../packages/php-wasm/util/src/lib/split-shell-command.ts","../../../../packages/php-wasm/util/src/lib/writable-polyfill.ts","../../../../packages/php-wasm/util/src/lib/create-spawn-handler.ts","../../../../packages/php-wasm/util/src/lib/random-string.ts","../../../../packages/php-wasm/util/src/lib/random-filename.ts","../../../../packages/php-wasm/util/src/lib/php-vars.ts","../../../../packages/php-wasm/util/src/lib/sprintf.ts","../../../../packages/php-wasm/util/src/lib/promised.ts","../../../../packages/php-wasm/util/src/lib/index.ts"],"sourcesContent":["export const SleepFinished = Symbol('SleepFinished');\n\nexport function sleep(ms: number): Promise<typeof SleepFinished> {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(() => resolve(SleepFinished), ms);\n\t});\n}\n","import { SleepFinished, sleep } from './sleep';\n\nexport interface SemaphoreOptions {\n\t/**\n\t * The maximum number of concurrent locks.\n\t */\n\tconcurrency: number;\n\t/**\n\t * The maximum time to wait for a lock to become available.\n\t */\n\ttimeout?: number;\n}\n\nexport class AcquireTimeoutError extends Error {\n\tconstructor() {\n\t\tsuper('Acquiring lock timed out');\n\t}\n}\n\nexport default class Semaphore {\n\tprivate _running = 0;\n\tprivate concurrency: number;\n\tprivate timeout?: number;\n\tprivate queue: (() => void)[];\n\n\tconstructor({ concurrency, timeout }: SemaphoreOptions) {\n\t\tthis.concurrency = concurrency;\n\t\tthis.timeout = timeout;\n\t\tthis.queue = [];\n\t}\n\n\tget remaining(): number {\n\t\treturn this.concurrency - this.running;\n\t}\n\n\tget running(): number {\n\t\treturn this._running;\n\t}\n\n\tasync acquire(): Promise<() => void> {\n\t\t// Concurrency exhausted - wait in queue for other workers to finish:\n\t\tif (this._running >= this.concurrency) {\n\t\t\t// Create a promise and store its resolver in the queue.\n\t\t\tconst acquired = new Promise<void>((resolve) => {\n\t\t\t\tthis.queue.push(resolve);\n\t\t\t});\n\n\t\t\t// Wait until it is resolved by another worker or a timeout occurs.\n\t\t\tif (this.timeout !== undefined) {\n\t\t\t\t// Store the resolver for cleanup in case of timeout.\n\t\t\t\tconst resolve = this.queue.at(-1)!;\n\t\t\t\tconst result = await Promise.race([\n\t\t\t\t\tacquired,\n\t\t\t\t\tsleep(this.timeout),\n\t\t\t\t]);\n\t\t\t\tif (result === SleepFinished) {\n\t\t\t\t\t// Remove the resolver for the timed out worker from the queue.\n\t\t\t\t\tthis.queue.splice(this.queue.indexOf(resolve), 1);\n\t\t\t\t\tthrow new AcquireTimeoutError();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tawait acquired;\n\t\t\t}\n\t\t}\n\n\t\t// Acquire the lock:\n\t\tthis._running++;\n\t\tlet released = false;\n\n\t\t// Return a release function:\n\t\treturn () => {\n\t\t\tif (released) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treleased = true;\n\t\t\tthis._running--;\n\n\t\t\t// Release the first item in the queue (call its resolver):\n\t\t\tif (this.queue.length > 0) {\n\t\t\t\tthis.queue.shift()!();\n\t\t\t}\n\t\t};\n\t}\n\n\tasync run<T>(fn: () => T | Promise<T>): Promise<T> {\n\t\tconst release = await this.acquire();\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} finally {\n\t\t\trelease();\n\t\t}\n\t}\n}\n","export class PhpWasmError extends Error {\n\tuserFriendlyMessage?: string;\n\tconstructor(message: string, userFriendlyMessage?: string) {\n\t\tsuper(message);\n\t\tthis.userFriendlyMessage = userFriendlyMessage ?? message;\n\t}\n}\n","/**\n * The functions in this module are mostly copied from the generated\n * Emscripten PHP module. This enables features like filesystem journaling,\n * which use some low-level Emscripten APIs and need access to the\n * same path helpers.\n */\n\n/**\n * Joins paths together.\n *\n * For example:\n *\n * > joinPaths('wordpress', 'wp-content')\n * 'wordpress/wp-content'\n *\n * Use this for all PHP paths and **do not** use path.join().\n * This is important because Emscripten paths are **always**\n * POSIX-style paths. Imagine joining paths on Windows:\n *\n * > path.join('wordpress', 'wp-content')\n * '\\\\wordpress\\\\wp-content' // invalid in PHP.wasm\n *\n * See the path.join issue for more details:\n *\n * https://github.com/WordPress/playground-tools/issues/11#issuecomment-1579074763\n *\n * @param paths Paths segments to join\n * @returns A joined path\n */\nexport function joinPaths(...paths: string[]) {\n\tfunction hasTrailingSlash(p: string) {\n\t\treturn p.substring(p.length - 1) === '/';\n\t}\n\n\tlet path = paths.join('/');\n\tconst isAbsolute = path[0] === '/';\n\tconst trailingSlash = hasTrailingSlash(path);\n\tpath = normalizePath(path);\n\tif (!path && !isAbsolute) {\n\t\tpath = '.';\n\t}\n\tif (path && trailingSlash && !hasTrailingSlash(path)) {\n\t\tpath += '/';\n\t}\n\treturn path;\n}\n\n/**\n * Returns the directory name of a path.\n *\n * @param path\n * @returns\n */\nexport function dirname(path: string) {\n\tif (path === '/') {\n\t\treturn '/';\n\t}\n\n\tpath = normalizePath(path);\n\n\tconst lastSlash = path.lastIndexOf('/');\n\tif (lastSlash === -1) {\n\t\treturn '';\n\t} else if (lastSlash === 0) {\n\t\treturn '/';\n\t}\n\treturn path.substr(0, lastSlash);\n}\n\n/**\n * Returns the last portion of a path.\n *\n * @param path - The path to extract the basename from.\n * @returns The basename of the path.\n */\nexport function basename(path: string) {\n\tif (path === '/') {\n\t\treturn '/';\n\t}\n\n\tpath = normalizePath(path);\n\n\tconst lastSlash = path.lastIndexOf('/');\n\tif (lastSlash === -1) {\n\t\treturn path;\n\t}\n\treturn path.substr(lastSlash + 1);\n}\n\n/**\n * Normalizes a path.\n *\n * For example:\n *\n * > normalizePath('wordpress/wp-content/../')\n * 'wordpress'\n *\n * @param path\n * @returns\n */\nexport function normalizePath(path: string) {\n\tconst isAbsolute = path[0] === '/';\n\tpath = normalizePathsArray(\n\t\tpath.split('/').filter((p: any) => !!p),\n\t\t!isAbsolute\n\t).join('/');\n\treturn (isAbsolute ? '/' : '') + path.replace(/\\/$/, '');\n}\n\n/**\n * Normalizes paths.\n *\n * For example:\n *\n * > normalizePathsArray(['wordpress', 'wp-content', '..', '', '.',\n * 'wp-includes']) ['wordpress', 'wp-includes']\n *\n * @param parts parts of the path to normalize\n * @param allowAboveRoot allow paths above the root\n * @returns normalized paths\n */\nexport function normalizePathsArray(parts: string[], allowAboveRoot: boolean) {\n\tlet up = 0;\n\tfor (let i = parts.length - 1; i >= 0; i--) {\n\t\tconst last = parts[i];\n\t\tif (last === '.') {\n\t\t\tparts.splice(i, 1);\n\t\t} else if (last === '..') {\n\t\t\tparts.splice(i, 1);\n\t\t\tup++;\n\t\t} else if (up) {\n\t\t\tparts.splice(i, 1);\n\t\t\tup--;\n\t\t}\n\t}\n\tif (allowAboveRoot) {\n\t\tfor (; up; up--) {\n\t\t\tparts.unshift('..');\n\t\t}\n\t}\n\treturn parts;\n}\n\n/**\n * Checks if the given parent path is an ancestor of the given child path.\n *\n * @param parent The parent path to check.\n * @param child The child path to verify against the parent.\n * @returns Whether the `parent` path is an ancestor of the `child` path.\n */\nexport function isParentOf(parent: string, child: string) {\n\tif (parent === '/') {\n\t\treturn true;\n\t}\n\tparent = normalizePath(parent);\n\tchild = normalizePath(child);\n\treturn child.startsWith(parent + '/') || child === parent;\n}\n\n/**\n * Guarantees a path is absolute by prepending `/` if needed.\n *\n * Useful when working with user-provided paths that might be relative,\n * or when you need to normalize edge cases like empty strings.\n *\n * For example:\n *\n * > ensureAbsolutePath('wp-content/uploads')\n * '/wp-content/uploads'\n *\n * > ensureAbsolutePath('/already/absolute')\n * '/already/absolute'\n *\n * > ensureAbsolutePath('')\n * '/'\n *\n * @param path - The path to make absolute.\n * @returns An absolute, normalized path starting with `/`.\n */\nexport function ensureAbsolutePath(path: string) {\n\treturn joinPaths('/', normalizePath(path || '/'));\n}\n\n/**\n * Converts a native OS path to a POSIX-style path.\n *\n * Transformations:\n * 1. Backslashes → forward slashes\n * 2. Windows drive letter `C:\\` → `/C/` (colons are invalid in\n * Emscripten VFS paths and cause ENOTDIR errno 28)\n *\n * On POSIX systems this is effectively a no-op.\n *\n * @see https://github.com/emscripten-core/emscripten/issues/17829\n */\nexport function toPosixPath(nativePath: string): string {\n\tlet result = nativePath.replaceAll('\\\\', '/');\n\t// Handle Windows drive letter: C:/ → /C/\n\tconst driveMatch = result.match(/^([A-Za-z]):\\//);\n\tif (driveMatch) {\n\t\tresult = '/' + driveMatch[1] + result.slice(2);\n\t}\n\treturn result;\n}\n","/**\n * Polyfills Node.js EventEmitter API. The main goal is to enable\n * using a child_process.spawn()-like API in both Node.js and the browser.\n *\n * @see https://nodejs.org/api/events.html#events_class_eventemitter\n */\ntype Listener = (...args: any[]) => any;\n\nexport class EventEmitterPolyfill {\n\tlisteners: Record<string, Listener[]> = {};\n\temit(eventName: string, data?: any) {\n\t\tif (this.listeners[eventName]) {\n\t\t\tthis.listeners[eventName].forEach(function (listener) {\n\t\t\t\tlistener(data);\n\t\t\t});\n\t\t}\n\t}\n\ton(eventName: string, listener: Listener) {\n\t\tif (!this.listeners[eventName]) {\n\t\t\tthis.listeners[eventName] = [];\n\t\t}\n\t\tthis.listeners[eventName].push(listener);\n\t}\n\tonce(eventName: string, listener: Listener) {\n\t\tconst wrappedListener = (...args: any[]) => {\n\t\t\tthis.off(eventName, wrappedListener);\n\t\t\tlistener(...args);\n\t\t};\n\t\tthis.on(eventName, wrappedListener);\n\t}\n\toff(eventName: string, listener: Listener) {\n\t\tif (this.listeners[eventName]) {\n\t\t\tthis.listeners[eventName] = this.listeners[eventName].filter(\n\t\t\t\t(l) => l !== listener\n\t\t\t);\n\t\t}\n\t}\n}\n","/**\n * Naive shell command parser.\n * Ensures that commands like `wp option set blogname \"My blog name\"` are split\n * into `['wp', 'option', 'set', 'blogname', 'My blog name']` instead of\n * `['wp', 'option', 'set', 'blogname', 'My', 'blog', 'name']`.\n *\n * @param command\n * @returns\n */\nexport function splitShellCommand(command: string) {\n\tconst MODE_UNQUOTED = 0;\n\tconst MODE_IN_QUOTE = 1;\n\n\tlet mode = MODE_UNQUOTED;\n\tlet quote = '';\n\n\tconst parts: string[] = [];\n\tlet currentPart = '';\n\tfor (let i = 0; i < command.length; i++) {\n\t\tconst char = command[i];\n\t\tif (char === '\\\\') {\n\t\t\t// Escaped quotes are treated as normal characters\n\t\t\t// This is a very naive approach to escaping, but it's good enough for\n\t\t\t// now. @TODO: Iterate on this later, perhaps using bun shell. @see https://github.com/WordPress/wordpress-playground/issues/1062\n\t\t\tif (command[i + 1] === '\"' || command[i + 1] === \"'\") {\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcurrentPart += command[i];\n\t\t} else if (mode === MODE_UNQUOTED) {\n\t\t\tif (char === '\"' || char === \"'\") {\n\t\t\t\tmode = MODE_IN_QUOTE;\n\t\t\t\tquote = char;\n\t\t\t} else if (char.match(/\\s/)) {\n\t\t\t\tif (currentPart.trim().length) {\n\t\t\t\t\tparts.push(currentPart.trim());\n\t\t\t\t}\n\t\t\t\tcurrentPart = char;\n\t\t\t} else if (parts.length && !currentPart) {\n\t\t\t\t// We just closed a quote to continue the same\n\t\t\t\t// argument with different escaping style, e.g.:\n\t\t\t\t// php -r 'require '\\''vendor/autoload.php'\\''\n\t\t\t\tcurrentPart = parts.pop()! + char;\n\t\t\t} else {\n\t\t\t\tcurrentPart += char;\n\t\t\t}\n\t\t} else if (mode === MODE_IN_QUOTE) {\n\t\t\tif (char === quote) {\n\t\t\t\tmode = MODE_UNQUOTED;\n\t\t\t\tquote = '';\n\t\t\t} else {\n\t\t\t\tcurrentPart += char;\n\t\t\t}\n\t\t}\n\t}\n\tif (currentPart) {\n\t\tparts.push(currentPart.trim());\n\t}\n\treturn parts;\n}\n","/**\n * Polyfills Node.js WritableStream API. The main goal is to enable\n * using a child_process.spawn()-like API in both Node.js and the browser.\n *\n * @see https://nodejs.org/api/stream.html#stream_writable_end_chunk_encoding_callback\n */\nimport { EventEmitterPolyfill } from './event-emitter-polyfill';\n\nexport interface WritableOptions {\n\thighWaterMark?: number;\n\tdecodeStrings?: boolean;\n\tdefaultEncoding?: BufferEncoding;\n\twrite: (chunk: any, encoding: BufferEncoding, cb: WriteCallback) => void;\n}\n\nexport type WriteCallback = (error?: Error | null) => void;\n\nexport class WritablePolyfill extends EventEmitterPolyfill {\n\tprivate buffer: Array<{\n\t\tchunk: any;\n\t\tencoding: BufferEncoding;\n\t\tcb: WriteCallback;\n\t}> = [];\n\tprivate writing = false;\n\tpublic ended = false;\n\tprivate length = 0;\n\tprivate highWaterMark: number;\n\tprivate decodeStrings: boolean;\n\tprivate defaultEncoding: BufferEncoding;\n\tprivate defer: (fn: () => void) => void;\n\tprivate _write: (\n\t\tchunk: any,\n\t\tencoding: BufferEncoding,\n\t\tcb: WriteCallback\n\t) => void;\n\n\tconstructor(opts: WritableOptions) {\n\t\tsuper();\n\t\tif (!opts.write) {\n\t\t\tthrow new Error('WritablePolyfill requires write option');\n\t\t}\n\t\tthis._write = opts.write;\n\t\tthis.highWaterMark = opts.highWaterMark ?? 16 * 1024;\n\t\tthis.decodeStrings = opts.decodeStrings ?? true;\n\t\tthis.defaultEncoding = opts.defaultEncoding ?? 'utf8';\n\t\t// queueMicrotask keeps browser support; fallback for older environments.\n\t\tthis.defer =\n\t\t\ttypeof queueMicrotask === 'function'\n\t\t\t\t? queueMicrotask\n\t\t\t\t: (fn) => setTimeout(fn, 0);\n\t}\n\n\twrite(\n\t\tchunk: any,\n\t\tencoding: BufferEncoding | WriteCallback = this.defaultEncoding,\n\t\tcb: WriteCallback = () => {}\n\t): boolean {\n\t\tif (typeof encoding === 'function') {\n\t\t\tcb = encoding as WriteCallback;\n\t\t\tencoding = this.defaultEncoding;\n\t\t}\n\n\t\tif (this.ended) {\n\t\t\tconst err = new Error('write after end');\n\t\t\t// We can't call this.defer() directly. If this.defer is\n\t\t\t// `queueMicrotask`, a `this.defer()` call will pass the\n\t\t\t// WritablePolyfill instance as `this` argument and cause\n\t\t\t// the browser to throw an error similar to \"Invalid\n\t\t\t// invocation\".\n\t\t\tconst defer = this.defer;\n\t\t\tdefer(() => cb(err));\n\t\t\tthis.emit('error', err);\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.decodeStrings && typeof chunk === 'string') {\n\t\t\tif (\n\t\t\t\ttypeof Buffer !== 'undefined' &&\n\t\t\t\ttypeof (Buffer as any).from === 'function'\n\t\t\t) {\n\t\t\t\tchunk = Buffer.from(chunk, encoding as BufferEncoding);\n\t\t\t} else if (typeof TextEncoder !== 'undefined') {\n\t\t\t\tchunk = new TextEncoder().encode(chunk);\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'String chunks are not supported in this environment: Buffer and TextEncoder are unavailable.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tencoding = 'buffer' as BufferEncoding;\n\t\t}\n\n\t\tthis.length += chunk.length ?? 1;\n\t\tconst needDrain = this.length >= this.highWaterMark;\n\n\t\tthis.buffer.push({ chunk, encoding: encoding as BufferEncoding, cb });\n\n\t\tif (!this.writing) this._clearBuffer();\n\n\t\treturn !needDrain;\n\t}\n\n\tend(\n\t\tchunk?: any,\n\t\tencoding?: BufferEncoding | WriteCallback,\n\t\tcb?: WriteCallback\n\t): void {\n\t\tif (typeof chunk === 'function') {\n\t\t\tcb = chunk;\n\t\t\tchunk = undefined;\n\t\t} else if (typeof encoding === 'function') {\n\t\t\tcb = encoding as WriteCallback;\n\t\t\tencoding = undefined;\n\t\t}\n\n\t\tif (chunk !== undefined)\n\t\t\tthis.write(chunk, encoding as BufferEncoding, () => {});\n\t\tthis.ended = true;\n\t\tif (!this.writing) this._clearBuffer();\n\t\tif (cb) this.defer(cb);\n\t}\n\n\t// Stubs kept for API parity; add logic if you depend on corking.\n\tcork(): void {}\n\tuncork(): void {}\n\n\tsetDefaultEncoding(enc: BufferEncoding): this {\n\t\tthis.defaultEncoding = enc;\n\t\treturn this;\n\t}\n\n\tprivate _clearBuffer(): void {\n\t\tconst entry = this.buffer.shift();\n\t\tif (!entry) {\n\t\t\tif (this.ended) this.emit('finish');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.writing = true;\n\t\tthis._write(entry.chunk, entry.encoding, (err?: Error | null) => {\n\t\t\tthis.writing = false;\n\t\t\tthis.length -= entry.chunk.length ?? 1;\n\t\t\tif (err) this.emit('error', err);\n\t\t\tentry.cb(err);\n\n\t\t\tif (this.buffer.length) {\n\t\t\t\tthis._clearBuffer();\n\t\t\t} else {\n\t\t\t\tif (this.length < this.highWaterMark) this.emit('drain');\n\t\t\t\tif (this.ended) this.emit('finish');\n\t\t\t}\n\t\t});\n\t}\n}\n","import { EventEmitterPolyfill } from './event-emitter-polyfill';\nimport { splitShellCommand } from './split-shell-command';\nimport { WritablePolyfill, type WriteCallback } from './writable-polyfill';\n\ntype Listener = (...args: any[]) => any;\n\nexport interface ProcessOptions {\n\tcwd?: string;\n\tenv?: Record<string, string>;\n}\n\n/**\n * Usage:\n * ```ts\n * php.setSpawnHandler(\n * createSpawnHandler(function (command, processApi) {\n * console.log(processApi.flushStdin());\n * processApi.stdout('/\\n/tmp\\n/home');\n *\t processApi.exit(0);\n * })\n * );\n * ```\n * @param program\n * @returns\n */\nexport function createSpawnHandler(\n\tprogram: (\n\t\tcommand: string[],\n\t\tprocessApi: ProcessApi,\n\t\toptions: ProcessOptions\n\t) => void | Promise<void>\n): any {\n\treturn function (\n\t\tcommand: string | string[],\n\t\targsArray: string[] = [],\n\t\toptions: ProcessOptions = {}\n\t) {\n\t\tconst childProcess = new ChildProcess();\n\t\tconst processApi = new ProcessApi(childProcess);\n\t\t// Give PHP a chance to register listeners\n\t\tsetTimeout(async () => {\n\t\t\tlet commandArray = [];\n\t\t\tif (argsArray.length) {\n\t\t\t\tcommandArray = [command as string, ...argsArray];\n\t\t\t} else if (typeof command === 'string') {\n\t\t\t\tcommandArray = splitShellCommand(command);\n\t\t\t} else if (Array.isArray(command)) {\n\t\t\t\tcommandArray = command;\n\t\t\t} else {\n\t\t\t\tthrow new Error('Invalid command ', command);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst promise = program(commandArray, processApi, options);\n\t\t\t\tif (\n\t\t\t\t\ttypeof promise !== 'object' ||\n\t\t\t\t\tpromise === null ||\n\t\t\t\t\t!('then' in promise)\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`The program callback passed to createSpawnHandler() did not return a promise. It indicates there's a bug in your code. ` +\n\t\t\t\t\t\t\t`The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() ` +\n\t\t\t\t\t\t\t`call. All the streams would be closed already. Make sure to put an \"await new Promise(resolve => setTimeout(resolve, 1))` +\n\t\t\t\t\t\t\t`before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`\n\t\t\t\t\t);\n\t\t\t\t} else if (processApi.exited) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`The program callback passed to createSpawnHandler() exited synchronously. It indicates there's a bug in your code. ` +\n\t\t\t\t\t\t\t`The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() ` +\n\t\t\t\t\t\t\t`call. All the streams would be closed already. Make sure to put an \"await new Promise(resolve => setTimeout(resolve, 1))` +\n\t\t\t\t\t\t\t`before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tchildProcess.emit('spawn', true);\n\t\t\t\tawait promise;\n\t\t\t} catch (e) {\n\t\t\t\tchildProcess.emit('error', e);\n\t\t\t\tif (\n\t\t\t\t\ttypeof e === 'object' &&\n\t\t\t\t\te !== null &&\n\t\t\t\t\t'message' in e &&\n\t\t\t\t\ttypeof e.message === 'string'\n\t\t\t\t) {\n\t\t\t\t\tprocessApi.stderr(e.message);\n\t\t\t\t}\n\t\t\t\tprocessApi.exit(1);\n\t\t\t}\n\t\t});\n\t\treturn childProcess;\n\t};\n}\n\nexport class ProcessApi extends EventEmitterPolyfill {\n\tpublic exited = false;\n\t/**\n\t * Keeps track of the data that was written to stdin before the\n\t * first listener was registered.\n\t */\n\tprivate stdinBuffer: Uint8Array[] | null = [];\n\tpublic childProcess: ChildProcess;\n\tconstructor(childProcess: ChildProcess) {\n\t\tsuper();\n\t\tthis.childProcess = childProcess;\n\t\tchildProcess.on('stdin', (data: Uint8Array) => {\n\t\t\tif (this.stdinBuffer) {\n\t\t\t\t// Need to clone the data buffer as it's reused by PHP\n\t\t\t\t// and the next data chunk will overwrite the previous one.\n\t\t\t\tthis.stdinBuffer.push(data.slice());\n\t\t\t} else {\n\t\t\t\tthis.emit('stdin', data);\n\t\t\t}\n\t\t});\n\t}\n\tstdinEnd() {\n\t\tif (!this.childProcess.stdin.ended) {\n\t\t\tthis.childProcess.stdin.end();\n\t\t}\n\t}\n\tstdout(data: string | ArrayBuffer) {\n\t\tthis.childProcess.stdout.write(data);\n\t}\n\tstdoutEnd() {\n\t\tif (!this.childProcess.stdout.ended) {\n\t\t\tthis.childProcess.stdout.end();\n\t\t}\n\t}\n\tstderr(data: string | ArrayBuffer) {\n\t\tthis.childProcess.stderr.write(data);\n\t}\n\tstderrEnd() {\n\t\tif (!this.childProcess.stderr.ended) {\n\t\t\tthis.childProcess.stderr.end();\n\t\t}\n\t}\n\tnotifySpawn() {\n\t\tthis.childProcess.emit('spawn', true);\n\t}\n\texit(code: number) {\n\t\tif (!this.exited) {\n\t\t\tthis.exited = true;\n\t\t\tthis.stdinEnd();\n\t\t\tthis.stdoutEnd();\n\t\t\tthis.stderrEnd();\n\t\t\tthis.childProcess.emit('exit', code);\n\t\t}\n\t}\n\toverride on(eventName: string, listener: Listener) {\n\t\tsuper.on(eventName, listener);\n\t\t/**\n\t\t * If it's the first stdin listener, flush all the data we've\n\t\t * buffered so far.\n\t\t */\n\t\tif (eventName === 'stdin' && this.stdinBuffer) {\n\t\t\tfor (let i = 0; i < this.stdinBuffer.length; i++) {\n\t\t\t\tthis.emit('stdin', this.stdinBuffer[i]);\n\t\t\t}\n\t\t\tthis.stdinBuffer = null;\n\t\t}\n\t}\n}\n\nlet lastPid = 9743;\nexport class ChildProcess extends EventEmitterPolyfill {\n\tstdout: WritablePolyfill;\n\tstderr: WritablePolyfill;\n\tstdin: WritablePolyfill;\n\tpid: number;\n\tconstructor(pid = lastPid++) {\n\t\tsuper();\n\t\tthis.pid = pid;\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this;\n\t\tthis.stdout = new WritablePolyfill({\n\t\t\twrite(data: any, encoding: BufferEncoding, cb: WriteCallback) {\n\t\t\t\tself.stdout.emit('data', data);\n\t\t\t\tcb();\n\t\t\t},\n\t\t});\n\t\tthis.stderr = new WritablePolyfill({\n\t\t\twrite: (data: any, encoding: BufferEncoding, cb: WriteCallback) => {\n\t\t\t\tself.stderr.emit('data', data);\n\t\t\t\tcb();\n\t\t\t},\n\t\t});\n\t\tthis.stdin = new WritablePolyfill({\n\t\t\twrite: (data: any, encoding: BufferEncoding, cb: WriteCallback) => {\n\t\t\t\tself.emit('stdin', data);\n\t\t\t\tcb();\n\t\t\t},\n\t\t});\n\t}\n}\n","export function randomString(\n\tlength = 36,\n\tspecialChars = '!@#$%^&*()_+=-[]/.,<>?'\n) {\n\tconst chars =\n\t\t'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' +\n\t\tspecialChars;\n\tlet result = '';\n\tfor (let i = length; i > 0; --i)\n\t\tresult += chars[Math.floor(Math.random() * chars.length)];\n\treturn result;\n}\n","import { randomString } from './random-string';\n\nexport function randomFilename() {\n\treturn randomString(36, '-_');\n}\n","export function phpVar(value: unknown): string {\n\treturn `json_decode(base64_decode('${stringToBase64(\n\t\tJSON.stringify(value)\n\t)}'), true)`;\n}\n\nexport function phpVars<T extends Record<string, unknown>>(\n\tvars: T\n): Record<keyof T, string> {\n\tconst result: Record<string, string> = {};\n\tfor (const key in vars) {\n\t\tresult[key] = phpVar(vars[key]);\n\t}\n\treturn result as Record<keyof T, string>;\n}\n\nfunction stringToBase64(str: string) {\n\treturn bytesToBase64(new TextEncoder().encode(str));\n}\n\nfunction bytesToBase64(bytes: Uint8Array) {\n\tconst binString = String.fromCodePoint(...bytes);\n\treturn btoa(binString);\n}\n","/**\n * Formats a string like sprintf().\n *\n * This function:\n * - Supports basic format specifiers: %s, %d, %f, %x, %%\n * - Supports bigint values\n *\n * The purpose of this function is for use in optional php-wasm tracing.\n * If we use printf-style formatting for trace messages, we let the trace\n * function decide whether to format and do not have to pay for formatting\n * unless tracing is enabled.\n */\nexport function sprintf(format: string, ...args: any[]): string {\n\tlet result = '';\n\tlet argIndex = 0;\n\n\tfor (let i = 0; i < format.length; i++) {\n\t\tif (format[i] === '%' && i + 1 < format.length) {\n\t\t\ti++;\n\t\t\tconst specifier = format[i];\n\n\t\t\tswitch (specifier) {\n\t\t\t\tcase 's': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tlet str;\n\t\t\t\t\tif (typeof arg === 'object') {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// If an object doesn't provide its own toString(),\n\t\t\t\t\t\t\t// try to represent it as JSON.\n\t\t\t\t\t\t\tstr = JSON.stringify(\n\t\t\t\t\t\t\t\targ,\n\t\t\t\t\t\t\t\t// Represent bigint values as strings in JSON.stringify().\n\t\t\t\t\t\t\t\t(key, value) => {\n\t\t\t\t\t\t\t\t\tif (typeof value === 'bigint') {\n\t\t\t\t\t\t\t\t\t\treturn `0x${value.toString(16)}`;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t2\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Ignore error and use default representation.\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = String(arg);\n\t\t\t\t\t}\n\n\t\t\t\t\tresult += str;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'd': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tif (typeof arg === 'bigint') {\n\t\t\t\t\t\tresult += arg.toString();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += Math.floor(Number(arg));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'f': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tif (typeof arg === 'bigint') {\n\t\t\t\t\t\tresult += Number(arg);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += Number(arg);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'x': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tif (typeof arg === 'bigint') {\n\t\t\t\t\t\tresult += arg.toString(16);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += Math.floor(Number(arg)).toString(16);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase '%': {\n\t\t\t\t\tresult += '%';\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tresult += '%' + specifier;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tresult += format[i];\n\t\t}\n\t}\n\n\treturn result;\n}\n","// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\ntype PromisedMethod<T extends (...args: any[]) => any> = (\n\t...args: Parameters<T>\n) => Promise<ReturnType<T>>;\n\nexport type Promised<T> = {\n\t[P in keyof T]: T[P] extends (...args: any[]) => any\n\t\t? PromisedMethod<T[P]>\n\t\t: T[P];\n};\n\n/**\n * Wraps a synchronous interface as a promised interface.\n *\n * This function tries to avoid wrapping methods inherited from\n * built-in JS object types (e.g., `Object`, `Array`, `Function`, etc.).\n *\n * The initial use case for this function is for unit testing\n * file locking in php-wasm. Php-wasm for JSPI expects the file lock manager\n * to be a promised interface used via comlink,\n * but the interface itself is synchronous.\n *\n * @param obj\n * @returns A promised interface that wraps the synchronous interface.\n */\nexport function wrapSynchronousInterfaceAsPromised<T extends object>(\n\tobj: T\n): Promised<T> {\n\tconst keysAlreadySeen = new Set<string | symbol>();\n\tconst keysToMakePromised = new Set<string | symbol>();\n\tconst looksLikeBuiltInObject =\n\t\t// NOTE: We don't generally add custom things to the global scope,\n\t\t// so let's use this as a heuristic to determine if an object is a built-in object type.\n\t\t(obj: object) =>\n\t\t\t(globalThis as any)[obj.constructor.name] !== obj.constructor;\n\n\tlet proto: object = obj;\n\twhile (proto !== null && !looksLikeBuiltInObject(proto)) {\n\t\tconst allKeys = [\n\t\t\t...Object.getOwnPropertyNames(proto),\n\t\t\t...Object.getOwnPropertySymbols(proto),\n\t\t];\n\t\tfor (const key of allKeys) {\n\t\t\tif (\n\t\t\t\t// Track keys already seen so an inherited method property\n\t\t\t\t// masked by a descendant property of the same name is not considered.\n\t\t\t\t!keysAlreadySeen.has(key) &&\n\t\t\t\t!keysToMakePromised.has(key) &&\n\t\t\t\ttypeof (proto as any)[key] === 'function'\n\t\t\t) {\n\t\t\t\tkeysToMakePromised.add(key);\n\t\t\t}\n\t\t\tkeysAlreadySeen.add(key);\n\t\t}\n\t\tproto = Object.getPrototypeOf(proto);\n\t}\n\n\t// NOTE: We could use Proxy here instead,\n\t// but providing a regular object is ultimately simpler.\n\tconst promisifiedObj = Object.create(obj);\n\tfor (const key of keysToMakePromised) {\n\t\tpromisifiedObj[key] = function (...args: any[]) {\n\t\t\treturn Promise.resolve((obj as any)[key](...args));\n\t\t};\n\t}\n\treturn promisifiedObj;\n}\n","import Semaphore, { AcquireTimeoutError } from './semaphore';\nexport { Semaphore, AcquireTimeoutError };\nexport { PhpWasmError } from './php-wasm-error';\nexport type { SemaphoreOptions } from './semaphore';\nexport {\n\tdirname,\n\tjoinPaths,\n\tbasename,\n\tnormalizePath,\n\tisParentOf,\n\tensureAbsolutePath,\n\ttoPosixPath,\n} from './paths';\nexport { createSpawnHandler } from './create-spawn-handler';\nexport { randomString } from './random-string';\nexport { randomFilename } from './random-filename';\nexport { splitShellCommand } from './split-shell-command';\nexport { WritablePolyfill, type WritableOptions } from './writable-polyfill';\nexport { EventEmitterPolyfill } from './event-emitter-polyfill';\nexport * from './php-vars';\n\nexport * from './sprintf';\n\nexport function concatUint8Arrays(arrays: Uint8Array[]): Uint8Array {\n\tlet totalLength = 0;\n\tarrays.forEach((a) => (totalLength += a.length));\n\tconst result = new Uint8Array(totalLength);\n\tlet offset = 0;\n\tarrays.forEach((a) => {\n\t\tresult.set(a, offset);\n\t\toffset += a.length;\n\t});\n\treturn result;\n}\n\nexport function concatArrayBuffers(buffers: ArrayBuffer[]): ArrayBuffer {\n\treturn concatUint8Arrays(buffers.map((b) => new Uint8Array(b)))\n\t\t.buffer as ArrayBuffer;\n}\n\nexport * from './promised';\n"],"names":["SleepFinished","sleep","ms","resolve","AcquireTimeoutError","Semaphore","concurrency","timeout","acquired","released","fn","release","PhpWasmError","message","userFriendlyMessage","joinPaths","paths","hasTrailingSlash","p","path","isAbsolute","trailingSlash","normalizePath","dirname","lastSlash","basename","normalizePathsArray","parts","allowAboveRoot","up","i","last","isParentOf","parent","child","ensureAbsolutePath","toPosixPath","nativePath","result","driveMatch","EventEmitterPolyfill","eventName","data","listener","wrappedListener","args","l","splitShellCommand","command","mode","quote","currentPart","char","WritablePolyfill","opts","chunk","encoding","cb","err","defer","needDrain","enc","entry","createSpawnHandler","program","argsArray","options","childProcess","ChildProcess","processApi","ProcessApi","commandArray","promise","e","code","lastPid","pid","self","randomString","length","specialChars","chars","randomFilename","phpVar","value","stringToBase64","phpVars","vars","key","str","bytesToBase64","bytes","binString","sprintf","format","argIndex","specifier","arg","wrapSynchronousInterfaceAsPromised","obj","keysAlreadySeen","keysToMakePromised","looksLikeBuiltInObject","proto","allKeys","promisifiedObj","concatUint8Arrays","arrays","totalLength","a","offset","concatArrayBuffers","buffers","b"],"mappings":"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"}
package/index.js CHANGED
@@ -4,7 +4,7 @@ function g(i) {
4
4
  setTimeout(() => e(d), i);
5
5
  });
6
6
  }
7
- class w extends Error {
7
+ class p extends Error {
8
8
  constructor() {
9
9
  super("Acquiring lock timed out");
10
10
  }
@@ -20,24 +20,25 @@ class k {
20
20
  return this._running;
21
21
  }
22
22
  async acquire() {
23
- for (; ; )
24
- if (this._running >= this.concurrency) {
25
- const e = new Promise((t) => {
26
- this.queue.push(t);
27
- });
28
- this.timeout !== void 0 ? await Promise.race([e, g(this.timeout)]).then(
29
- (t) => {
30
- if (t === d)
31
- throw new w();
32
- }
33
- ) : await e;
34
- } else {
35
- this._running++;
36
- let e = !1;
37
- return () => {
38
- e || (e = !0, this._running--, this.queue.length > 0 && this.queue.shift()());
39
- };
40
- }
23
+ if (this._running >= this.concurrency) {
24
+ const t = new Promise((r) => {
25
+ this.queue.push(r);
26
+ });
27
+ if (this.timeout !== void 0) {
28
+ const r = this.queue.at(-1);
29
+ if (await Promise.race([
30
+ t,
31
+ g(this.timeout)
32
+ ]) === d)
33
+ throw this.queue.splice(this.queue.indexOf(r), 1), new p();
34
+ } else
35
+ await t;
36
+ }
37
+ this._running++;
38
+ let e = !1;
39
+ return () => {
40
+ e || (e = !0, this._running--, this.queue.length > 0 && this.queue.shift()());
41
+ };
41
42
  }
42
43
  async run(e) {
43
44
  const t = await this.acquire();
@@ -48,34 +49,34 @@ class k {
48
49
  }
49
50
  }
50
51
  }
51
- class M extends Error {
52
+ class A extends Error {
52
53
  constructor(e, t) {
53
54
  super(e), this.userFriendlyMessage = t ?? e;
54
55
  }
55
56
  }
56
- function p(...i) {
57
- function e(f) {
58
- return f.substring(f.length - 1) === "/";
57
+ function w(...i) {
58
+ function e(l) {
59
+ return l.substring(l.length - 1) === "/";
59
60
  }
60
61
  let t = i.join("/");
61
62
  const r = t[0] === "/", s = e(t);
62
- return t = u(t), !t && !r && (t = "."), t && s && !e(t) && (t += "/"), t;
63
+ return t = f(t), !t && !r && (t = "."), t && s && !e(t) && (t += "/"), t;
63
64
  }
64
- function A(i) {
65
+ function M(i) {
65
66
  if (i === "/")
66
67
  return "/";
67
- i = u(i);
68
+ i = f(i);
68
69
  const e = i.lastIndexOf("/");
69
70
  return e === -1 ? "" : e === 0 ? "/" : i.substr(0, e);
70
71
  }
71
72
  function B(i) {
72
73
  if (i === "/")
73
74
  return "/";
74
- i = u(i);
75
+ i = f(i);
75
76
  const e = i.lastIndexOf("/");
76
77
  return e === -1 ? i : i.substr(e + 1);
77
78
  }
78
- function u(i) {
79
+ function f(i) {
79
80
  const e = i[0] === "/";
80
81
  return i = y(
81
82
  i.split("/").filter((t) => !!t),
@@ -93,11 +94,16 @@ function y(i, e) {
93
94
  i.unshift("..");
94
95
  return i;
95
96
  }
96
- function U(i, e) {
97
- return i === "/" ? !0 : (i = u(i), e = u(e), e.startsWith(i + "/") || e === i);
97
+ function q(i, e) {
98
+ return i === "/" ? !0 : (i = f(i), e = f(e), e.startsWith(i + "/") || e === i);
98
99
  }
99
- function q(i) {
100
- return p("/", u(i || "/"));
100
+ function U(i) {
101
+ return w("/", f(i || "/"));
102
+ }
103
+ function D(i) {
104
+ let e = i.replaceAll("\\", "/");
105
+ const t = e.match(/^([A-Za-z]):\//);
106
+ return t && (e = "/" + t[1] + e.slice(2)), e;
101
107
  }
102
108
  class a {
103
109
  constructor() {
@@ -125,13 +131,13 @@ class a {
125
131
  }
126
132
  function m(i) {
127
133
  let r = 0, s = "";
128
- const f = [];
134
+ const l = [];
129
135
  let n = "";
130
136
  for (let o = 0; o < i.length; o++) {
131
- const l = i[o];
132
- l === "\\" ? ((i[o + 1] === '"' || i[o + 1] === "'") && o++, n += i[o]) : r === 0 ? l === '"' || l === "'" ? (r = 1, s = l) : l.match(/\s/) ? (n.trim().length && f.push(n.trim()), n = l) : f.length && !n ? n = f.pop() + l : n += l : r === 1 && (l === s ? (r = 0, s = "") : n += l);
137
+ const u = i[o];
138
+ u === "\\" ? ((i[o + 1] === '"' || i[o + 1] === "'") && o++, n += i[o]) : r === 0 ? u === '"' || u === "'" ? (r = 1, s = u) : u.match(/\s/) ? (n.trim().length && l.push(n.trim()), n = u) : l.length && !n ? n = l.pop() + u : n += u : r === 1 && (u === s ? (r = 0, s = "") : n += u);
133
139
  }
134
- return n && f.push(n.trim()), f;
140
+ return n && l.push(n.trim()), l;
135
141
  }
136
142
  class h extends a {
137
143
  constructor(e) {
@@ -142,8 +148,8 @@ class h extends a {
142
148
  write(e, t = this.defaultEncoding, r = () => {
143
149
  }) {
144
150
  if (typeof t == "function" && (r = t, t = this.defaultEncoding), this.ended) {
145
- const f = new Error("write after end"), n = this.defer;
146
- return n(() => r(f)), this.emit("error", f), !1;
151
+ const l = new Error("write after end"), n = this.defer;
152
+ return n(() => r(l)), this.emit("error", l), !1;
147
153
  }
148
154
  if (this.decodeStrings && typeof e == "string") {
149
155
  if (typeof Buffer < "u" && typeof Buffer.from == "function")
@@ -183,9 +189,9 @@ class h extends a {
183
189
  });
184
190
  }
185
191
  }
186
- function D(i) {
192
+ function I(i) {
187
193
  return function(e, t = [], r = {}) {
188
- const s = new P(), f = new b(s);
194
+ const s = new E(), l = new b(s);
189
195
  return setTimeout(async () => {
190
196
  let n = [];
191
197
  if (t.length)
@@ -197,18 +203,18 @@ function D(i) {
197
203
  else
198
204
  throw new Error("Invalid command ", e);
199
205
  try {
200
- const o = i(n, f, r);
206
+ const o = i(n, l, r);
201
207
  if (typeof o != "object" || o === null || !("then" in o))
202
208
  throw new Error(
203
209
  `The program callback passed to createSpawnHandler() did not return a promise. It indicates there's a bug in your code. The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() call. All the streams would be closed already. Make sure to put an "await new Promise(resolve => setTimeout(resolve, 1))before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`
204
210
  );
205
- if (f.exited)
211
+ if (l.exited)
206
212
  throw new Error(
207
213
  `The program callback passed to createSpawnHandler() exited synchronously. It indicates there's a bug in your code. The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() call. All the streams would be closed already. Make sure to put an "await new Promise(resolve => setTimeout(resolve, 1))before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`
208
214
  );
209
215
  s.emit("spawn", !0), await o;
210
216
  } catch (o) {
211
- s.emit("error", o), typeof o == "object" && o !== null && "message" in o && typeof o.message == "string" && f.stderr(o.message), f.exit(1);
217
+ s.emit("error", o), typeof o == "object" && o !== null && "message" in o && typeof o.message == "string" && l.stderr(o.message), l.exit(1);
212
218
  }
213
219
  }), s;
214
220
  };
@@ -248,22 +254,22 @@ class b extends a {
248
254
  }
249
255
  }
250
256
  }
251
- let E = 9743;
252
- class P extends a {
253
- constructor(e = E++) {
257
+ let P = 9743;
258
+ class E extends a {
259
+ constructor(e = P++) {
254
260
  super(), this.pid = e;
255
261
  const t = this;
256
262
  this.stdout = new h({
257
- write(r, s, f) {
258
- t.stdout.emit("data", r), f();
263
+ write(r, s, l) {
264
+ t.stdout.emit("data", r), l();
259
265
  }
260
266
  }), this.stderr = new h({
261
- write: (r, s, f) => {
262
- t.stderr.emit("data", r), f();
267
+ write: (r, s, l) => {
268
+ t.stderr.emit("data", r), l();
263
269
  }
264
270
  }), this.stdin = new h({
265
- write: (r, s, f) => {
266
- t.emit("stdin", r), f();
271
+ write: (r, s, l) => {
272
+ t.emit("stdin", r), l();
267
273
  }
268
274
  });
269
275
  }
@@ -275,34 +281,34 @@ function S(i = 36, e = "!@#$%^&*()_+=-[]/.,<>?") {
275
281
  r += t[Math.floor(Math.random() * t.length)];
276
282
  return r;
277
283
  }
278
- function I() {
284
+ function j() {
279
285
  return S(36, "-_");
280
286
  }
281
- function O(i) {
282
- return `json_decode(base64_decode('${x(
287
+ function x(i) {
288
+ return `json_decode(base64_decode('${O(
283
289
  JSON.stringify(i)
284
290
  )}'), true)`;
285
291
  }
286
- function j(i) {
292
+ function W(i) {
287
293
  const e = {};
288
294
  for (const t in i)
289
- e[t] = O(i[t]);
295
+ e[t] = x(i[t]);
290
296
  return e;
291
297
  }
292
- function x(i) {
298
+ function O(i) {
293
299
  return T(new TextEncoder().encode(i));
294
300
  }
295
301
  function T(i) {
296
302
  const e = String.fromCodePoint(...i);
297
303
  return btoa(e);
298
304
  }
299
- function W(i, ...e) {
305
+ function H(i, ...e) {
300
306
  let t = "", r = 0;
301
307
  for (let s = 0; s < i.length; s++)
302
308
  if (i[s] === "%" && s + 1 < i.length) {
303
309
  s++;
304
- const f = i[s];
305
- switch (f) {
310
+ const l = i[s];
311
+ switch (l) {
306
312
  case "s": {
307
313
  const n = e[r++];
308
314
  let o;
@@ -311,7 +317,7 @@ function W(i, ...e) {
311
317
  o = JSON.stringify(
312
318
  n,
313
319
  // Represent bigint values as strings in JSON.stringify().
314
- (l, c) => typeof c == "bigint" ? `0x${c.toString(16)}` : c,
320
+ (u, c) => typeof c == "bigint" ? `0x${c.toString(16)}` : c,
315
321
  2
316
322
  );
317
323
  } catch {
@@ -341,13 +347,13 @@ function W(i, ...e) {
341
347
  break;
342
348
  }
343
349
  default:
344
- t += "%" + f;
350
+ t += "%" + l;
345
351
  }
346
352
  } else
347
353
  t += i[s];
348
354
  return t;
349
355
  }
350
- function H(i) {
356
+ function N(i) {
351
357
  const e = /* @__PURE__ */ new Set(), t = /* @__PURE__ */ new Set(), r = (
352
358
  // NOTE: We don't generally add custom things to the global scope,
353
359
  // so let's use this as a heuristic to determine if an object is a built-in object type.
@@ -365,12 +371,12 @@ function H(i) {
365
371
  !e.has(o) && !t.has(o) && typeof s[o] == "function" && t.add(o), e.add(o);
366
372
  s = Object.getPrototypeOf(s);
367
373
  }
368
- const f = Object.create(i);
374
+ const l = Object.create(i);
369
375
  for (const n of t)
370
- f[n] = function(...o) {
376
+ l[n] = function(...o) {
371
377
  return Promise.resolve(i[n](...o));
372
378
  };
373
- return f;
379
+ return l;
374
380
  }
375
381
  function _(i) {
376
382
  let e = 0;
@@ -381,30 +387,31 @@ function _(i) {
381
387
  t.set(s, r), r += s.length;
382
388
  }), t;
383
389
  }
384
- function N(i) {
390
+ function Q(i) {
385
391
  return _(i.map((e) => new Uint8Array(e))).buffer;
386
392
  }
387
393
  export {
388
- w as AcquireTimeoutError,
394
+ p as AcquireTimeoutError,
389
395
  a as EventEmitterPolyfill,
390
- M as PhpWasmError,
396
+ A as PhpWasmError,
391
397
  k as Semaphore,
392
398
  h as WritablePolyfill,
393
399
  B as basename,
394
- N as concatArrayBuffers,
400
+ Q as concatArrayBuffers,
395
401
  _ as concatUint8Arrays,
396
- D as createSpawnHandler,
397
- A as dirname,
398
- q as ensureAbsolutePath,
399
- U as isParentOf,
400
- p as joinPaths,
401
- u as normalizePath,
402
- O as phpVar,
403
- j as phpVars,
404
- I as randomFilename,
402
+ I as createSpawnHandler,
403
+ M as dirname,
404
+ U as ensureAbsolutePath,
405
+ q as isParentOf,
406
+ w as joinPaths,
407
+ f as normalizePath,
408
+ x as phpVar,
409
+ W as phpVars,
410
+ j as randomFilename,
405
411
  S as randomString,
406
412
  m as splitShellCommand,
407
- W as sprintf,
408
- H as wrapSynchronousInterfaceAsPromised
413
+ H as sprintf,
414
+ D as toPosixPath,
415
+ N as wrapSynchronousInterfaceAsPromised
409
416
  };
410
417
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../packages/php-wasm/util/src/lib/sleep.ts","../../../../packages/php-wasm/util/src/lib/semaphore.ts","../../../../packages/php-wasm/util/src/lib/php-wasm-error.ts","../../../../packages/php-wasm/util/src/lib/paths.ts","../../../../packages/php-wasm/util/src/lib/event-emitter-polyfill.ts","../../../../packages/php-wasm/util/src/lib/split-shell-command.ts","../../../../packages/php-wasm/util/src/lib/writable-polyfill.ts","../../../../packages/php-wasm/util/src/lib/create-spawn-handler.ts","../../../../packages/php-wasm/util/src/lib/random-string.ts","../../../../packages/php-wasm/util/src/lib/random-filename.ts","../../../../packages/php-wasm/util/src/lib/php-vars.ts","../../../../packages/php-wasm/util/src/lib/sprintf.ts","../../../../packages/php-wasm/util/src/lib/promised.ts","../../../../packages/php-wasm/util/src/lib/index.ts"],"sourcesContent":["export const SleepFinished = Symbol('SleepFinished');\n\nexport function sleep(ms: number): Promise<typeof SleepFinished> {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(() => resolve(SleepFinished), ms);\n\t});\n}\n","import { SleepFinished, sleep } from './sleep';\n\nexport interface SemaphoreOptions {\n\t/**\n\t * The maximum number of concurrent locks.\n\t */\n\tconcurrency: number;\n\t/**\n\t * The maximum time to wait for a lock to become available.\n\t */\n\ttimeout?: number;\n}\n\nexport class AcquireTimeoutError extends Error {\n\tconstructor() {\n\t\tsuper('Acquiring lock timed out');\n\t}\n}\n\nexport default class Semaphore {\n\tprivate _running = 0;\n\tprivate concurrency: number;\n\tprivate timeout?: number;\n\tprivate queue: (() => void)[];\n\n\tconstructor({ concurrency, timeout }: SemaphoreOptions) {\n\t\tthis.concurrency = concurrency;\n\t\tthis.timeout = timeout;\n\t\tthis.queue = [];\n\t}\n\n\tget remaining(): number {\n\t\treturn this.concurrency - this.running;\n\t}\n\n\tget running(): number {\n\t\treturn this._running;\n\t}\n\n\tasync acquire(): Promise<() => void> {\n\t\twhile (true) {\n\t\t\tif (this._running >= this.concurrency) {\n\t\t\t\t// Concurrency exhausted – wait until a lock is released:\n\t\t\t\tconst acquired = new Promise<void>((resolve) => {\n\t\t\t\t\tthis.queue.push(resolve);\n\t\t\t\t});\n\t\t\t\tif (this.timeout !== undefined) {\n\t\t\t\t\tawait Promise.race([acquired, sleep(this.timeout)]).then(\n\t\t\t\t\t\t(value) => {\n\t\t\t\t\t\t\tif (value === SleepFinished) {\n\t\t\t\t\t\t\t\tthrow new AcquireTimeoutError();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tawait acquired;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Acquire the lock:\n\t\t\t\tthis._running++;\n\t\t\t\tlet released = false;\n\t\t\t\treturn () => {\n\t\t\t\t\tif (released) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\treleased = true;\n\t\t\t\t\tthis._running--;\n\t\t\t\t\t// Release the lock:\n\t\t\t\t\tif (this.queue.length > 0) {\n\t\t\t\t\t\tthis.queue.shift()!();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\tasync run<T>(fn: () => T | Promise<T>): Promise<T> {\n\t\tconst release = await this.acquire();\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} finally {\n\t\t\trelease();\n\t\t}\n\t}\n}\n","export class PhpWasmError extends Error {\n\tuserFriendlyMessage?: string;\n\tconstructor(message: string, userFriendlyMessage?: string) {\n\t\tsuper(message);\n\t\tthis.userFriendlyMessage = userFriendlyMessage ?? message;\n\t}\n}\n","/**\n * The functions in this module are mostly copied from the generated\n * Emscripten PHP module. This enables features like filesystem journaling,\n * which use some low-level Emscripten APIs and need access to the\n * same path helpers.\n */\n\n/**\n * Joins paths together.\n *\n * For example:\n *\n * > joinPaths('wordpress', 'wp-content')\n * 'wordpress/wp-content'\n *\n * Use this for all PHP paths and **do not** use path.join().\n * This is important because Emscripten paths are **always**\n * POSIX-style paths. Imagine joining paths on Windows:\n *\n * > path.join('wordpress', 'wp-content')\n * '\\\\wordpress\\\\wp-content' // invalid in PHP.wasm\n *\n * See the path.join issue for more details:\n *\n * https://github.com/WordPress/playground-tools/issues/11#issuecomment-1579074763\n *\n * @param paths Paths segments to join\n * @returns A joined path\n */\nexport function joinPaths(...paths: string[]) {\n\tfunction hasTrailingSlash(p: string) {\n\t\treturn p.substring(p.length - 1) === '/';\n\t}\n\n\tlet path = paths.join('/');\n\tconst isAbsolute = path[0] === '/';\n\tconst trailingSlash = hasTrailingSlash(path);\n\tpath = normalizePath(path);\n\tif (!path && !isAbsolute) {\n\t\tpath = '.';\n\t}\n\tif (path && trailingSlash && !hasTrailingSlash(path)) {\n\t\tpath += '/';\n\t}\n\treturn path;\n}\n\n/**\n * Returns the directory name of a path.\n *\n * @param path\n * @returns\n */\nexport function dirname(path: string) {\n\tif (path === '/') {\n\t\treturn '/';\n\t}\n\n\tpath = normalizePath(path);\n\n\tconst lastSlash = path.lastIndexOf('/');\n\tif (lastSlash === -1) {\n\t\treturn '';\n\t} else if (lastSlash === 0) {\n\t\treturn '/';\n\t}\n\treturn path.substr(0, lastSlash);\n}\n\n/**\n * Returns the last portion of a path.\n *\n * @param path - The path to extract the basename from.\n * @returns The basename of the path.\n */\nexport function basename(path: string) {\n\tif (path === '/') {\n\t\treturn '/';\n\t}\n\n\tpath = normalizePath(path);\n\n\tconst lastSlash = path.lastIndexOf('/');\n\tif (lastSlash === -1) {\n\t\treturn path;\n\t}\n\treturn path.substr(lastSlash + 1);\n}\n\n/**\n * Normalizes a path.\n *\n * For example:\n *\n * > normalizePath('wordpress/wp-content/../')\n * 'wordpress'\n *\n * @param path\n * @returns\n */\nexport function normalizePath(path: string) {\n\tconst isAbsolute = path[0] === '/';\n\tpath = normalizePathsArray(\n\t\tpath.split('/').filter((p: any) => !!p),\n\t\t!isAbsolute\n\t).join('/');\n\treturn (isAbsolute ? '/' : '') + path.replace(/\\/$/, '');\n}\n\n/**\n * Normalizes paths.\n *\n * For example:\n *\n * > normalizePathsArray(['wordpress', 'wp-content', '..', '', '.',\n * 'wp-includes']) ['wordpress', 'wp-includes']\n *\n * @param parts parts of the path to normalize\n * @param allowAboveRoot allow paths above the root\n * @returns normalized paths\n */\nexport function normalizePathsArray(parts: string[], allowAboveRoot: boolean) {\n\tlet up = 0;\n\tfor (let i = parts.length - 1; i >= 0; i--) {\n\t\tconst last = parts[i];\n\t\tif (last === '.') {\n\t\t\tparts.splice(i, 1);\n\t\t} else if (last === '..') {\n\t\t\tparts.splice(i, 1);\n\t\t\tup++;\n\t\t} else if (up) {\n\t\t\tparts.splice(i, 1);\n\t\t\tup--;\n\t\t}\n\t}\n\tif (allowAboveRoot) {\n\t\tfor (; up; up--) {\n\t\t\tparts.unshift('..');\n\t\t}\n\t}\n\treturn parts;\n}\n\n/**\n * Checks if the given parent path is an ancestor of the given child path.\n *\n * @param parent The parent path to check.\n * @param child The child path to verify against the parent.\n * @returns Whether the `parent` path is an ancestor of the `child` path.\n */\nexport function isParentOf(parent: string, child: string) {\n\tif (parent === '/') {\n\t\treturn true;\n\t}\n\tparent = normalizePath(parent);\n\tchild = normalizePath(child);\n\treturn child.startsWith(parent + '/') || child === parent;\n}\n\n/**\n * Guarantees a path is absolute by prepending `/` if needed.\n *\n * Useful when working with user-provided paths that might be relative,\n * or when you need to normalize edge cases like empty strings.\n *\n * For example:\n *\n * > ensureAbsolutePath('wp-content/uploads')\n * '/wp-content/uploads'\n *\n * > ensureAbsolutePath('/already/absolute')\n * '/already/absolute'\n *\n * > ensureAbsolutePath('')\n * '/'\n *\n * @param path - The path to make absolute.\n * @returns An absolute, normalized path starting with `/`.\n */\nexport function ensureAbsolutePath(path: string) {\n\treturn joinPaths('/', normalizePath(path || '/'));\n}\n","/**\n * Polyfills Node.js EventEmitter API. The main goal is to enable\n * using a child_process.spawn()-like API in both Node.js and the browser.\n *\n * @see https://nodejs.org/api/events.html#events_class_eventemitter\n */\ntype Listener = (...args: any[]) => any;\n\nexport class EventEmitterPolyfill {\n\tlisteners: Record<string, Listener[]> = {};\n\temit(eventName: string, data?: any) {\n\t\tif (this.listeners[eventName]) {\n\t\t\tthis.listeners[eventName].forEach(function (listener) {\n\t\t\t\tlistener(data);\n\t\t\t});\n\t\t}\n\t}\n\ton(eventName: string, listener: Listener) {\n\t\tif (!this.listeners[eventName]) {\n\t\t\tthis.listeners[eventName] = [];\n\t\t}\n\t\tthis.listeners[eventName].push(listener);\n\t}\n\tonce(eventName: string, listener: Listener) {\n\t\tconst wrappedListener = (...args: any[]) => {\n\t\t\tthis.off(eventName, wrappedListener);\n\t\t\tlistener(...args);\n\t\t};\n\t\tthis.on(eventName, wrappedListener);\n\t}\n\toff(eventName: string, listener: Listener) {\n\t\tif (this.listeners[eventName]) {\n\t\t\tthis.listeners[eventName] = this.listeners[eventName].filter(\n\t\t\t\t(l) => l !== listener\n\t\t\t);\n\t\t}\n\t}\n}\n","/**\n * Naive shell command parser.\n * Ensures that commands like `wp option set blogname \"My blog name\"` are split\n * into `['wp', 'option', 'set', 'blogname', 'My blog name']` instead of\n * `['wp', 'option', 'set', 'blogname', 'My', 'blog', 'name']`.\n *\n * @param command\n * @returns\n */\nexport function splitShellCommand(command: string) {\n\tconst MODE_UNQUOTED = 0;\n\tconst MODE_IN_QUOTE = 1;\n\n\tlet mode = MODE_UNQUOTED;\n\tlet quote = '';\n\n\tconst parts: string[] = [];\n\tlet currentPart = '';\n\tfor (let i = 0; i < command.length; i++) {\n\t\tconst char = command[i];\n\t\tif (char === '\\\\') {\n\t\t\t// Escaped quotes are treated as normal characters\n\t\t\t// This is a very naive approach to escaping, but it's good enough for\n\t\t\t// now. @TODO: Iterate on this later, perhaps using bun shell. @see https://github.com/WordPress/wordpress-playground/issues/1062\n\t\t\tif (command[i + 1] === '\"' || command[i + 1] === \"'\") {\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcurrentPart += command[i];\n\t\t} else if (mode === MODE_UNQUOTED) {\n\t\t\tif (char === '\"' || char === \"'\") {\n\t\t\t\tmode = MODE_IN_QUOTE;\n\t\t\t\tquote = char;\n\t\t\t} else if (char.match(/\\s/)) {\n\t\t\t\tif (currentPart.trim().length) {\n\t\t\t\t\tparts.push(currentPart.trim());\n\t\t\t\t}\n\t\t\t\tcurrentPart = char;\n\t\t\t} else if (parts.length && !currentPart) {\n\t\t\t\t// We just closed a quote to continue the same\n\t\t\t\t// argument with different escaping style, e.g.:\n\t\t\t\t// php -r 'require '\\''vendor/autoload.php'\\''\n\t\t\t\tcurrentPart = parts.pop()! + char;\n\t\t\t} else {\n\t\t\t\tcurrentPart += char;\n\t\t\t}\n\t\t} else if (mode === MODE_IN_QUOTE) {\n\t\t\tif (char === quote) {\n\t\t\t\tmode = MODE_UNQUOTED;\n\t\t\t\tquote = '';\n\t\t\t} else {\n\t\t\t\tcurrentPart += char;\n\t\t\t}\n\t\t}\n\t}\n\tif (currentPart) {\n\t\tparts.push(currentPart.trim());\n\t}\n\treturn parts;\n}\n","/**\n * Polyfills Node.js WritableStream API. The main goal is to enable\n * using a child_process.spawn()-like API in both Node.js and the browser.\n *\n * @see https://nodejs.org/api/stream.html#stream_writable_end_chunk_encoding_callback\n */\nimport { EventEmitterPolyfill } from './event-emitter-polyfill';\n\nexport interface WritableOptions {\n\thighWaterMark?: number;\n\tdecodeStrings?: boolean;\n\tdefaultEncoding?: BufferEncoding;\n\twrite: (chunk: any, encoding: BufferEncoding, cb: WriteCallback) => void;\n}\n\nexport type WriteCallback = (error?: Error | null) => void;\n\nexport class WritablePolyfill extends EventEmitterPolyfill {\n\tprivate buffer: Array<{\n\t\tchunk: any;\n\t\tencoding: BufferEncoding;\n\t\tcb: WriteCallback;\n\t}> = [];\n\tprivate writing = false;\n\tpublic ended = false;\n\tprivate length = 0;\n\tprivate highWaterMark: number;\n\tprivate decodeStrings: boolean;\n\tprivate defaultEncoding: BufferEncoding;\n\tprivate defer: (fn: () => void) => void;\n\tprivate _write: (\n\t\tchunk: any,\n\t\tencoding: BufferEncoding,\n\t\tcb: WriteCallback\n\t) => void;\n\n\tconstructor(opts: WritableOptions) {\n\t\tsuper();\n\t\tif (!opts.write) {\n\t\t\tthrow new Error('WritablePolyfill requires write option');\n\t\t}\n\t\tthis._write = opts.write;\n\t\tthis.highWaterMark = opts.highWaterMark ?? 16 * 1024;\n\t\tthis.decodeStrings = opts.decodeStrings ?? true;\n\t\tthis.defaultEncoding = opts.defaultEncoding ?? 'utf8';\n\t\t// queueMicrotask keeps browser support; fallback for older environments.\n\t\tthis.defer =\n\t\t\ttypeof queueMicrotask === 'function'\n\t\t\t\t? queueMicrotask\n\t\t\t\t: (fn) => setTimeout(fn, 0);\n\t}\n\n\twrite(\n\t\tchunk: any,\n\t\tencoding: BufferEncoding | WriteCallback = this.defaultEncoding,\n\t\tcb: WriteCallback = () => {}\n\t): boolean {\n\t\tif (typeof encoding === 'function') {\n\t\t\tcb = encoding as WriteCallback;\n\t\t\tencoding = this.defaultEncoding;\n\t\t}\n\n\t\tif (this.ended) {\n\t\t\tconst err = new Error('write after end');\n\t\t\t// We can't call this.defer() directly. If this.defer is\n\t\t\t// `queueMicrotask`, a `this.defer()` call will pass the\n\t\t\t// WritablePolyfill instance as `this` argument and cause\n\t\t\t// the browser to throw an error similar to \"Invalid\n\t\t\t// invocation\".\n\t\t\tconst defer = this.defer;\n\t\t\tdefer(() => cb(err));\n\t\t\tthis.emit('error', err);\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.decodeStrings && typeof chunk === 'string') {\n\t\t\tif (\n\t\t\t\ttypeof Buffer !== 'undefined' &&\n\t\t\t\ttypeof (Buffer as any).from === 'function'\n\t\t\t) {\n\t\t\t\tchunk = Buffer.from(chunk, encoding as BufferEncoding);\n\t\t\t} else if (typeof TextEncoder !== 'undefined') {\n\t\t\t\tchunk = new TextEncoder().encode(chunk);\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'String chunks are not supported in this environment: Buffer and TextEncoder are unavailable.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tencoding = 'buffer' as BufferEncoding;\n\t\t}\n\n\t\tthis.length += chunk.length ?? 1;\n\t\tconst needDrain = this.length >= this.highWaterMark;\n\n\t\tthis.buffer.push({ chunk, encoding: encoding as BufferEncoding, cb });\n\n\t\tif (!this.writing) this._clearBuffer();\n\n\t\treturn !needDrain;\n\t}\n\n\tend(\n\t\tchunk?: any,\n\t\tencoding?: BufferEncoding | WriteCallback,\n\t\tcb?: WriteCallback\n\t): void {\n\t\tif (typeof chunk === 'function') {\n\t\t\tcb = chunk;\n\t\t\tchunk = undefined;\n\t\t} else if (typeof encoding === 'function') {\n\t\t\tcb = encoding as WriteCallback;\n\t\t\tencoding = undefined;\n\t\t}\n\n\t\tif (chunk !== undefined)\n\t\t\tthis.write(chunk, encoding as BufferEncoding, () => {});\n\t\tthis.ended = true;\n\t\tif (!this.writing) this._clearBuffer();\n\t\tif (cb) this.defer(cb);\n\t}\n\n\t// Stubs kept for API parity; add logic if you depend on corking.\n\tcork(): void {}\n\tuncork(): void {}\n\n\tsetDefaultEncoding(enc: BufferEncoding): this {\n\t\tthis.defaultEncoding = enc;\n\t\treturn this;\n\t}\n\n\tprivate _clearBuffer(): void {\n\t\tconst entry = this.buffer.shift();\n\t\tif (!entry) {\n\t\t\tif (this.ended) this.emit('finish');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.writing = true;\n\t\tthis._write(entry.chunk, entry.encoding, (err?: Error | null) => {\n\t\t\tthis.writing = false;\n\t\t\tthis.length -= entry.chunk.length ?? 1;\n\t\t\tif (err) this.emit('error', err);\n\t\t\tentry.cb(err);\n\n\t\t\tif (this.buffer.length) {\n\t\t\t\tthis._clearBuffer();\n\t\t\t} else {\n\t\t\t\tif (this.length < this.highWaterMark) this.emit('drain');\n\t\t\t\tif (this.ended) this.emit('finish');\n\t\t\t}\n\t\t});\n\t}\n}\n","import { EventEmitterPolyfill } from './event-emitter-polyfill';\nimport { splitShellCommand } from './split-shell-command';\nimport { WritablePolyfill, type WriteCallback } from './writable-polyfill';\n\ntype Listener = (...args: any[]) => any;\n\nexport interface ProcessOptions {\n\tcwd?: string;\n\tenv?: Record<string, string>;\n}\n\n/**\n * Usage:\n * ```ts\n * php.setSpawnHandler(\n * createSpawnHandler(function (command, processApi) {\n * console.log(processApi.flushStdin());\n * processApi.stdout('/\\n/tmp\\n/home');\n *\t processApi.exit(0);\n * })\n * );\n * ```\n * @param program\n * @returns\n */\nexport function createSpawnHandler(\n\tprogram: (\n\t\tcommand: string[],\n\t\tprocessApi: ProcessApi,\n\t\toptions: ProcessOptions\n\t) => void | Promise<void>\n): any {\n\treturn function (\n\t\tcommand: string | string[],\n\t\targsArray: string[] = [],\n\t\toptions: ProcessOptions = {}\n\t) {\n\t\tconst childProcess = new ChildProcess();\n\t\tconst processApi = new ProcessApi(childProcess);\n\t\t// Give PHP a chance to register listeners\n\t\tsetTimeout(async () => {\n\t\t\tlet commandArray = [];\n\t\t\tif (argsArray.length) {\n\t\t\t\tcommandArray = [command as string, ...argsArray];\n\t\t\t} else if (typeof command === 'string') {\n\t\t\t\tcommandArray = splitShellCommand(command);\n\t\t\t} else if (Array.isArray(command)) {\n\t\t\t\tcommandArray = command;\n\t\t\t} else {\n\t\t\t\tthrow new Error('Invalid command ', command);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst promise = program(commandArray, processApi, options);\n\t\t\t\tif (\n\t\t\t\t\ttypeof promise !== 'object' ||\n\t\t\t\t\tpromise === null ||\n\t\t\t\t\t!('then' in promise)\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`The program callback passed to createSpawnHandler() did not return a promise. It indicates there's a bug in your code. ` +\n\t\t\t\t\t\t\t`The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() ` +\n\t\t\t\t\t\t\t`call. All the streams would be closed already. Make sure to put an \"await new Promise(resolve => setTimeout(resolve, 1))` +\n\t\t\t\t\t\t\t`before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`\n\t\t\t\t\t);\n\t\t\t\t} else if (processApi.exited) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`The program callback passed to createSpawnHandler() exited synchronously. It indicates there's a bug in your code. ` +\n\t\t\t\t\t\t\t`The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() ` +\n\t\t\t\t\t\t\t`call. All the streams would be closed already. Make sure to put an \"await new Promise(resolve => setTimeout(resolve, 1))` +\n\t\t\t\t\t\t\t`before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tchildProcess.emit('spawn', true);\n\t\t\t\tawait promise;\n\t\t\t} catch (e) {\n\t\t\t\tchildProcess.emit('error', e);\n\t\t\t\tif (\n\t\t\t\t\ttypeof e === 'object' &&\n\t\t\t\t\te !== null &&\n\t\t\t\t\t'message' in e &&\n\t\t\t\t\ttypeof e.message === 'string'\n\t\t\t\t) {\n\t\t\t\t\tprocessApi.stderr(e.message);\n\t\t\t\t}\n\t\t\t\tprocessApi.exit(1);\n\t\t\t}\n\t\t});\n\t\treturn childProcess;\n\t};\n}\n\nexport class ProcessApi extends EventEmitterPolyfill {\n\tpublic exited = false;\n\t/**\n\t * Keeps track of the data that was written to stdin before the\n\t * first listener was registered.\n\t */\n\tprivate stdinBuffer: Uint8Array[] | null = [];\n\tpublic childProcess: ChildProcess;\n\tconstructor(childProcess: ChildProcess) {\n\t\tsuper();\n\t\tthis.childProcess = childProcess;\n\t\tchildProcess.on('stdin', (data: Uint8Array) => {\n\t\t\tif (this.stdinBuffer) {\n\t\t\t\t// Need to clone the data buffer as it's reused by PHP\n\t\t\t\t// and the next data chunk will overwrite the previous one.\n\t\t\t\tthis.stdinBuffer.push(data.slice());\n\t\t\t} else {\n\t\t\t\tthis.emit('stdin', data);\n\t\t\t}\n\t\t});\n\t}\n\tstdinEnd() {\n\t\tif (!this.childProcess.stdin.ended) {\n\t\t\tthis.childProcess.stdin.end();\n\t\t}\n\t}\n\tstdout(data: string | ArrayBuffer) {\n\t\tthis.childProcess.stdout.write(data);\n\t}\n\tstdoutEnd() {\n\t\tif (!this.childProcess.stdout.ended) {\n\t\t\tthis.childProcess.stdout.end();\n\t\t}\n\t}\n\tstderr(data: string | ArrayBuffer) {\n\t\tthis.childProcess.stderr.write(data);\n\t}\n\tstderrEnd() {\n\t\tif (!this.childProcess.stderr.ended) {\n\t\t\tthis.childProcess.stderr.end();\n\t\t}\n\t}\n\tnotifySpawn() {\n\t\tthis.childProcess.emit('spawn', true);\n\t}\n\texit(code: number) {\n\t\tif (!this.exited) {\n\t\t\tthis.exited = true;\n\t\t\tthis.stdinEnd();\n\t\t\tthis.stdoutEnd();\n\t\t\tthis.stderrEnd();\n\t\t\tthis.childProcess.emit('exit', code);\n\t\t}\n\t}\n\toverride on(eventName: string, listener: Listener) {\n\t\tsuper.on(eventName, listener);\n\t\t/**\n\t\t * If it's the first stdin listener, flush all the data we've\n\t\t * buffered so far.\n\t\t */\n\t\tif (eventName === 'stdin' && this.stdinBuffer) {\n\t\t\tfor (let i = 0; i < this.stdinBuffer.length; i++) {\n\t\t\t\tthis.emit('stdin', this.stdinBuffer[i]);\n\t\t\t}\n\t\t\tthis.stdinBuffer = null;\n\t\t}\n\t}\n}\n\nlet lastPid = 9743;\nexport class ChildProcess extends EventEmitterPolyfill {\n\tstdout: WritablePolyfill;\n\tstderr: WritablePolyfill;\n\tstdin: WritablePolyfill;\n\tpid: number;\n\tconstructor(pid = lastPid++) {\n\t\tsuper();\n\t\tthis.pid = pid;\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this;\n\t\tthis.stdout = new WritablePolyfill({\n\t\t\twrite(data: any, encoding: BufferEncoding, cb: WriteCallback) {\n\t\t\t\tself.stdout.emit('data', data);\n\t\t\t\tcb();\n\t\t\t},\n\t\t});\n\t\tthis.stderr = new WritablePolyfill({\n\t\t\twrite: (data: any, encoding: BufferEncoding, cb: WriteCallback) => {\n\t\t\t\tself.stderr.emit('data', data);\n\t\t\t\tcb();\n\t\t\t},\n\t\t});\n\t\tthis.stdin = new WritablePolyfill({\n\t\t\twrite: (data: any, encoding: BufferEncoding, cb: WriteCallback) => {\n\t\t\t\tself.emit('stdin', data);\n\t\t\t\tcb();\n\t\t\t},\n\t\t});\n\t}\n}\n","export function randomString(\n\tlength = 36,\n\tspecialChars = '!@#$%^&*()_+=-[]/.,<>?'\n) {\n\tconst chars =\n\t\t'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' +\n\t\tspecialChars;\n\tlet result = '';\n\tfor (let i = length; i > 0; --i)\n\t\tresult += chars[Math.floor(Math.random() * chars.length)];\n\treturn result;\n}\n","import { randomString } from './random-string';\n\nexport function randomFilename() {\n\treturn randomString(36, '-_');\n}\n","export function phpVar(value: unknown): string {\n\treturn `json_decode(base64_decode('${stringToBase64(\n\t\tJSON.stringify(value)\n\t)}'), true)`;\n}\n\nexport function phpVars<T extends Record<string, unknown>>(\n\tvars: T\n): Record<keyof T, string> {\n\tconst result: Record<string, string> = {};\n\tfor (const key in vars) {\n\t\tresult[key] = phpVar(vars[key]);\n\t}\n\treturn result as Record<keyof T, string>;\n}\n\nfunction stringToBase64(str: string) {\n\treturn bytesToBase64(new TextEncoder().encode(str));\n}\n\nfunction bytesToBase64(bytes: Uint8Array) {\n\tconst binString = String.fromCodePoint(...bytes);\n\treturn btoa(binString);\n}\n","/**\n * Formats a string like sprintf().\n *\n * This function:\n * - Supports basic format specifiers: %s, %d, %f, %x, %%\n * - Supports bigint values\n *\n * The purpose of this function is for use in optional php-wasm tracing.\n * If we use printf-style formatting for trace messages, we let the trace\n * function decide whether to format and do not have to pay for formatting\n * unless tracing is enabled.\n */\nexport function sprintf(format: string, ...args: any[]): string {\n\tlet result = '';\n\tlet argIndex = 0;\n\n\tfor (let i = 0; i < format.length; i++) {\n\t\tif (format[i] === '%' && i + 1 < format.length) {\n\t\t\ti++;\n\t\t\tconst specifier = format[i];\n\n\t\t\tswitch (specifier) {\n\t\t\t\tcase 's': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tlet str;\n\t\t\t\t\tif (typeof arg === 'object') {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// If an object doesn't provide its own toString(),\n\t\t\t\t\t\t\t// try to represent it as JSON.\n\t\t\t\t\t\t\tstr = JSON.stringify(\n\t\t\t\t\t\t\t\targ,\n\t\t\t\t\t\t\t\t// Represent bigint values as strings in JSON.stringify().\n\t\t\t\t\t\t\t\t(key, value) => {\n\t\t\t\t\t\t\t\t\tif (typeof value === 'bigint') {\n\t\t\t\t\t\t\t\t\t\treturn `0x${value.toString(16)}`;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t2\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Ignore error and use default representation.\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = String(arg);\n\t\t\t\t\t}\n\n\t\t\t\t\tresult += str;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'd': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tif (typeof arg === 'bigint') {\n\t\t\t\t\t\tresult += arg.toString();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += Math.floor(Number(arg));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'f': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tif (typeof arg === 'bigint') {\n\t\t\t\t\t\tresult += Number(arg);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += Number(arg);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'x': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tif (typeof arg === 'bigint') {\n\t\t\t\t\t\tresult += arg.toString(16);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += Math.floor(Number(arg)).toString(16);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase '%': {\n\t\t\t\t\tresult += '%';\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tresult += '%' + specifier;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tresult += format[i];\n\t\t}\n\t}\n\n\treturn result;\n}\n","// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\ntype PromisedMethod<T extends (...args: any[]) => any> = (\n\t...args: Parameters<T>\n) => Promise<ReturnType<T>>;\n\nexport type Promised<T> = {\n\t[P in keyof T]: T[P] extends (...args: any[]) => any\n\t\t? PromisedMethod<T[P]>\n\t\t: T[P];\n};\n\n/**\n * Wraps a synchronous interface as a promised interface.\n *\n * This function tries to avoid wrapping methods inherited from\n * built-in JS object types (e.g., `Object`, `Array`, `Function`, etc.).\n *\n * The initial use case for this function is for unit testing\n * file locking in php-wasm. Php-wasm for JSPI expects the file lock manager\n * to be a promised interface used via comlink,\n * but the interface itself is synchronous.\n *\n * @param obj\n * @returns A promised interface that wraps the synchronous interface.\n */\nexport function wrapSynchronousInterfaceAsPromised<T extends object>(\n\tobj: T\n): Promised<T> {\n\tconst keysAlreadySeen = new Set<string | symbol>();\n\tconst keysToMakePromised = new Set<string | symbol>();\n\tconst looksLikeBuiltInObject =\n\t\t// NOTE: We don't generally add custom things to the global scope,\n\t\t// so let's use this as a heuristic to determine if an object is a built-in object type.\n\t\t(obj: object) =>\n\t\t\t(globalThis as any)[obj.constructor.name] !== obj.constructor;\n\n\tlet proto: object = obj;\n\twhile (proto !== null && !looksLikeBuiltInObject(proto)) {\n\t\tconst allKeys = [\n\t\t\t...Object.getOwnPropertyNames(proto),\n\t\t\t...Object.getOwnPropertySymbols(proto),\n\t\t];\n\t\tfor (const key of allKeys) {\n\t\t\tif (\n\t\t\t\t// Track keys already seen so an inherited method property\n\t\t\t\t// masked by a descendant property of the same name is not considered.\n\t\t\t\t!keysAlreadySeen.has(key) &&\n\t\t\t\t!keysToMakePromised.has(key) &&\n\t\t\t\ttypeof (proto as any)[key] === 'function'\n\t\t\t) {\n\t\t\t\tkeysToMakePromised.add(key);\n\t\t\t}\n\t\t\tkeysAlreadySeen.add(key);\n\t\t}\n\t\tproto = Object.getPrototypeOf(proto);\n\t}\n\n\t// NOTE: We could use Proxy here instead,\n\t// but providing a regular object is ultimately simpler.\n\tconst promisifiedObj = Object.create(obj);\n\tfor (const key of keysToMakePromised) {\n\t\tpromisifiedObj[key] = function (...args: any[]) {\n\t\t\treturn Promise.resolve((obj as any)[key](...args));\n\t\t};\n\t}\n\treturn promisifiedObj;\n}\n","import Semaphore, { AcquireTimeoutError } from './semaphore';\nexport { Semaphore, AcquireTimeoutError };\nexport { PhpWasmError } from './php-wasm-error';\nexport type { SemaphoreOptions } from './semaphore';\nexport {\n\tdirname,\n\tjoinPaths,\n\tbasename,\n\tnormalizePath,\n\tisParentOf,\n\tensureAbsolutePath,\n} from './paths';\nexport { createSpawnHandler } from './create-spawn-handler';\nexport { randomString } from './random-string';\nexport { randomFilename } from './random-filename';\nexport { splitShellCommand } from './split-shell-command';\nexport { WritablePolyfill, type WritableOptions } from './writable-polyfill';\nexport { EventEmitterPolyfill } from './event-emitter-polyfill';\nexport * from './php-vars';\n\nexport * from './sprintf';\n\nexport function concatUint8Arrays(arrays: Uint8Array[]): Uint8Array {\n\tlet totalLength = 0;\n\tarrays.forEach((a) => (totalLength += a.length));\n\tconst result = new Uint8Array(totalLength);\n\tlet offset = 0;\n\tarrays.forEach((a) => {\n\t\tresult.set(a, offset);\n\t\toffset += a.length;\n\t});\n\treturn result;\n}\n\nexport function concatArrayBuffers(buffers: ArrayBuffer[]): ArrayBuffer {\n\treturn concatUint8Arrays(buffers.map((b) => new Uint8Array(b)))\n\t\t.buffer as ArrayBuffer;\n}\n\nexport * from './promised';\n"],"names":["SleepFinished","sleep","ms","resolve","AcquireTimeoutError","Semaphore","concurrency","timeout","acquired","value","released","fn","release","PhpWasmError","message","userFriendlyMessage","joinPaths","paths","hasTrailingSlash","p","path","isAbsolute","trailingSlash","normalizePath","dirname","lastSlash","basename","normalizePathsArray","parts","allowAboveRoot","up","i","last","isParentOf","parent","child","ensureAbsolutePath","EventEmitterPolyfill","eventName","data","listener","wrappedListener","args","l","splitShellCommand","command","mode","quote","currentPart","char","WritablePolyfill","opts","chunk","encoding","cb","err","defer","needDrain","enc","entry","createSpawnHandler","program","argsArray","options","childProcess","ChildProcess","processApi","ProcessApi","commandArray","promise","e","code","lastPid","pid","self","randomString","length","specialChars","chars","result","randomFilename","phpVar","stringToBase64","phpVars","vars","key","str","bytesToBase64","bytes","binString","sprintf","format","argIndex","specifier","arg","wrapSynchronousInterfaceAsPromised","obj","keysAlreadySeen","keysToMakePromised","looksLikeBuiltInObject","proto","allKeys","promisifiedObj","concatUint8Arrays","arrays","totalLength","a","offset","concatArrayBuffers","buffers","b"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../packages/php-wasm/util/src/lib/sleep.ts","../../../../packages/php-wasm/util/src/lib/semaphore.ts","../../../../packages/php-wasm/util/src/lib/php-wasm-error.ts","../../../../packages/php-wasm/util/src/lib/paths.ts","../../../../packages/php-wasm/util/src/lib/event-emitter-polyfill.ts","../../../../packages/php-wasm/util/src/lib/split-shell-command.ts","../../../../packages/php-wasm/util/src/lib/writable-polyfill.ts","../../../../packages/php-wasm/util/src/lib/create-spawn-handler.ts","../../../../packages/php-wasm/util/src/lib/random-string.ts","../../../../packages/php-wasm/util/src/lib/random-filename.ts","../../../../packages/php-wasm/util/src/lib/php-vars.ts","../../../../packages/php-wasm/util/src/lib/sprintf.ts","../../../../packages/php-wasm/util/src/lib/promised.ts","../../../../packages/php-wasm/util/src/lib/index.ts"],"sourcesContent":["export const SleepFinished = Symbol('SleepFinished');\n\nexport function sleep(ms: number): Promise<typeof SleepFinished> {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(() => resolve(SleepFinished), ms);\n\t});\n}\n","import { SleepFinished, sleep } from './sleep';\n\nexport interface SemaphoreOptions {\n\t/**\n\t * The maximum number of concurrent locks.\n\t */\n\tconcurrency: number;\n\t/**\n\t * The maximum time to wait for a lock to become available.\n\t */\n\ttimeout?: number;\n}\n\nexport class AcquireTimeoutError extends Error {\n\tconstructor() {\n\t\tsuper('Acquiring lock timed out');\n\t}\n}\n\nexport default class Semaphore {\n\tprivate _running = 0;\n\tprivate concurrency: number;\n\tprivate timeout?: number;\n\tprivate queue: (() => void)[];\n\n\tconstructor({ concurrency, timeout }: SemaphoreOptions) {\n\t\tthis.concurrency = concurrency;\n\t\tthis.timeout = timeout;\n\t\tthis.queue = [];\n\t}\n\n\tget remaining(): number {\n\t\treturn this.concurrency - this.running;\n\t}\n\n\tget running(): number {\n\t\treturn this._running;\n\t}\n\n\tasync acquire(): Promise<() => void> {\n\t\t// Concurrency exhausted - wait in queue for other workers to finish:\n\t\tif (this._running >= this.concurrency) {\n\t\t\t// Create a promise and store its resolver in the queue.\n\t\t\tconst acquired = new Promise<void>((resolve) => {\n\t\t\t\tthis.queue.push(resolve);\n\t\t\t});\n\n\t\t\t// Wait until it is resolved by another worker or a timeout occurs.\n\t\t\tif (this.timeout !== undefined) {\n\t\t\t\t// Store the resolver for cleanup in case of timeout.\n\t\t\t\tconst resolve = this.queue.at(-1)!;\n\t\t\t\tconst result = await Promise.race([\n\t\t\t\t\tacquired,\n\t\t\t\t\tsleep(this.timeout),\n\t\t\t\t]);\n\t\t\t\tif (result === SleepFinished) {\n\t\t\t\t\t// Remove the resolver for the timed out worker from the queue.\n\t\t\t\t\tthis.queue.splice(this.queue.indexOf(resolve), 1);\n\t\t\t\t\tthrow new AcquireTimeoutError();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tawait acquired;\n\t\t\t}\n\t\t}\n\n\t\t// Acquire the lock:\n\t\tthis._running++;\n\t\tlet released = false;\n\n\t\t// Return a release function:\n\t\treturn () => {\n\t\t\tif (released) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treleased = true;\n\t\t\tthis._running--;\n\n\t\t\t// Release the first item in the queue (call its resolver):\n\t\t\tif (this.queue.length > 0) {\n\t\t\t\tthis.queue.shift()!();\n\t\t\t}\n\t\t};\n\t}\n\n\tasync run<T>(fn: () => T | Promise<T>): Promise<T> {\n\t\tconst release = await this.acquire();\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} finally {\n\t\t\trelease();\n\t\t}\n\t}\n}\n","export class PhpWasmError extends Error {\n\tuserFriendlyMessage?: string;\n\tconstructor(message: string, userFriendlyMessage?: string) {\n\t\tsuper(message);\n\t\tthis.userFriendlyMessage = userFriendlyMessage ?? message;\n\t}\n}\n","/**\n * The functions in this module are mostly copied from the generated\n * Emscripten PHP module. This enables features like filesystem journaling,\n * which use some low-level Emscripten APIs and need access to the\n * same path helpers.\n */\n\n/**\n * Joins paths together.\n *\n * For example:\n *\n * > joinPaths('wordpress', 'wp-content')\n * 'wordpress/wp-content'\n *\n * Use this for all PHP paths and **do not** use path.join().\n * This is important because Emscripten paths are **always**\n * POSIX-style paths. Imagine joining paths on Windows:\n *\n * > path.join('wordpress', 'wp-content')\n * '\\\\wordpress\\\\wp-content' // invalid in PHP.wasm\n *\n * See the path.join issue for more details:\n *\n * https://github.com/WordPress/playground-tools/issues/11#issuecomment-1579074763\n *\n * @param paths Paths segments to join\n * @returns A joined path\n */\nexport function joinPaths(...paths: string[]) {\n\tfunction hasTrailingSlash(p: string) {\n\t\treturn p.substring(p.length - 1) === '/';\n\t}\n\n\tlet path = paths.join('/');\n\tconst isAbsolute = path[0] === '/';\n\tconst trailingSlash = hasTrailingSlash(path);\n\tpath = normalizePath(path);\n\tif (!path && !isAbsolute) {\n\t\tpath = '.';\n\t}\n\tif (path && trailingSlash && !hasTrailingSlash(path)) {\n\t\tpath += '/';\n\t}\n\treturn path;\n}\n\n/**\n * Returns the directory name of a path.\n *\n * @param path\n * @returns\n */\nexport function dirname(path: string) {\n\tif (path === '/') {\n\t\treturn '/';\n\t}\n\n\tpath = normalizePath(path);\n\n\tconst lastSlash = path.lastIndexOf('/');\n\tif (lastSlash === -1) {\n\t\treturn '';\n\t} else if (lastSlash === 0) {\n\t\treturn '/';\n\t}\n\treturn path.substr(0, lastSlash);\n}\n\n/**\n * Returns the last portion of a path.\n *\n * @param path - The path to extract the basename from.\n * @returns The basename of the path.\n */\nexport function basename(path: string) {\n\tif (path === '/') {\n\t\treturn '/';\n\t}\n\n\tpath = normalizePath(path);\n\n\tconst lastSlash = path.lastIndexOf('/');\n\tif (lastSlash === -1) {\n\t\treturn path;\n\t}\n\treturn path.substr(lastSlash + 1);\n}\n\n/**\n * Normalizes a path.\n *\n * For example:\n *\n * > normalizePath('wordpress/wp-content/../')\n * 'wordpress'\n *\n * @param path\n * @returns\n */\nexport function normalizePath(path: string) {\n\tconst isAbsolute = path[0] === '/';\n\tpath = normalizePathsArray(\n\t\tpath.split('/').filter((p: any) => !!p),\n\t\t!isAbsolute\n\t).join('/');\n\treturn (isAbsolute ? '/' : '') + path.replace(/\\/$/, '');\n}\n\n/**\n * Normalizes paths.\n *\n * For example:\n *\n * > normalizePathsArray(['wordpress', 'wp-content', '..', '', '.',\n * 'wp-includes']) ['wordpress', 'wp-includes']\n *\n * @param parts parts of the path to normalize\n * @param allowAboveRoot allow paths above the root\n * @returns normalized paths\n */\nexport function normalizePathsArray(parts: string[], allowAboveRoot: boolean) {\n\tlet up = 0;\n\tfor (let i = parts.length - 1; i >= 0; i--) {\n\t\tconst last = parts[i];\n\t\tif (last === '.') {\n\t\t\tparts.splice(i, 1);\n\t\t} else if (last === '..') {\n\t\t\tparts.splice(i, 1);\n\t\t\tup++;\n\t\t} else if (up) {\n\t\t\tparts.splice(i, 1);\n\t\t\tup--;\n\t\t}\n\t}\n\tif (allowAboveRoot) {\n\t\tfor (; up; up--) {\n\t\t\tparts.unshift('..');\n\t\t}\n\t}\n\treturn parts;\n}\n\n/**\n * Checks if the given parent path is an ancestor of the given child path.\n *\n * @param parent The parent path to check.\n * @param child The child path to verify against the parent.\n * @returns Whether the `parent` path is an ancestor of the `child` path.\n */\nexport function isParentOf(parent: string, child: string) {\n\tif (parent === '/') {\n\t\treturn true;\n\t}\n\tparent = normalizePath(parent);\n\tchild = normalizePath(child);\n\treturn child.startsWith(parent + '/') || child === parent;\n}\n\n/**\n * Guarantees a path is absolute by prepending `/` if needed.\n *\n * Useful when working with user-provided paths that might be relative,\n * or when you need to normalize edge cases like empty strings.\n *\n * For example:\n *\n * > ensureAbsolutePath('wp-content/uploads')\n * '/wp-content/uploads'\n *\n * > ensureAbsolutePath('/already/absolute')\n * '/already/absolute'\n *\n * > ensureAbsolutePath('')\n * '/'\n *\n * @param path - The path to make absolute.\n * @returns An absolute, normalized path starting with `/`.\n */\nexport function ensureAbsolutePath(path: string) {\n\treturn joinPaths('/', normalizePath(path || '/'));\n}\n\n/**\n * Converts a native OS path to a POSIX-style path.\n *\n * Transformations:\n * 1. Backslashes → forward slashes\n * 2. Windows drive letter `C:\\` → `/C/` (colons are invalid in\n * Emscripten VFS paths and cause ENOTDIR errno 28)\n *\n * On POSIX systems this is effectively a no-op.\n *\n * @see https://github.com/emscripten-core/emscripten/issues/17829\n */\nexport function toPosixPath(nativePath: string): string {\n\tlet result = nativePath.replaceAll('\\\\', '/');\n\t// Handle Windows drive letter: C:/ → /C/\n\tconst driveMatch = result.match(/^([A-Za-z]):\\//);\n\tif (driveMatch) {\n\t\tresult = '/' + driveMatch[1] + result.slice(2);\n\t}\n\treturn result;\n}\n","/**\n * Polyfills Node.js EventEmitter API. The main goal is to enable\n * using a child_process.spawn()-like API in both Node.js and the browser.\n *\n * @see https://nodejs.org/api/events.html#events_class_eventemitter\n */\ntype Listener = (...args: any[]) => any;\n\nexport class EventEmitterPolyfill {\n\tlisteners: Record<string, Listener[]> = {};\n\temit(eventName: string, data?: any) {\n\t\tif (this.listeners[eventName]) {\n\t\t\tthis.listeners[eventName].forEach(function (listener) {\n\t\t\t\tlistener(data);\n\t\t\t});\n\t\t}\n\t}\n\ton(eventName: string, listener: Listener) {\n\t\tif (!this.listeners[eventName]) {\n\t\t\tthis.listeners[eventName] = [];\n\t\t}\n\t\tthis.listeners[eventName].push(listener);\n\t}\n\tonce(eventName: string, listener: Listener) {\n\t\tconst wrappedListener = (...args: any[]) => {\n\t\t\tthis.off(eventName, wrappedListener);\n\t\t\tlistener(...args);\n\t\t};\n\t\tthis.on(eventName, wrappedListener);\n\t}\n\toff(eventName: string, listener: Listener) {\n\t\tif (this.listeners[eventName]) {\n\t\t\tthis.listeners[eventName] = this.listeners[eventName].filter(\n\t\t\t\t(l) => l !== listener\n\t\t\t);\n\t\t}\n\t}\n}\n","/**\n * Naive shell command parser.\n * Ensures that commands like `wp option set blogname \"My blog name\"` are split\n * into `['wp', 'option', 'set', 'blogname', 'My blog name']` instead of\n * `['wp', 'option', 'set', 'blogname', 'My', 'blog', 'name']`.\n *\n * @param command\n * @returns\n */\nexport function splitShellCommand(command: string) {\n\tconst MODE_UNQUOTED = 0;\n\tconst MODE_IN_QUOTE = 1;\n\n\tlet mode = MODE_UNQUOTED;\n\tlet quote = '';\n\n\tconst parts: string[] = [];\n\tlet currentPart = '';\n\tfor (let i = 0; i < command.length; i++) {\n\t\tconst char = command[i];\n\t\tif (char === '\\\\') {\n\t\t\t// Escaped quotes are treated as normal characters\n\t\t\t// This is a very naive approach to escaping, but it's good enough for\n\t\t\t// now. @TODO: Iterate on this later, perhaps using bun shell. @see https://github.com/WordPress/wordpress-playground/issues/1062\n\t\t\tif (command[i + 1] === '\"' || command[i + 1] === \"'\") {\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcurrentPart += command[i];\n\t\t} else if (mode === MODE_UNQUOTED) {\n\t\t\tif (char === '\"' || char === \"'\") {\n\t\t\t\tmode = MODE_IN_QUOTE;\n\t\t\t\tquote = char;\n\t\t\t} else if (char.match(/\\s/)) {\n\t\t\t\tif (currentPart.trim().length) {\n\t\t\t\t\tparts.push(currentPart.trim());\n\t\t\t\t}\n\t\t\t\tcurrentPart = char;\n\t\t\t} else if (parts.length && !currentPart) {\n\t\t\t\t// We just closed a quote to continue the same\n\t\t\t\t// argument with different escaping style, e.g.:\n\t\t\t\t// php -r 'require '\\''vendor/autoload.php'\\''\n\t\t\t\tcurrentPart = parts.pop()! + char;\n\t\t\t} else {\n\t\t\t\tcurrentPart += char;\n\t\t\t}\n\t\t} else if (mode === MODE_IN_QUOTE) {\n\t\t\tif (char === quote) {\n\t\t\t\tmode = MODE_UNQUOTED;\n\t\t\t\tquote = '';\n\t\t\t} else {\n\t\t\t\tcurrentPart += char;\n\t\t\t}\n\t\t}\n\t}\n\tif (currentPart) {\n\t\tparts.push(currentPart.trim());\n\t}\n\treturn parts;\n}\n","/**\n * Polyfills Node.js WritableStream API. The main goal is to enable\n * using a child_process.spawn()-like API in both Node.js and the browser.\n *\n * @see https://nodejs.org/api/stream.html#stream_writable_end_chunk_encoding_callback\n */\nimport { EventEmitterPolyfill } from './event-emitter-polyfill';\n\nexport interface WritableOptions {\n\thighWaterMark?: number;\n\tdecodeStrings?: boolean;\n\tdefaultEncoding?: BufferEncoding;\n\twrite: (chunk: any, encoding: BufferEncoding, cb: WriteCallback) => void;\n}\n\nexport type WriteCallback = (error?: Error | null) => void;\n\nexport class WritablePolyfill extends EventEmitterPolyfill {\n\tprivate buffer: Array<{\n\t\tchunk: any;\n\t\tencoding: BufferEncoding;\n\t\tcb: WriteCallback;\n\t}> = [];\n\tprivate writing = false;\n\tpublic ended = false;\n\tprivate length = 0;\n\tprivate highWaterMark: number;\n\tprivate decodeStrings: boolean;\n\tprivate defaultEncoding: BufferEncoding;\n\tprivate defer: (fn: () => void) => void;\n\tprivate _write: (\n\t\tchunk: any,\n\t\tencoding: BufferEncoding,\n\t\tcb: WriteCallback\n\t) => void;\n\n\tconstructor(opts: WritableOptions) {\n\t\tsuper();\n\t\tif (!opts.write) {\n\t\t\tthrow new Error('WritablePolyfill requires write option');\n\t\t}\n\t\tthis._write = opts.write;\n\t\tthis.highWaterMark = opts.highWaterMark ?? 16 * 1024;\n\t\tthis.decodeStrings = opts.decodeStrings ?? true;\n\t\tthis.defaultEncoding = opts.defaultEncoding ?? 'utf8';\n\t\t// queueMicrotask keeps browser support; fallback for older environments.\n\t\tthis.defer =\n\t\t\ttypeof queueMicrotask === 'function'\n\t\t\t\t? queueMicrotask\n\t\t\t\t: (fn) => setTimeout(fn, 0);\n\t}\n\n\twrite(\n\t\tchunk: any,\n\t\tencoding: BufferEncoding | WriteCallback = this.defaultEncoding,\n\t\tcb: WriteCallback = () => {}\n\t): boolean {\n\t\tif (typeof encoding === 'function') {\n\t\t\tcb = encoding as WriteCallback;\n\t\t\tencoding = this.defaultEncoding;\n\t\t}\n\n\t\tif (this.ended) {\n\t\t\tconst err = new Error('write after end');\n\t\t\t// We can't call this.defer() directly. If this.defer is\n\t\t\t// `queueMicrotask`, a `this.defer()` call will pass the\n\t\t\t// WritablePolyfill instance as `this` argument and cause\n\t\t\t// the browser to throw an error similar to \"Invalid\n\t\t\t// invocation\".\n\t\t\tconst defer = this.defer;\n\t\t\tdefer(() => cb(err));\n\t\t\tthis.emit('error', err);\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.decodeStrings && typeof chunk === 'string') {\n\t\t\tif (\n\t\t\t\ttypeof Buffer !== 'undefined' &&\n\t\t\t\ttypeof (Buffer as any).from === 'function'\n\t\t\t) {\n\t\t\t\tchunk = Buffer.from(chunk, encoding as BufferEncoding);\n\t\t\t} else if (typeof TextEncoder !== 'undefined') {\n\t\t\t\tchunk = new TextEncoder().encode(chunk);\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'String chunks are not supported in this environment: Buffer and TextEncoder are unavailable.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tencoding = 'buffer' as BufferEncoding;\n\t\t}\n\n\t\tthis.length += chunk.length ?? 1;\n\t\tconst needDrain = this.length >= this.highWaterMark;\n\n\t\tthis.buffer.push({ chunk, encoding: encoding as BufferEncoding, cb });\n\n\t\tif (!this.writing) this._clearBuffer();\n\n\t\treturn !needDrain;\n\t}\n\n\tend(\n\t\tchunk?: any,\n\t\tencoding?: BufferEncoding | WriteCallback,\n\t\tcb?: WriteCallback\n\t): void {\n\t\tif (typeof chunk === 'function') {\n\t\t\tcb = chunk;\n\t\t\tchunk = undefined;\n\t\t} else if (typeof encoding === 'function') {\n\t\t\tcb = encoding as WriteCallback;\n\t\t\tencoding = undefined;\n\t\t}\n\n\t\tif (chunk !== undefined)\n\t\t\tthis.write(chunk, encoding as BufferEncoding, () => {});\n\t\tthis.ended = true;\n\t\tif (!this.writing) this._clearBuffer();\n\t\tif (cb) this.defer(cb);\n\t}\n\n\t// Stubs kept for API parity; add logic if you depend on corking.\n\tcork(): void {}\n\tuncork(): void {}\n\n\tsetDefaultEncoding(enc: BufferEncoding): this {\n\t\tthis.defaultEncoding = enc;\n\t\treturn this;\n\t}\n\n\tprivate _clearBuffer(): void {\n\t\tconst entry = this.buffer.shift();\n\t\tif (!entry) {\n\t\t\tif (this.ended) this.emit('finish');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.writing = true;\n\t\tthis._write(entry.chunk, entry.encoding, (err?: Error | null) => {\n\t\t\tthis.writing = false;\n\t\t\tthis.length -= entry.chunk.length ?? 1;\n\t\t\tif (err) this.emit('error', err);\n\t\t\tentry.cb(err);\n\n\t\t\tif (this.buffer.length) {\n\t\t\t\tthis._clearBuffer();\n\t\t\t} else {\n\t\t\t\tif (this.length < this.highWaterMark) this.emit('drain');\n\t\t\t\tif (this.ended) this.emit('finish');\n\t\t\t}\n\t\t});\n\t}\n}\n","import { EventEmitterPolyfill } from './event-emitter-polyfill';\nimport { splitShellCommand } from './split-shell-command';\nimport { WritablePolyfill, type WriteCallback } from './writable-polyfill';\n\ntype Listener = (...args: any[]) => any;\n\nexport interface ProcessOptions {\n\tcwd?: string;\n\tenv?: Record<string, string>;\n}\n\n/**\n * Usage:\n * ```ts\n * php.setSpawnHandler(\n * createSpawnHandler(function (command, processApi) {\n * console.log(processApi.flushStdin());\n * processApi.stdout('/\\n/tmp\\n/home');\n *\t processApi.exit(0);\n * })\n * );\n * ```\n * @param program\n * @returns\n */\nexport function createSpawnHandler(\n\tprogram: (\n\t\tcommand: string[],\n\t\tprocessApi: ProcessApi,\n\t\toptions: ProcessOptions\n\t) => void | Promise<void>\n): any {\n\treturn function (\n\t\tcommand: string | string[],\n\t\targsArray: string[] = [],\n\t\toptions: ProcessOptions = {}\n\t) {\n\t\tconst childProcess = new ChildProcess();\n\t\tconst processApi = new ProcessApi(childProcess);\n\t\t// Give PHP a chance to register listeners\n\t\tsetTimeout(async () => {\n\t\t\tlet commandArray = [];\n\t\t\tif (argsArray.length) {\n\t\t\t\tcommandArray = [command as string, ...argsArray];\n\t\t\t} else if (typeof command === 'string') {\n\t\t\t\tcommandArray = splitShellCommand(command);\n\t\t\t} else if (Array.isArray(command)) {\n\t\t\t\tcommandArray = command;\n\t\t\t} else {\n\t\t\t\tthrow new Error('Invalid command ', command);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst promise = program(commandArray, processApi, options);\n\t\t\t\tif (\n\t\t\t\t\ttypeof promise !== 'object' ||\n\t\t\t\t\tpromise === null ||\n\t\t\t\t\t!('then' in promise)\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`The program callback passed to createSpawnHandler() did not return a promise. It indicates there's a bug in your code. ` +\n\t\t\t\t\t\t\t`The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() ` +\n\t\t\t\t\t\t\t`call. All the streams would be closed already. Make sure to put an \"await new Promise(resolve => setTimeout(resolve, 1))` +\n\t\t\t\t\t\t\t`before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`\n\t\t\t\t\t);\n\t\t\t\t} else if (processApi.exited) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`The program callback passed to createSpawnHandler() exited synchronously. It indicates there's a bug in your code. ` +\n\t\t\t\t\t\t\t`The callback must return a promise. PHP cannot interact with program that synchronously exists at the end of the proc_open() ` +\n\t\t\t\t\t\t\t`call. All the streams would be closed already. Make sure to put an \"await new Promise(resolve => setTimeout(resolve, 1))` +\n\t\t\t\t\t\t\t`before calling processApi.exit(0) in your callback to let PHP catch up with the stdout data.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tchildProcess.emit('spawn', true);\n\t\t\t\tawait promise;\n\t\t\t} catch (e) {\n\t\t\t\tchildProcess.emit('error', e);\n\t\t\t\tif (\n\t\t\t\t\ttypeof e === 'object' &&\n\t\t\t\t\te !== null &&\n\t\t\t\t\t'message' in e &&\n\t\t\t\t\ttypeof e.message === 'string'\n\t\t\t\t) {\n\t\t\t\t\tprocessApi.stderr(e.message);\n\t\t\t\t}\n\t\t\t\tprocessApi.exit(1);\n\t\t\t}\n\t\t});\n\t\treturn childProcess;\n\t};\n}\n\nexport class ProcessApi extends EventEmitterPolyfill {\n\tpublic exited = false;\n\t/**\n\t * Keeps track of the data that was written to stdin before the\n\t * first listener was registered.\n\t */\n\tprivate stdinBuffer: Uint8Array[] | null = [];\n\tpublic childProcess: ChildProcess;\n\tconstructor(childProcess: ChildProcess) {\n\t\tsuper();\n\t\tthis.childProcess = childProcess;\n\t\tchildProcess.on('stdin', (data: Uint8Array) => {\n\t\t\tif (this.stdinBuffer) {\n\t\t\t\t// Need to clone the data buffer as it's reused by PHP\n\t\t\t\t// and the next data chunk will overwrite the previous one.\n\t\t\t\tthis.stdinBuffer.push(data.slice());\n\t\t\t} else {\n\t\t\t\tthis.emit('stdin', data);\n\t\t\t}\n\t\t});\n\t}\n\tstdinEnd() {\n\t\tif (!this.childProcess.stdin.ended) {\n\t\t\tthis.childProcess.stdin.end();\n\t\t}\n\t}\n\tstdout(data: string | ArrayBuffer) {\n\t\tthis.childProcess.stdout.write(data);\n\t}\n\tstdoutEnd() {\n\t\tif (!this.childProcess.stdout.ended) {\n\t\t\tthis.childProcess.stdout.end();\n\t\t}\n\t}\n\tstderr(data: string | ArrayBuffer) {\n\t\tthis.childProcess.stderr.write(data);\n\t}\n\tstderrEnd() {\n\t\tif (!this.childProcess.stderr.ended) {\n\t\t\tthis.childProcess.stderr.end();\n\t\t}\n\t}\n\tnotifySpawn() {\n\t\tthis.childProcess.emit('spawn', true);\n\t}\n\texit(code: number) {\n\t\tif (!this.exited) {\n\t\t\tthis.exited = true;\n\t\t\tthis.stdinEnd();\n\t\t\tthis.stdoutEnd();\n\t\t\tthis.stderrEnd();\n\t\t\tthis.childProcess.emit('exit', code);\n\t\t}\n\t}\n\toverride on(eventName: string, listener: Listener) {\n\t\tsuper.on(eventName, listener);\n\t\t/**\n\t\t * If it's the first stdin listener, flush all the data we've\n\t\t * buffered so far.\n\t\t */\n\t\tif (eventName === 'stdin' && this.stdinBuffer) {\n\t\t\tfor (let i = 0; i < this.stdinBuffer.length; i++) {\n\t\t\t\tthis.emit('stdin', this.stdinBuffer[i]);\n\t\t\t}\n\t\t\tthis.stdinBuffer = null;\n\t\t}\n\t}\n}\n\nlet lastPid = 9743;\nexport class ChildProcess extends EventEmitterPolyfill {\n\tstdout: WritablePolyfill;\n\tstderr: WritablePolyfill;\n\tstdin: WritablePolyfill;\n\tpid: number;\n\tconstructor(pid = lastPid++) {\n\t\tsuper();\n\t\tthis.pid = pid;\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this;\n\t\tthis.stdout = new WritablePolyfill({\n\t\t\twrite(data: any, encoding: BufferEncoding, cb: WriteCallback) {\n\t\t\t\tself.stdout.emit('data', data);\n\t\t\t\tcb();\n\t\t\t},\n\t\t});\n\t\tthis.stderr = new WritablePolyfill({\n\t\t\twrite: (data: any, encoding: BufferEncoding, cb: WriteCallback) => {\n\t\t\t\tself.stderr.emit('data', data);\n\t\t\t\tcb();\n\t\t\t},\n\t\t});\n\t\tthis.stdin = new WritablePolyfill({\n\t\t\twrite: (data: any, encoding: BufferEncoding, cb: WriteCallback) => {\n\t\t\t\tself.emit('stdin', data);\n\t\t\t\tcb();\n\t\t\t},\n\t\t});\n\t}\n}\n","export function randomString(\n\tlength = 36,\n\tspecialChars = '!@#$%^&*()_+=-[]/.,<>?'\n) {\n\tconst chars =\n\t\t'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' +\n\t\tspecialChars;\n\tlet result = '';\n\tfor (let i = length; i > 0; --i)\n\t\tresult += chars[Math.floor(Math.random() * chars.length)];\n\treturn result;\n}\n","import { randomString } from './random-string';\n\nexport function randomFilename() {\n\treturn randomString(36, '-_');\n}\n","export function phpVar(value: unknown): string {\n\treturn `json_decode(base64_decode('${stringToBase64(\n\t\tJSON.stringify(value)\n\t)}'), true)`;\n}\n\nexport function phpVars<T extends Record<string, unknown>>(\n\tvars: T\n): Record<keyof T, string> {\n\tconst result: Record<string, string> = {};\n\tfor (const key in vars) {\n\t\tresult[key] = phpVar(vars[key]);\n\t}\n\treturn result as Record<keyof T, string>;\n}\n\nfunction stringToBase64(str: string) {\n\treturn bytesToBase64(new TextEncoder().encode(str));\n}\n\nfunction bytesToBase64(bytes: Uint8Array) {\n\tconst binString = String.fromCodePoint(...bytes);\n\treturn btoa(binString);\n}\n","/**\n * Formats a string like sprintf().\n *\n * This function:\n * - Supports basic format specifiers: %s, %d, %f, %x, %%\n * - Supports bigint values\n *\n * The purpose of this function is for use in optional php-wasm tracing.\n * If we use printf-style formatting for trace messages, we let the trace\n * function decide whether to format and do not have to pay for formatting\n * unless tracing is enabled.\n */\nexport function sprintf(format: string, ...args: any[]): string {\n\tlet result = '';\n\tlet argIndex = 0;\n\n\tfor (let i = 0; i < format.length; i++) {\n\t\tif (format[i] === '%' && i + 1 < format.length) {\n\t\t\ti++;\n\t\t\tconst specifier = format[i];\n\n\t\t\tswitch (specifier) {\n\t\t\t\tcase 's': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tlet str;\n\t\t\t\t\tif (typeof arg === 'object') {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// If an object doesn't provide its own toString(),\n\t\t\t\t\t\t\t// try to represent it as JSON.\n\t\t\t\t\t\t\tstr = JSON.stringify(\n\t\t\t\t\t\t\t\targ,\n\t\t\t\t\t\t\t\t// Represent bigint values as strings in JSON.stringify().\n\t\t\t\t\t\t\t\t(key, value) => {\n\t\t\t\t\t\t\t\t\tif (typeof value === 'bigint') {\n\t\t\t\t\t\t\t\t\t\treturn `0x${value.toString(16)}`;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t2\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Ignore error and use default representation.\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = String(arg);\n\t\t\t\t\t}\n\n\t\t\t\t\tresult += str;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'd': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tif (typeof arg === 'bigint') {\n\t\t\t\t\t\tresult += arg.toString();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += Math.floor(Number(arg));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'f': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tif (typeof arg === 'bigint') {\n\t\t\t\t\t\tresult += Number(arg);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += Number(arg);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'x': {\n\t\t\t\t\tconst arg = args[argIndex++];\n\t\t\t\t\tif (typeof arg === 'bigint') {\n\t\t\t\t\t\tresult += arg.toString(16);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult += Math.floor(Number(arg)).toString(16);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase '%': {\n\t\t\t\t\tresult += '%';\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tresult += '%' + specifier;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tresult += format[i];\n\t\t}\n\t}\n\n\treturn result;\n}\n","// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\ntype PromisedMethod<T extends (...args: any[]) => any> = (\n\t...args: Parameters<T>\n) => Promise<ReturnType<T>>;\n\nexport type Promised<T> = {\n\t[P in keyof T]: T[P] extends (...args: any[]) => any\n\t\t? PromisedMethod<T[P]>\n\t\t: T[P];\n};\n\n/**\n * Wraps a synchronous interface as a promised interface.\n *\n * This function tries to avoid wrapping methods inherited from\n * built-in JS object types (e.g., `Object`, `Array`, `Function`, etc.).\n *\n * The initial use case for this function is for unit testing\n * file locking in php-wasm. Php-wasm for JSPI expects the file lock manager\n * to be a promised interface used via comlink,\n * but the interface itself is synchronous.\n *\n * @param obj\n * @returns A promised interface that wraps the synchronous interface.\n */\nexport function wrapSynchronousInterfaceAsPromised<T extends object>(\n\tobj: T\n): Promised<T> {\n\tconst keysAlreadySeen = new Set<string | symbol>();\n\tconst keysToMakePromised = new Set<string | symbol>();\n\tconst looksLikeBuiltInObject =\n\t\t// NOTE: We don't generally add custom things to the global scope,\n\t\t// so let's use this as a heuristic to determine if an object is a built-in object type.\n\t\t(obj: object) =>\n\t\t\t(globalThis as any)[obj.constructor.name] !== obj.constructor;\n\n\tlet proto: object = obj;\n\twhile (proto !== null && !looksLikeBuiltInObject(proto)) {\n\t\tconst allKeys = [\n\t\t\t...Object.getOwnPropertyNames(proto),\n\t\t\t...Object.getOwnPropertySymbols(proto),\n\t\t];\n\t\tfor (const key of allKeys) {\n\t\t\tif (\n\t\t\t\t// Track keys already seen so an inherited method property\n\t\t\t\t// masked by a descendant property of the same name is not considered.\n\t\t\t\t!keysAlreadySeen.has(key) &&\n\t\t\t\t!keysToMakePromised.has(key) &&\n\t\t\t\ttypeof (proto as any)[key] === 'function'\n\t\t\t) {\n\t\t\t\tkeysToMakePromised.add(key);\n\t\t\t}\n\t\t\tkeysAlreadySeen.add(key);\n\t\t}\n\t\tproto = Object.getPrototypeOf(proto);\n\t}\n\n\t// NOTE: We could use Proxy here instead,\n\t// but providing a regular object is ultimately simpler.\n\tconst promisifiedObj = Object.create(obj);\n\tfor (const key of keysToMakePromised) {\n\t\tpromisifiedObj[key] = function (...args: any[]) {\n\t\t\treturn Promise.resolve((obj as any)[key](...args));\n\t\t};\n\t}\n\treturn promisifiedObj;\n}\n","import Semaphore, { AcquireTimeoutError } from './semaphore';\nexport { Semaphore, AcquireTimeoutError };\nexport { PhpWasmError } from './php-wasm-error';\nexport type { SemaphoreOptions } from './semaphore';\nexport {\n\tdirname,\n\tjoinPaths,\n\tbasename,\n\tnormalizePath,\n\tisParentOf,\n\tensureAbsolutePath,\n\ttoPosixPath,\n} from './paths';\nexport { createSpawnHandler } from './create-spawn-handler';\nexport { randomString } from './random-string';\nexport { randomFilename } from './random-filename';\nexport { splitShellCommand } from './split-shell-command';\nexport { WritablePolyfill, type WritableOptions } from './writable-polyfill';\nexport { EventEmitterPolyfill } from './event-emitter-polyfill';\nexport * from './php-vars';\n\nexport * from './sprintf';\n\nexport function concatUint8Arrays(arrays: Uint8Array[]): Uint8Array {\n\tlet totalLength = 0;\n\tarrays.forEach((a) => (totalLength += a.length));\n\tconst result = new Uint8Array(totalLength);\n\tlet offset = 0;\n\tarrays.forEach((a) => {\n\t\tresult.set(a, offset);\n\t\toffset += a.length;\n\t});\n\treturn result;\n}\n\nexport function concatArrayBuffers(buffers: ArrayBuffer[]): ArrayBuffer {\n\treturn concatUint8Arrays(buffers.map((b) => new Uint8Array(b)))\n\t\t.buffer as ArrayBuffer;\n}\n\nexport * from './promised';\n"],"names":["SleepFinished","sleep","ms","resolve","AcquireTimeoutError","Semaphore","concurrency","timeout","acquired","released","fn","release","PhpWasmError","message","userFriendlyMessage","joinPaths","paths","hasTrailingSlash","p","path","isAbsolute","trailingSlash","normalizePath","dirname","lastSlash","basename","normalizePathsArray","parts","allowAboveRoot","up","i","last","isParentOf","parent","child","ensureAbsolutePath","toPosixPath","nativePath","result","driveMatch","EventEmitterPolyfill","eventName","data","listener","wrappedListener","args","l","splitShellCommand","command","mode","quote","currentPart","char","WritablePolyfill","opts","chunk","encoding","cb","err","defer","needDrain","enc","entry","createSpawnHandler","program","argsArray","options","childProcess","ChildProcess","processApi","ProcessApi","commandArray","promise","e","code","lastPid","pid","self","randomString","length","specialChars","chars","randomFilename","phpVar","value","stringToBase64","phpVars","vars","key","str","bytesToBase64","bytes","binString","sprintf","format","argIndex","specifier","arg","wrapSynchronousInterfaceAsPromised","obj","keysAlreadySeen","keysToMakePromised","looksLikeBuiltInObject","proto","allKeys","promisifiedObj","concatUint8Arrays","arrays","totalLength","a","offset","concatArrayBuffers","buffers","b"],"mappings":"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"}
package/lib/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import Semaphore, { AcquireTimeoutError } from './semaphore';
2
2
  export { Semaphore, AcquireTimeoutError };
3
3
  export { PhpWasmError } from './php-wasm-error';
4
4
  export type { SemaphoreOptions } from './semaphore';
5
- export { dirname, joinPaths, basename, normalizePath, isParentOf, ensureAbsolutePath, } from './paths';
5
+ export { dirname, joinPaths, basename, normalizePath, isParentOf, ensureAbsolutePath, toPosixPath, } from './paths';
6
6
  export { createSpawnHandler } from './create-spawn-handler';
7
7
  export { randomString } from './random-string';
8
8
  export { randomFilename } from './random-filename';
package/lib/paths.d.ts CHANGED
@@ -95,3 +95,16 @@ export declare function isParentOf(parent: string, child: string): boolean;
95
95
  * @returns An absolute, normalized path starting with `/`.
96
96
  */
97
97
  export declare function ensureAbsolutePath(path: string): string;
98
+ /**
99
+ * Converts a native OS path to a POSIX-style path.
100
+ *
101
+ * Transformations:
102
+ * 1. Backslashes → forward slashes
103
+ * 2. Windows drive letter `C:\` → `/C/` (colons are invalid in
104
+ * Emscripten VFS paths and cause ENOTDIR errno 28)
105
+ *
106
+ * On POSIX systems this is effectively a no-op.
107
+ *
108
+ * @see https://github.com/emscripten-core/emscripten/issues/17829
109
+ */
110
+ export declare function toPosixPath(nativePath: string): string;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/WordPress/wordpress-playground"
6
6
  },
7
- "version": "3.0.46",
7
+ "version": "3.0.51",
8
8
  "type": "module",
9
9
  "types": "index.d.ts",
10
10
  "typedoc": {
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "main": "./index.cjs",
29
29
  "module": "./index.js",
30
- "gitHead": "845cbc01dba047db8bf0b4ae2670b924e3517087",
30
+ "gitHead": "ebc05da827807f3311ed1de8711fa74266183fab",
31
31
  "engines": {
32
32
  "node": ">=20.18.3",
33
33
  "npm": ">=10.1.0"
@@ -41,7 +41,9 @@
41
41
  "@playwright/test": "1.55.1",
42
42
  "ws": "8.18.3",
43
43
  "tmp": "0.2.5",
44
- "form-data": "^4.0.4"
44
+ "form-data": "^4.0.4",
45
+ "lodash": "^4.17.23",
46
+ "glob": "^9.3.0"
45
47
  },
46
48
  "dependencies": {},
47
49
  "optionalDependencies": {