@php-wasm/util 1.1.3 → 1.1.4
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 +1 -1
- package/index.cjs.map +1 -1
- package/index.js +147 -95
- package/index.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/sprintf.d.ts +13 -0
- package/package.json +2 -2
package/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=Symbol("SleepFinished");function p(e){return new Promise(t=>{setTimeout(()=>t(a),e)})}class d extends Error{constructor(){super("Acquiring lock timed out")}}class E{constructor({concurrency:t,timeout:i}){this._running=0,this.concurrency=t,this.timeout=i,this.queue=[]}get remaining(){return this.concurrency-this.running}get running(){return this._running}async acquire(){for(;;)if(this._running>=this.concurrency){const t=new Promise(i=>{this.queue.push(i)});this.timeout!==void 0?await Promise.race([t,p(this.timeout)]).then(i=>{if(i===a)throw new d}):await t}else{this._running++;let t=!1;return()=>{t||(t=!0,this._running--,this.queue.length>0&&this.queue.shift()())}}}async run(t){const i=await this.acquire();try{return await t()}finally{i()}}}class b extends Error{constructor(t,i){super(t),this.userFriendlyMessage=i??t}}function w(...e){function t(u){return u.substring(u.length-1)==="/"}let i=e.join("/");const s=i[0]==="/",n=t(i);return i=l(i),!i&&!s&&(i="."),i&&n&&!t(i)&&(i+="/"),i}function S(e){if(e==="/")return"/";e=l(e);const t=e.lastIndexOf("/");return t===-1?"":t===0?"/":e.substr(0,t)}function P(e){if(e==="/")return"/";e=l(e);const t=e.lastIndexOf("/");return t===-1?e:e.substr(t+1)}function l(e){const t=e[0]==="/";return e=O(e.split("/").filter(i=>!!i),!t).join("/"),(t?"/":"")+e.replace(/\/$/,"")}function O(e,t){let i=0;for(let s=e.length-1;s>=0;s--){const n=e[s];n==="."?e.splice(s,1):n===".."?(e.splice(s,1),i++):i&&(e.splice(s,1),i--)}if(t)for(;i;i--)e.unshift("..");return e}function x(e,t){return e==="/"?!0:(e=l(e),t=l(t),t.startsWith(e+"/")||t===e)}function D(e){let s=0,n="";const u=[];let r="";for(let o=0;o<e.length;o++){const c=e[o];c==="\\"?((e[o+1]==='"'||e[o+1]==="'")&&o++,r+=e[o]):s===0?c==='"'||c==="'"?(s=1,n=c):c.match(/\s/)?(r.trim().length&&u.push(r.trim()),r=c):u.length&&!r?r=u.pop()+c:r+=c:s===1&&(c===n?(s=0,n=""):r+=c)}return r&&u.push(r.trim()),u}function T(e){return function(t,i=[],s={}){const n=new U,u=new _(n);return setTimeout(async()=>{let r=[];if(i.length)r=[t,...i];else if(typeof t=="string")r=D(t);else if(Array.isArray(t))r=t;else throw new Error("Invalid command ",t);try{await e(r,u,s)}catch(o){n.emit("error",o),typeof o=="object"&&o!==null&&"message"in o&&typeof o.message=="string"&&u.stderr(o.message),u.exit(1)}n.emit("spawn",!0)}),n}}class f{constructor(){this.listeners={}}emit(t,i){this.listeners[t]&&this.listeners[t].forEach(function(s){s(i)})}on(t,i){this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push(i)}}class _ extends f{constructor(t){super(),this.exited=!1,this.stdinData=[],this.childProcess=t,t.on("stdin",i=>{this.stdinData?this.stdinData.push(i.slice()):this.emit("stdin",i)})}stdout(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stdout.emit("data",t)}stdoutEnd(){this.childProcess.stdout.emit("end",{})}stderr(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stderr.emit("data",t)}stderrEnd(){this.childProcess.stderr.emit("end",{})}notifySpawn(){this.childProcess.emit("spawn",!0)}exit(t){this.exited||(this.exited=!0,this.childProcess.emit("exit",t))}flushStdin(){if(this.stdinData)for(let t=0;t<this.stdinData.length;t++)this.emit("stdin",this.stdinData[t]);this.stdinData=null}}let A=9743;class U extends f{constructor(t=A++){super(),this.stdout=new f,this.stderr=new f;const i=this;this.pid=t,this.stdin={write:s=>{i.emit("stdin",s)}}}}function g(e=36,t="!@#$%^&*()_+=-[]/.,<>?"){const i="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"+t;let s="";for(let n=e;n>0;--n)s+=i[Math.floor(Math.random()*i.length)];return s}function M(){return g(36,"-_")}function m(e){return`json_decode(base64_decode('${N(JSON.stringify(e))}'), true)`}function q(e){const t={};for(const i in e)t[i]=m(e[i]);return t}function N(e){return j(new TextEncoder().encode(e))}function j(e){const t=String.fromCodePoint(...e);return btoa(t)}function k(e,...t){let i="",s=0;for(let n=0;n<e.length;n++)if(e[n]==="%"&&n+1<e.length){n++;const u=e[n];switch(u){case"s":{const r=t[s++];let o;if(typeof r=="object")try{o=JSON.stringify(r,(c,h)=>typeof h=="bigint"?`0x${h.toString(16)}`:h,2)}catch{}else o=String(r);i+=o;break}case"d":{const r=t[s++];typeof r=="bigint"?i+=r.toString():i+=Math.floor(Number(r));break}case"f":{const r=t[s++];i+=Number(r);break}case"x":{const r=t[s++];typeof r=="bigint"?i+=r.toString(16):i+=Math.floor(Number(r)).toString(16);break}case"%":{i+="%";break}default:i+="%"+u}}else i+=e[n];return i}function y(e){let t=0;e.forEach(n=>t+=n.length);const i=new Uint8Array(t);let s=0;return e.forEach(n=>{i.set(n,s),s+=n.length}),i}function I(e){return y(e.map(t=>new Uint8Array(t))).buffer}exports.AcquireTimeoutError=d;exports.PhpWasmError=b;exports.Semaphore=E;exports.basename=P;exports.concatArrayBuffers=I;exports.concatUint8Arrays=y;exports.createSpawnHandler=T;exports.dirname=S;exports.isParentOf=x;exports.joinPaths=w;exports.normalizePath=l;exports.phpVar=m;exports.phpVars=q;exports.randomFilename=M;exports.randomString=g;exports.sprintf=k;
|
|
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/split-shell-command.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/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 * 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","import { splitShellCommand } from './split-shell-command';\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\tawait program(commandArray, processApi, options);\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\tchildProcess.emit('spawn', true);\n\t\t});\n\t\treturn childProcess;\n\t};\n}\n\nclass EventEmitter {\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}\n\nexport class ProcessApi extends EventEmitter {\n\tprivate exited = false;\n\tprivate stdinData: Uint8Array[] | null = [];\n\tprivate 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.stdinData) {\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.stdinData.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\tstdout(data: string | ArrayBuffer) {\n\t\tif (typeof data === 'string') {\n\t\t\tdata = new TextEncoder().encode(data);\n\t\t}\n\t\tthis.childProcess.stdout.emit('data', data);\n\t}\n\tstdoutEnd() {\n\t\tthis.childProcess.stdout.emit('end', {});\n\t}\n\tstderr(data: string | ArrayBuffer) {\n\t\tif (typeof data === 'string') {\n\t\t\tdata = new TextEncoder().encode(data);\n\t\t}\n\t\tthis.childProcess.stderr.emit('data', data);\n\t}\n\tstderrEnd() {\n\t\tthis.childProcess.stderr.emit('end', {});\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.childProcess.emit('exit', code);\n\t\t}\n\t}\n\tflushStdin() {\n\t\tif (this.stdinData) {\n\t\t\tfor (let i = 0; i < this.stdinData.length; i++) {\n\t\t\t\tthis.emit('stdin', this.stdinData[i]);\n\t\t\t}\n\t\t}\n\t\tthis.stdinData = null;\n\t}\n}\n\nexport type StdIn = {\n\twrite: (data: string) => void;\n};\n\nlet lastPid = 9743;\nexport class ChildProcess extends EventEmitter {\n\tstdout: EventEmitter = new EventEmitter();\n\tstderr: EventEmitter = new EventEmitter();\n\tstdin: StdIn;\n\tpid: number;\n\tconstructor(pid = lastPid++) {\n\t\tsuper();\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this;\n\t\tthis.pid = pid;\n\t\tthis.stdin = {\n\t\t\twrite: (data: string) => {\n\t\t\t\tself.emit('stdin', data);\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","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} from './paths';\nexport { createSpawnHandler } from './create-spawn-handler';\nexport { randomString } from './random-string';\nexport { randomFilename } from './random-filename';\n\nexport * from './php-vars';\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))).buffer;\n}\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","splitShellCommand","command","mode","quote","currentPart","char","createSpawnHandler","program","argsArray","options","childProcess","ChildProcess","processApi","ProcessApi","commandArray","e","EventEmitter","eventName","data","listener","code","lastPid","pid","self","randomString","length","specialChars","chars","result","randomFilename","phpVar","stringToBase64","phpVars","vars","key","str","bytesToBase64","bytes","binString","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/split-shell-command.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/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 * 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","import { splitShellCommand } from './split-shell-command';\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\tawait program(commandArray, processApi, options);\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\tchildProcess.emit('spawn', true);\n\t\t});\n\t\treturn childProcess;\n\t};\n}\n\nclass EventEmitter {\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}\n\nexport class ProcessApi extends EventEmitter {\n\tprivate exited = false;\n\tprivate stdinData: Uint8Array[] | null = [];\n\tprivate 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.stdinData) {\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.stdinData.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\tstdout(data: string | ArrayBuffer) {\n\t\tif (typeof data === 'string') {\n\t\t\tdata = new TextEncoder().encode(data);\n\t\t}\n\t\tthis.childProcess.stdout.emit('data', data);\n\t}\n\tstdoutEnd() {\n\t\tthis.childProcess.stdout.emit('end', {});\n\t}\n\tstderr(data: string | ArrayBuffer) {\n\t\tif (typeof data === 'string') {\n\t\t\tdata = new TextEncoder().encode(data);\n\t\t}\n\t\tthis.childProcess.stderr.emit('data', data);\n\t}\n\tstderrEnd() {\n\t\tthis.childProcess.stderr.emit('end', {});\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.childProcess.emit('exit', code);\n\t\t}\n\t}\n\tflushStdin() {\n\t\tif (this.stdinData) {\n\t\t\tfor (let i = 0; i < this.stdinData.length; i++) {\n\t\t\t\tthis.emit('stdin', this.stdinData[i]);\n\t\t\t}\n\t\t}\n\t\tthis.stdinData = null;\n\t}\n}\n\nexport type StdIn = {\n\twrite: (data: string) => void;\n};\n\nlet lastPid = 9743;\nexport class ChildProcess extends EventEmitter {\n\tstdout: EventEmitter = new EventEmitter();\n\tstderr: EventEmitter = new EventEmitter();\n\tstdin: StdIn;\n\tpid: number;\n\tconstructor(pid = lastPid++) {\n\t\tsuper();\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this;\n\t\tthis.pid = pid;\n\t\tthis.stdin = {\n\t\t\twrite: (data: string) => {\n\t\t\t\tself.emit('stdin', data);\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","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} from './paths';\nexport { createSpawnHandler } from './create-spawn-handler';\nexport { randomString } from './random-string';\nexport { randomFilename } from './random-filename';\n\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))).buffer;\n}\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","splitShellCommand","command","mode","quote","currentPart","char","createSpawnHandler","program","argsArray","options","childProcess","ChildProcess","processApi","ProcessApi","commandArray","e","EventEmitter","eventName","data","listener","code","lastPid","pid","self","randomString","length","specialChars","chars","result","randomFilename","phpVar","stringToBase64","phpVars","vars","key","str","bytesToBase64","bytes","binString","sprintf","format","args","argIndex","specifier","arg","concatUint8Arrays","arrays","totalLength","a","offset","concatArrayBuffers","buffers","b"],"mappings":"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"}
|
package/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
const
|
|
2
|
-
function
|
|
1
|
+
const a = Symbol("SleepFinished");
|
|
2
|
+
function d(e) {
|
|
3
3
|
return new Promise((t) => {
|
|
4
|
-
setTimeout(() => t(
|
|
4
|
+
setTimeout(() => t(a), e);
|
|
5
5
|
});
|
|
6
6
|
}
|
|
7
|
-
class
|
|
7
|
+
class g extends Error {
|
|
8
8
|
constructor() {
|
|
9
9
|
super("Acquiring lock timed out");
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
class
|
|
13
|
-
constructor({ concurrency: t, timeout:
|
|
14
|
-
this._running = 0, this.concurrency = t, this.timeout =
|
|
12
|
+
class D {
|
|
13
|
+
constructor({ concurrency: t, timeout: i }) {
|
|
14
|
+
this._running = 0, this.concurrency = t, this.timeout = i, this.queue = [];
|
|
15
15
|
}
|
|
16
16
|
get remaining() {
|
|
17
17
|
return this.concurrency - this.running;
|
|
@@ -22,13 +22,13 @@ class x {
|
|
|
22
22
|
async acquire() {
|
|
23
23
|
for (; ; )
|
|
24
24
|
if (this._running >= this.concurrency) {
|
|
25
|
-
const t = new Promise((
|
|
26
|
-
this.queue.push(
|
|
25
|
+
const t = new Promise((i) => {
|
|
26
|
+
this.queue.push(i);
|
|
27
27
|
});
|
|
28
|
-
this.timeout !== void 0 ? await Promise.race([t,
|
|
29
|
-
(
|
|
30
|
-
if (
|
|
31
|
-
throw new
|
|
28
|
+
this.timeout !== void 0 ? await Promise.race([t, d(this.timeout)]).then(
|
|
29
|
+
(i) => {
|
|
30
|
+
if (i === a)
|
|
31
|
+
throw new g();
|
|
32
32
|
}
|
|
33
33
|
) : await t;
|
|
34
34
|
} else {
|
|
@@ -40,26 +40,26 @@ class x {
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
async run(t) {
|
|
43
|
-
const
|
|
43
|
+
const i = await this.acquire();
|
|
44
44
|
try {
|
|
45
45
|
return await t();
|
|
46
46
|
} finally {
|
|
47
|
-
|
|
47
|
+
i();
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
class
|
|
52
|
-
constructor(t,
|
|
53
|
-
super(t), this.userFriendlyMessage =
|
|
51
|
+
class _ extends Error {
|
|
52
|
+
constructor(t, i) {
|
|
53
|
+
super(t), this.userFriendlyMessage = i ?? t;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
function T(...e) {
|
|
57
57
|
function t(u) {
|
|
58
58
|
return u.substring(u.length - 1) === "/";
|
|
59
59
|
}
|
|
60
|
-
let
|
|
61
|
-
const
|
|
62
|
-
return
|
|
60
|
+
let i = e.join("/");
|
|
61
|
+
const n = i[0] === "/", r = t(i);
|
|
62
|
+
return i = l(i), !i && !n && (i = "."), i && r && !t(i) && (i += "/"), i;
|
|
63
63
|
}
|
|
64
64
|
function U(e) {
|
|
65
65
|
if (e === "/")
|
|
@@ -68,7 +68,7 @@ function U(e) {
|
|
|
68
68
|
const t = e.lastIndexOf("/");
|
|
69
69
|
return t === -1 ? "" : t === 0 ? "/" : e.substr(0, t);
|
|
70
70
|
}
|
|
71
|
-
function
|
|
71
|
+
function A(e) {
|
|
72
72
|
if (e === "/")
|
|
73
73
|
return "/";
|
|
74
74
|
e = l(e);
|
|
@@ -77,74 +77,74 @@ function b(e) {
|
|
|
77
77
|
}
|
|
78
78
|
function l(e) {
|
|
79
79
|
const t = e[0] === "/";
|
|
80
|
-
return e =
|
|
81
|
-
e.split("/").filter((
|
|
80
|
+
return e = y(
|
|
81
|
+
e.split("/").filter((i) => !!i),
|
|
82
82
|
!t
|
|
83
83
|
).join("/"), (t ? "/" : "") + e.replace(/\/$/, "");
|
|
84
84
|
}
|
|
85
|
-
function
|
|
86
|
-
let
|
|
87
|
-
for (let
|
|
88
|
-
const
|
|
89
|
-
|
|
85
|
+
function y(e, t) {
|
|
86
|
+
let i = 0;
|
|
87
|
+
for (let n = e.length - 1; n >= 0; n--) {
|
|
88
|
+
const r = e[n];
|
|
89
|
+
r === "." ? e.splice(n, 1) : r === ".." ? (e.splice(n, 1), i++) : i && (e.splice(n, 1), i--);
|
|
90
90
|
}
|
|
91
91
|
if (t)
|
|
92
|
-
for (;
|
|
92
|
+
for (; i; i--)
|
|
93
93
|
e.unshift("..");
|
|
94
94
|
return e;
|
|
95
95
|
}
|
|
96
|
-
function
|
|
96
|
+
function M(e, t) {
|
|
97
97
|
return e === "/" ? !0 : (e = l(e), t = l(t), t.startsWith(e + "/") || t === e);
|
|
98
98
|
}
|
|
99
99
|
function m(e) {
|
|
100
|
-
let
|
|
100
|
+
let n = 0, r = "";
|
|
101
101
|
const u = [];
|
|
102
|
-
let
|
|
102
|
+
let s = "";
|
|
103
103
|
for (let o = 0; o < e.length; o++) {
|
|
104
104
|
const c = e[o];
|
|
105
|
-
c === "\\" ? ((e[o + 1] === '"' || e[o + 1] === "'") && o++,
|
|
105
|
+
c === "\\" ? ((e[o + 1] === '"' || e[o + 1] === "'") && o++, s += e[o]) : n === 0 ? c === '"' || c === "'" ? (n = 1, r = c) : c.match(/\s/) ? (s.trim().length && u.push(s.trim()), s = c) : u.length && !s ? s = u.pop() + c : s += c : n === 1 && (c === r ? (n = 0, r = "") : s += c);
|
|
106
106
|
}
|
|
107
|
-
return
|
|
107
|
+
return s && u.push(s.trim()), u;
|
|
108
108
|
}
|
|
109
109
|
function q(e) {
|
|
110
|
-
return function(t,
|
|
111
|
-
const
|
|
110
|
+
return function(t, i = [], n = {}) {
|
|
111
|
+
const r = new b(), u = new E(r);
|
|
112
112
|
return setTimeout(async () => {
|
|
113
|
-
let
|
|
114
|
-
if (
|
|
115
|
-
|
|
113
|
+
let s = [];
|
|
114
|
+
if (i.length)
|
|
115
|
+
s = [t, ...i];
|
|
116
116
|
else if (typeof t == "string")
|
|
117
|
-
|
|
117
|
+
s = m(t);
|
|
118
118
|
else if (Array.isArray(t))
|
|
119
|
-
|
|
119
|
+
s = t;
|
|
120
120
|
else
|
|
121
121
|
throw new Error("Invalid command ", t);
|
|
122
122
|
try {
|
|
123
|
-
await e(
|
|
123
|
+
await e(s, u, n);
|
|
124
124
|
} catch (o) {
|
|
125
|
-
|
|
125
|
+
r.emit("error", o), typeof o == "object" && o !== null && "message" in o && typeof o.message == "string" && u.stderr(o.message), u.exit(1);
|
|
126
126
|
}
|
|
127
|
-
|
|
128
|
-
}),
|
|
127
|
+
r.emit("spawn", !0);
|
|
128
|
+
}), r;
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
131
|
class f {
|
|
132
132
|
constructor() {
|
|
133
133
|
this.listeners = {};
|
|
134
134
|
}
|
|
135
|
-
emit(t,
|
|
136
|
-
this.listeners[t] && this.listeners[t].forEach(function(
|
|
137
|
-
i
|
|
135
|
+
emit(t, i) {
|
|
136
|
+
this.listeners[t] && this.listeners[t].forEach(function(n) {
|
|
137
|
+
n(i);
|
|
138
138
|
});
|
|
139
139
|
}
|
|
140
|
-
on(t,
|
|
141
|
-
this.listeners[t] || (this.listeners[t] = []), this.listeners[t].push(
|
|
140
|
+
on(t, i) {
|
|
141
|
+
this.listeners[t] || (this.listeners[t] = []), this.listeners[t].push(i);
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
class E extends f {
|
|
145
145
|
constructor(t) {
|
|
146
|
-
super(), this.exited = !1, this.stdinData = [], this.childProcess = t, t.on("stdin", (
|
|
147
|
-
this.stdinData ? this.stdinData.push(
|
|
146
|
+
super(), this.exited = !1, this.stdinData = [], this.childProcess = t, t.on("stdin", (i) => {
|
|
147
|
+
this.stdinData ? this.stdinData.push(i.slice()) : this.emit("stdin", i);
|
|
148
148
|
});
|
|
149
149
|
}
|
|
150
150
|
stdout(t) {
|
|
@@ -172,73 +172,125 @@ class E extends f {
|
|
|
172
172
|
this.stdinData = null;
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
|
-
let
|
|
176
|
-
class
|
|
177
|
-
constructor(t =
|
|
175
|
+
let p = 9743;
|
|
176
|
+
class b extends f {
|
|
177
|
+
constructor(t = p++) {
|
|
178
178
|
super(), this.stdout = new f(), this.stderr = new f();
|
|
179
|
-
const
|
|
179
|
+
const i = this;
|
|
180
180
|
this.pid = t, this.stdin = {
|
|
181
|
-
write: (
|
|
182
|
-
|
|
181
|
+
write: (n) => {
|
|
182
|
+
i.emit("stdin", n);
|
|
183
183
|
}
|
|
184
184
|
};
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
|
-
function
|
|
188
|
-
const
|
|
189
|
-
let
|
|
190
|
-
for (let
|
|
191
|
-
|
|
192
|
-
return
|
|
187
|
+
function w(e = 36, t = "!@#$%^&*()_+=-[]/.,<>?") {
|
|
188
|
+
const i = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + t;
|
|
189
|
+
let n = "";
|
|
190
|
+
for (let r = e; r > 0; --r)
|
|
191
|
+
n += i[Math.floor(Math.random() * i.length)];
|
|
192
|
+
return n;
|
|
193
193
|
}
|
|
194
|
-
function
|
|
195
|
-
return
|
|
194
|
+
function N() {
|
|
195
|
+
return w(36, "-_");
|
|
196
196
|
}
|
|
197
|
-
function
|
|
198
|
-
return `json_decode(base64_decode('${
|
|
197
|
+
function S(e) {
|
|
198
|
+
return `json_decode(base64_decode('${P(
|
|
199
199
|
JSON.stringify(e)
|
|
200
200
|
)}'), true)`;
|
|
201
201
|
}
|
|
202
|
-
function
|
|
202
|
+
function k(e) {
|
|
203
203
|
const t = {};
|
|
204
|
-
for (const
|
|
205
|
-
t[
|
|
204
|
+
for (const i in e)
|
|
205
|
+
t[i] = S(e[i]);
|
|
206
206
|
return t;
|
|
207
207
|
}
|
|
208
|
-
function
|
|
209
|
-
return
|
|
208
|
+
function P(e) {
|
|
209
|
+
return x(new TextEncoder().encode(e));
|
|
210
210
|
}
|
|
211
|
-
function
|
|
211
|
+
function x(e) {
|
|
212
212
|
const t = String.fromCodePoint(...e);
|
|
213
213
|
return btoa(t);
|
|
214
214
|
}
|
|
215
|
-
function
|
|
215
|
+
function I(e, ...t) {
|
|
216
|
+
let i = "", n = 0;
|
|
217
|
+
for (let r = 0; r < e.length; r++)
|
|
218
|
+
if (e[r] === "%" && r + 1 < e.length) {
|
|
219
|
+
r++;
|
|
220
|
+
const u = e[r];
|
|
221
|
+
switch (u) {
|
|
222
|
+
case "s": {
|
|
223
|
+
const s = t[n++];
|
|
224
|
+
let o;
|
|
225
|
+
if (typeof s == "object")
|
|
226
|
+
try {
|
|
227
|
+
o = JSON.stringify(
|
|
228
|
+
s,
|
|
229
|
+
// Represent bigint values as strings in JSON.stringify().
|
|
230
|
+
(c, h) => typeof h == "bigint" ? `0x${h.toString(16)}` : h,
|
|
231
|
+
2
|
|
232
|
+
);
|
|
233
|
+
} catch {
|
|
234
|
+
}
|
|
235
|
+
else
|
|
236
|
+
o = String(s);
|
|
237
|
+
i += o;
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
case "d": {
|
|
241
|
+
const s = t[n++];
|
|
242
|
+
typeof s == "bigint" ? i += s.toString() : i += Math.floor(Number(s));
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
case "f": {
|
|
246
|
+
const s = t[n++];
|
|
247
|
+
i += Number(s);
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
case "x": {
|
|
251
|
+
const s = t[n++];
|
|
252
|
+
typeof s == "bigint" ? i += s.toString(16) : i += Math.floor(Number(s)).toString(16);
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
case "%": {
|
|
256
|
+
i += "%";
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
default:
|
|
260
|
+
i += "%" + u;
|
|
261
|
+
}
|
|
262
|
+
} else
|
|
263
|
+
i += e[r];
|
|
264
|
+
return i;
|
|
265
|
+
}
|
|
266
|
+
function O(e) {
|
|
216
267
|
let t = 0;
|
|
217
|
-
e.forEach((
|
|
218
|
-
const
|
|
219
|
-
let
|
|
220
|
-
return e.forEach((
|
|
221
|
-
|
|
222
|
-
}),
|
|
268
|
+
e.forEach((r) => t += r.length);
|
|
269
|
+
const i = new Uint8Array(t);
|
|
270
|
+
let n = 0;
|
|
271
|
+
return e.forEach((r) => {
|
|
272
|
+
i.set(r, n), n += r.length;
|
|
273
|
+
}), i;
|
|
223
274
|
}
|
|
224
|
-
function
|
|
225
|
-
return
|
|
275
|
+
function Q(e) {
|
|
276
|
+
return O(e.map((t) => new Uint8Array(t))).buffer;
|
|
226
277
|
}
|
|
227
278
|
export {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
279
|
+
g as AcquireTimeoutError,
|
|
280
|
+
_ as PhpWasmError,
|
|
281
|
+
D as Semaphore,
|
|
282
|
+
A as basename,
|
|
283
|
+
Q as concatArrayBuffers,
|
|
284
|
+
O as concatUint8Arrays,
|
|
234
285
|
q as createSpawnHandler,
|
|
235
286
|
U as dirname,
|
|
236
|
-
|
|
287
|
+
M as isParentOf,
|
|
237
288
|
T as joinPaths,
|
|
238
289
|
l as normalizePath,
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
290
|
+
S as phpVar,
|
|
291
|
+
k as phpVars,
|
|
292
|
+
N as randomFilename,
|
|
293
|
+
w as randomString,
|
|
294
|
+
I as sprintf
|
|
243
295
|
};
|
|
244
296
|
//# 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/split-shell-command.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/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 * 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","import { splitShellCommand } from './split-shell-command';\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\tawait program(commandArray, processApi, options);\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\tchildProcess.emit('spawn', true);\n\t\t});\n\t\treturn childProcess;\n\t};\n}\n\nclass EventEmitter {\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}\n\nexport class ProcessApi extends EventEmitter {\n\tprivate exited = false;\n\tprivate stdinData: Uint8Array[] | null = [];\n\tprivate 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.stdinData) {\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.stdinData.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\tstdout(data: string | ArrayBuffer) {\n\t\tif (typeof data === 'string') {\n\t\t\tdata = new TextEncoder().encode(data);\n\t\t}\n\t\tthis.childProcess.stdout.emit('data', data);\n\t}\n\tstdoutEnd() {\n\t\tthis.childProcess.stdout.emit('end', {});\n\t}\n\tstderr(data: string | ArrayBuffer) {\n\t\tif (typeof data === 'string') {\n\t\t\tdata = new TextEncoder().encode(data);\n\t\t}\n\t\tthis.childProcess.stderr.emit('data', data);\n\t}\n\tstderrEnd() {\n\t\tthis.childProcess.stderr.emit('end', {});\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.childProcess.emit('exit', code);\n\t\t}\n\t}\n\tflushStdin() {\n\t\tif (this.stdinData) {\n\t\t\tfor (let i = 0; i < this.stdinData.length; i++) {\n\t\t\t\tthis.emit('stdin', this.stdinData[i]);\n\t\t\t}\n\t\t}\n\t\tthis.stdinData = null;\n\t}\n}\n\nexport type StdIn = {\n\twrite: (data: string) => void;\n};\n\nlet lastPid = 9743;\nexport class ChildProcess extends EventEmitter {\n\tstdout: EventEmitter = new EventEmitter();\n\tstderr: EventEmitter = new EventEmitter();\n\tstdin: StdIn;\n\tpid: number;\n\tconstructor(pid = lastPid++) {\n\t\tsuper();\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this;\n\t\tthis.pid = pid;\n\t\tthis.stdin = {\n\t\t\twrite: (data: string) => {\n\t\t\t\tself.emit('stdin', data);\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","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} from './paths';\nexport { createSpawnHandler } from './create-spawn-handler';\nexport { randomString } from './random-string';\nexport { randomFilename } from './random-filename';\n\nexport * from './php-vars';\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))).buffer;\n}\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","last","isParentOf","parent","child","splitShellCommand","command","mode","quote","currentPart","i","char","createSpawnHandler","program","argsArray","options","childProcess","ChildProcess","processApi","ProcessApi","commandArray","e","EventEmitter","eventName","data","listener","code","lastPid","pid","self","randomString","length","specialChars","chars","result","randomFilename","phpVar","stringToBase64","phpVars","vars","key","str","bytesToBase64","bytes","binString","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/split-shell-command.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/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 * 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","import { splitShellCommand } from './split-shell-command';\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\tawait program(commandArray, processApi, options);\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\tchildProcess.emit('spawn', true);\n\t\t});\n\t\treturn childProcess;\n\t};\n}\n\nclass EventEmitter {\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}\n\nexport class ProcessApi extends EventEmitter {\n\tprivate exited = false;\n\tprivate stdinData: Uint8Array[] | null = [];\n\tprivate 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.stdinData) {\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.stdinData.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\tstdout(data: string | ArrayBuffer) {\n\t\tif (typeof data === 'string') {\n\t\t\tdata = new TextEncoder().encode(data);\n\t\t}\n\t\tthis.childProcess.stdout.emit('data', data);\n\t}\n\tstdoutEnd() {\n\t\tthis.childProcess.stdout.emit('end', {});\n\t}\n\tstderr(data: string | ArrayBuffer) {\n\t\tif (typeof data === 'string') {\n\t\t\tdata = new TextEncoder().encode(data);\n\t\t}\n\t\tthis.childProcess.stderr.emit('data', data);\n\t}\n\tstderrEnd() {\n\t\tthis.childProcess.stderr.emit('end', {});\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.childProcess.emit('exit', code);\n\t\t}\n\t}\n\tflushStdin() {\n\t\tif (this.stdinData) {\n\t\t\tfor (let i = 0; i < this.stdinData.length; i++) {\n\t\t\t\tthis.emit('stdin', this.stdinData[i]);\n\t\t\t}\n\t\t}\n\t\tthis.stdinData = null;\n\t}\n}\n\nexport type StdIn = {\n\twrite: (data: string) => void;\n};\n\nlet lastPid = 9743;\nexport class ChildProcess extends EventEmitter {\n\tstdout: EventEmitter = new EventEmitter();\n\tstderr: EventEmitter = new EventEmitter();\n\tstdin: StdIn;\n\tpid: number;\n\tconstructor(pid = lastPid++) {\n\t\tsuper();\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this;\n\t\tthis.pid = pid;\n\t\tthis.stdin = {\n\t\t\twrite: (data: string) => {\n\t\t\t\tself.emit('stdin', data);\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","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} from './paths';\nexport { createSpawnHandler } from './create-spawn-handler';\nexport { randomString } from './random-string';\nexport { randomFilename } from './random-filename';\n\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))).buffer;\n}\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","splitShellCommand","command","mode","quote","currentPart","char","createSpawnHandler","program","argsArray","options","childProcess","ChildProcess","processApi","ProcessApi","commandArray","e","EventEmitter","eventName","data","listener","code","lastPid","pid","self","randomString","length","specialChars","chars","result","randomFilename","phpVar","stringToBase64","phpVars","vars","key","str","bytesToBase64","bytes","binString","sprintf","format","args","argIndex","specifier","arg","concatUint8Arrays","arrays","totalLength","a","offset","concatArrayBuffers","buffers","b"],"mappings":"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"}
|
package/lib/index.d.ts
CHANGED
|
@@ -7,5 +7,6 @@ export { createSpawnHandler } from './create-spawn-handler';
|
|
|
7
7
|
export { randomString } from './random-string';
|
|
8
8
|
export { randomFilename } from './random-filename';
|
|
9
9
|
export * from './php-vars';
|
|
10
|
+
export * from './sprintf';
|
|
10
11
|
export declare function concatUint8Arrays(arrays: Uint8Array[]): Uint8Array;
|
|
11
12
|
export declare function concatArrayBuffers(buffers: ArrayBuffer[]): ArrayBuffer;
|
package/lib/sprintf.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats a string like sprintf().
|
|
3
|
+
*
|
|
4
|
+
* This function:
|
|
5
|
+
* - Supports basic format specifiers: %s, %d, %f, %x, %%
|
|
6
|
+
* - Supports bigint values
|
|
7
|
+
*
|
|
8
|
+
* The purpose of this function is for use in optional php-wasm tracing.
|
|
9
|
+
* If we use printf-style formatting for trace messages, we let the trace
|
|
10
|
+
* function decide whether to format and do not have to pay for formatting
|
|
11
|
+
* unless tracing is enabled.
|
|
12
|
+
*/
|
|
13
|
+
export declare function sprintf(format: string, ...args: any[]): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@php-wasm/util",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "index.d.ts",
|
|
6
6
|
"typedoc": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"main": "./index.cjs",
|
|
25
25
|
"module": "./index.js",
|
|
26
|
-
"gitHead": "
|
|
26
|
+
"gitHead": "ed646326d99ba84bad911d65b6634265f508f073",
|
|
27
27
|
"engines": {
|
|
28
28
|
"node": ">=20.18.3",
|
|
29
29
|
"npm": ">=10.1.0"
|