@wp-playground/wordpress 3.0.22 → 3.0.31

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/boot.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { CookieStore, FileNotFoundAction, FileNotFoundGetActionCallback, FileTree, PHPProcessManager, SpawnHandler } from '@php-wasm/universal';
1
+ import type { CookieStore, FileNotFoundAction, FileNotFoundGetActionCallback, FileTree, PHPWorker, SpawnHandler, Remote } from '@php-wasm/universal';
2
2
  import { PHP, PHPRequestHandler } from '@php-wasm/universal';
3
3
  export type PhpIniOptions = Record<string, string>;
4
4
  export type Hook = (php: PHP) => void | Promise<void>;
@@ -14,6 +14,7 @@ export declare function bootWordPressAndRequestHandler(options: BootRequestHandl
14
14
  export interface BootRequestHandlerOptions {
15
15
  createPhpRuntime: (isPrimary?: boolean) => Promise<number>;
16
16
  onPHPInstanceCreated?: PHPInstanceCreatedHook;
17
+ maxPhpInstances?: number;
17
18
  /**
18
19
  * PHP SAPI name to be returned by get_sapi_name(). Overriding
19
20
  * it is useful for running programs that check for this value,
@@ -26,7 +27,10 @@ export interface BootRequestHandlerOptions {
26
27
  */
27
28
  siteUrl: string;
28
29
  documentRoot?: string;
29
- spawnHandler?: (processManager: PHPProcessManager) => SpawnHandler;
30
+ spawnHandler?: (getPHPInstance?: () => Promise<{
31
+ php: PHP | Remote<PHPWorker>;
32
+ reap: () => void;
33
+ }>) => SpawnHandler;
30
34
  /**
31
35
  * PHP.ini entries to define before running any code. They'll
32
36
  * be used for all requests.
package/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("@php-wasm/util"),f=require("@wp-playground/common"),h=require("@php-wasm/logger"),u=require("@php-wasm/universal"),x=`<?php
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("@php-wasm/util"),c=require("@wp-playground/common"),h=require("@php-wasm/logger"),u=require("@php-wasm/universal"),x=`<?php
2
2
 
3
3
  /**
4
4
  * Rewrites the wp-config.php file to ensure specific constants are defined
@@ -352,7 +352,7 @@ function skip_whitespace($tokens) {
352
352
  ob_clean();
353
353
  echo false === $return_value ? '0' : '1';
354
354
  ob_end_flush();
355
- `})).text!=="1")throw new Error("Failed to rewrite constants in wp-config.php.")}async function w(e,n){const t=a.joinPaths(n,"wp-config.php"),i={DB_NAME:"wordpress"};!e.fileExists(t)&&e.fileExists(a.joinPaths(n,"wp-config-sample.php"))&&await e.writeFile(t,await e.readFileAsBuffer(a.joinPaths(n,"wp-config-sample.php"))),await g(e,t,i,"skip")}async function L(e){const n=await m(e);return await $(n,e),n}async function $(e,n){var l,s;const t=await e.getPrimaryPhp();if((l=n.hooks)!=null&&l.beforeWordPressFiles&&await n.hooks.beforeWordPressFiles(t),n.wordPressZip&&await S(t,await n.wordPressZip),n.constants)for(const d in n.constants)t.defineConstant(d,n.constants[d]);n.dataSqlPath&&(t.defineConstant("DB_DIR",a.dirname(n.dataSqlPath)),t.defineConstant("DB_FILE",a.basename(n.dataSqlPath))),t.defineConstant("WP_HOME",n.siteUrl),t.defineConstant("WP_SITEURL",n.siteUrl),await w(t,e.documentRoot),(s=n.hooks)!=null&&s.beforeDatabaseSetup&&await n.hooks.beforeDatabaseSetup(t);let i=!1;n.sqliteIntegrationPluginZip&&(i=!0,await T(t,await n.sqliteIntegrationPluginZip));const r=n.wordpressInstallMode??"download-and-install",o=!!n.dataSqlPath;if(["download-and-install","install-from-existing-files"].includes(r)){await c(e,{usesSqlite:i,hasCustomDatabasePath:o});try{await _(t)}catch(d){throw o||await p(e),d}o||await p(e)}else if(r==="install-from-existing-files-if-needed"){if(await c(e,{usesSqlite:i,hasCustomDatabasePath:o}),!await b(t))try{await _(t)}catch(d){throw o||await p(e),d}o||await p(e)}return e}async function c(e,{usesSqlite:n,hasCustomDatabasePath:t}){const i=await e.getPrimaryPhp();if(i.isFile("/internal/shared/preload/0-sqlite.php"))return;const r=a.joinPaths(e.documentRoot,"wp-content/mu-plugins/sqlite-database-integration");if(!i.isDir(r)&&!n&&!t)throw new Error("Error connecting to the MySQL database.")}async function p(e){const n=await e.getPrimaryPhp();if(await I(n))return;if(n.isFile("/internal/shared/preload/0-sqlite.php"))throw new Error("Error connecting to the SQLite database.");const i=a.joinPaths(e.documentRoot,"wp-content/mu-plugins/sqlite-database-integration");throw n.isDir(i)?new Error("Error connecting to the SQLite database."):new Error("Error connecting to the MySQL database.")}async function m(e){const n=e.spawnHandler??u.sandboxedSpawnHandlerFactory;async function t(r,o){const l=await e.createPhpRuntime(o),s=new u.PHP(l);return e.sapiName&&s.setSapiName(e.sapiName),r&&(s.requestHandler=r),e.phpIniEntries&&u.setPhpIniEntries(s,e.phpIniEntries),s.defineConstant("WP_SQLITE_AST_DRIVER",!0),o&&!s.isFile("/internal/.boot-files-written")&&(await E(s),await u.writeFiles(s,"/",e.createFiles||{}),await R(s,a.joinPaths(new URL(e.siteUrl).pathname,"phpinfo.php")),await u.writeFiles(s,"/internal",{".boot-files-written":""})),n&&await s.setSpawnHandler(n(r.processManager)),s.enableRuntimeRotation({recreateRuntime:e.createPhpRuntime,maxRequests:400}),e.onPHPInstanceCreated&&await e.onPHPInstanceCreated(s,{isPrimary:o}),s}const i=new u.PHPRequestHandler({phpFactory:async({isPrimary:r})=>t(i,r),documentRoot:e.documentRoot||"/wordpress",absoluteUrl:e.siteUrl,rewriteRules:k,getFileNotFoundAction:e.getFileNotFoundAction??P,cookieStore:e.cookieStore});return i}async function b(e){return(await e.run({code:`<?php
355
+ `})).text!=="1")throw new Error("Failed to rewrite constants in wp-config.php.")}async function w(e,n){const t=a.joinPaths(n,"wp-config.php"),i={DB_NAME:"wordpress"};!e.fileExists(t)&&e.fileExists(a.joinPaths(n,"wp-config-sample.php"))&&await e.writeFile(t,await e.readFileAsBuffer(a.joinPaths(n,"wp-config-sample.php"))),await g(e,t,i,"skip")}async function I(e){const n=await m(e);return await $(n,e),n}async function $(e,n){var l,s;const t=await e.getPrimaryPhp();if((l=n.hooks)!=null&&l.beforeWordPressFiles&&await n.hooks.beforeWordPressFiles(t),n.wordPressZip&&await v(t,await n.wordPressZip),n.constants)for(const d in n.constants)t.defineConstant(d,n.constants[d]);n.dataSqlPath&&(t.defineConstant("DB_DIR",a.dirname(n.dataSqlPath)),t.defineConstant("DB_FILE",a.basename(n.dataSqlPath))),t.defineConstant("WP_HOME",n.siteUrl),t.defineConstant("WP_SITEURL",n.siteUrl),await w(t,e.documentRoot),(s=n.hooks)!=null&&s.beforeDatabaseSetup&&await n.hooks.beforeDatabaseSetup(t);let i=!1;n.sqliteIntegrationPluginZip&&(i=!0,await T(t,await n.sqliteIntegrationPluginZip));const r=n.wordpressInstallMode??"download-and-install",o=!!n.dataSqlPath;if(["download-and-install","install-from-existing-files"].includes(r)){await f(e,{usesSqlite:i,hasCustomDatabasePath:o});try{await _(t)}catch(d){throw o||await p(e),d}o||await p(e)}else if(r==="install-from-existing-files-if-needed"){if(await f(e,{usesSqlite:i,hasCustomDatabasePath:o}),!await b(t))try{await _(t)}catch(d){throw o||await p(e),d}o||await p(e)}return e}async function f(e,{usesSqlite:n,hasCustomDatabasePath:t}){const i=await e.getPrimaryPhp();if(i.isFile("/internal/shared/preload/0-sqlite.php"))return;const r=a.joinPaths(e.documentRoot,"wp-content/mu-plugins/sqlite-database-integration");if(!i.isDir(r)&&!n&&!t)throw new Error("Error connecting to the MySQL database.")}async function p(e){const n=await e.getPrimaryPhp();if(await L(n))return;if(n.isFile("/internal/shared/preload/0-sqlite.php"))throw new Error("Error connecting to the SQLite database.");const i=a.joinPaths(e.documentRoot,"wp-content/mu-plugins/sqlite-database-integration");throw n.isDir(i)?new Error("Error connecting to the SQLite database."):new Error("Error connecting to the MySQL database.")}async function m(e){const n=e.spawnHandler??u.sandboxedSpawnHandlerFactory;async function t(r,o=!1){const l=await e.createPhpRuntime(o),s=new u.PHP(l);return e.sapiName&&s.setSapiName(e.sapiName),r&&(s.requestHandler=r),e.phpIniEntries&&u.setPhpIniEntries(s,e.phpIniEntries),s.defineConstant("WP_SQLITE_AST_DRIVER",!0),o&&!s.isFile("/internal/.boot-files-written")&&(await E(s),await u.writeFiles(s,"/",e.createFiles||{}),await R(s,a.joinPaths(new URL(e.siteUrl).pathname,"phpinfo.php")),await u.writeFiles(s,"/internal",{".boot-files-written":""})),n&&await s.setSpawnHandler(n(r?()=>r.instanceManager.acquirePHPInstance({considerPrimary:!1}):void 0)),s.enableRuntimeRotation({recreateRuntime:e.createPhpRuntime,maxRequests:400}),e.onPHPInstanceCreated&&await e.onPHPInstanceCreated(s,{isPrimary:o}),s}const i=new u.PHPRequestHandler({documentRoot:e.documentRoot||"/wordpress",absoluteUrl:e.siteUrl,rewriteRules:k,getFileNotFoundAction:e.getFileNotFoundAction??P,cookieStore:e.cookieStore,php:e.maxPhpInstances===1?await t(void 0,!0):void 0,phpFactory:e.maxPhpInstances!==1?async({isPrimary:r})=>t(i,r):void 0,maxPhpInstances:e.maxPhpInstances});return i}async function b(e){return(await e.run({code:`<?php
356
356
  ob_start();
357
357
  $wp_load = getenv('DOCUMENT_ROOT') . '/wp-load.php';
358
358
  if (!file_exists($wp_load)) {
@@ -383,7 +383,7 @@ function skip_whitespace($tokens) {
383
383
  echo '0';
384
384
  }
385
385
  ob_end_flush();
386
- `,env:{DOCUMENT_ROOT:e.documentRoot}})).text!=="1"&&h.logger.warn("Failed to default to pretty permalinks after WP install.")}function P(e){return{type:"internal-redirect",uri:"/index.php"}}async function I(e){return(await e.run({code:`<?php
386
+ `,env:{DOCUMENT_ROOT:e.documentRoot}})).text!=="1"&&h.logger.warn("Failed to default to pretty permalinks after WP install.")}function P(e){return{type:"internal-redirect",uri:"/index.php"}}async function L(e){return(await e.run({code:`<?php
387
387
  ob_start();
388
388
  $wp_load = getenv('DOCUMENT_ROOT') . '/wp-load.php';
389
389
  if (!file_exists($wp_load)) {
@@ -394,10 +394,10 @@ function skip_whitespace($tokens) {
394
394
  ob_clean();
395
395
  echo $wpdb->check_connection( false ) ? '1' : '0';
396
396
  ob_end_flush();
397
- `,env:{DOCUMENT_ROOT:e.documentRoot}})).text==="1"}async function W(e){const{php:n,reap:t}=await e.processManager.acquirePHPInstance({considerPrimary:!0});try{const r=(await n.run({code:`<?php
397
+ `,env:{DOCUMENT_ROOT:e.documentRoot}})).text==="1"}async function W(e){const{php:n,reap:t}=await e.instanceManager.acquirePHPInstance({considerPrimary:!0});try{const r=(await n.run({code:`<?php
398
398
  require '${e.documentRoot}/wp-includes/version.php';
399
399
  echo $wp_version;
400
- `})).text;if(!r)throw new Error("Unable to read loaded WordPress version.");return y(r)}finally{t()}}function y(e){if(/-(alpha|beta|RC)\d*-\d+$/.test(e))return"nightly";if(/-(beta|RC)\d*$/.test(e))return"beta";const i=e.match(/^(\d+\.\d+)(?:\.\d+)?$/);return i!==null?i[1]:e}const k=[{match:new RegExp("^(/[_0-9a-zA-Z-]+)?(/wp-(content|admin|includes)/.*)"),replacement:"$2"}];async function E(e){await e.mkdir("/internal/shared/mu-plugins"),await e.writeFile("/internal/shared/preload/env.php",`<?php
400
+ `})).text;if(!r)throw new Error("Unable to read loaded WordPress version.");return y(r)}finally{t()}}function y(e){if(/-(alpha|beta|RC)\d*-\d+$/.test(e))return"trunk";if(/-(beta|RC)\d*$/.test(e))return"beta";const i=e.match(/^(\d+\.\d+)(?:\.\d+)?$/);return i!==null?i[1]:e}const k=[{match:new RegExp("^(/[_0-9a-zA-Z-]+)?(/wp-(content|admin|includes)/.*)"),replacement:"$2"}];async function E(e){await e.mkdir("/internal/shared/mu-plugins"),await e.writeFile("/internal/shared/preload/env.php",`<?php
401
401
 
402
402
  // Allow adding filters/actions prior to loading WordPress.
403
403
  // $function_to_add MUST be a string.
@@ -674,7 +674,7 @@ function skip_whitespace($tokens) {
674
674
  phpinfo();
675
675
  exit;
676
676
  }
677
- `)}async function T(e,n){await e.isDir("/tmp/sqlite-database-integration")&&await e.rmdir("/tmp/sqlite-database-integration",{recursive:!0}),await e.mkdir("/tmp/sqlite-database-integration"),await f.unzipFile(e,n,"/tmp/sqlite-database-integration");const t="/internal/shared/sqlite-database-integration",i=`/tmp/sqlite-database-integration/${(await e.listFiles("/tmp/sqlite-database-integration"))[0]}`;await e.mv(i,t),await e.defineConstant("SQLITE_MAIN_FILE","1");const o=(await e.readFileAsText(a.joinPaths(t,"db.copy"))).replace("'{SQLITE_IMPLEMENTATION_FOLDER_PATH}'",a.phpVar(t)).replace("'{SQLITE_PLUGIN}'",a.phpVar(a.joinPaths(t,"load.php"))),l=a.joinPaths(await e.documentRoot,"wp-content/db.php"),s=`<?php
677
+ `)}async function T(e,n){await e.isDir("/tmp/sqlite-database-integration")&&await e.rmdir("/tmp/sqlite-database-integration",{recursive:!0}),await e.mkdir("/tmp/sqlite-database-integration"),await c.unzipFile(e,n,"/tmp/sqlite-database-integration");const t="/internal/shared/sqlite-database-integration",i=`/tmp/sqlite-database-integration/${(await e.listFiles("/tmp/sqlite-database-integration"))[0]}`;await e.mv(i,t),await e.defineConstant("SQLITE_MAIN_FILE","1");const o=(await e.readFileAsText(a.joinPaths(t,"db.copy"))).replace("'{SQLITE_IMPLEMENTATION_FOLDER_PATH}'",a.phpVar(t)).replace("'{SQLITE_PLUGIN}'",a.phpVar(a.joinPaths(t,"load.php"))),l=a.joinPaths(await e.documentRoot,"wp-content/db.php"),s=`<?php
678
678
  // Do not preload this if WordPress comes with a custom db.php file.
679
679
  if(file_exists(${a.phpVar(l)})) {
680
680
  return;
@@ -760,5 +760,5 @@ if(!function_exists('mysqli_connect')) {
760
760
  var_dump(isset($wpdb));
761
761
  die("SQLite integration not loaded " . get_class($wpdb));
762
762
  }
763
- `)}async function S(e,n){e.mkdir("/tmp/unzipped-wordpress"),await f.unzipFile(e,n,"/tmp/unzipped-wordpress"),e.fileExists("/tmp/unzipped-wordpress/wordpress.zip")&&await f.unzipFile(e,"/tmp/unzipped-wordpress/wordpress.zip","/tmp/unzipped-wordpress");let t=e.fileExists("/tmp/unzipped-wordpress/wordpress")?"/tmp/unzipped-wordpress/wordpress":e.fileExists("/tmp/unzipped-wordpress/build")?"/tmp/unzipped-wordpress/build":"/tmp/unzipped-wordpress";if(!e.fileExists(a.joinPaths(t,"wp-config-sample.php"))){const r=e.listFiles(t);if(r.length){const o=r[0];e.fileExists(a.joinPaths(t,o,"wp-config-sample.php"))&&(t=a.joinPaths(t,o))}}const i=(r,o,l)=>{if(l.isDir(r)&&l.isDir(o))for(const s of l.listFiles(r)){const d=a.joinPaths(r,s),v=a.joinPaths(o,s);i(d,v,l)}else{if(l.fileExists(o)){const s=r.replace(/^\/tmp\/unzipped-wordpress\//,"/");h.logger.warn(`Cannot unzip WordPress files at ${o}: ${s} already exists.`);return}l.mv(r,o)}};i(t,e.documentRoot,e),e.fileExists(t)&&e.rmdir(t,{recursive:!0}),!e.fileExists(a.joinPaths(e.documentRoot,"wp-config.php"))&&e.fileExists(a.joinPaths(e.documentRoot,"wp-config-sample.php"))&&e.writeFile(a.joinPaths(e.documentRoot,"wp-config.php"),e.readFileAsText(a.joinPaths(e.documentRoot,"/wp-config-sample.php")))}const U=f.createMemoizedFetch(fetch);async function C(e="latest"){if(e===null)e="latest";else if(e.startsWith("https://")||e.startsWith("http://")){const i=await crypto.subtle.digest("SHA-1",new TextEncoder().encode(e)),r=Array.from(new Uint8Array(i)).map(o=>o.toString(16).padStart(2,"0")).join("");return{releaseUrl:e,version:"custom-"+r.substring(0,8),source:"inferred"}}else if(e==="trunk"||e==="nightly")return{releaseUrl:"https://wordpress.org/nightly-builds/wordpress-latest.zip",version:"nightly-"+new Date().toISOString().split("T")[0],source:"inferred"};let t=await(await U("https://api.wordpress.org/core/version-check/1.7/?channel=beta")).json();t=t.offers.filter(i=>i.response==="autoupdate");for(const i of t){if(e==="beta"&&(i.version.includes("beta")||i.version.includes("RC")))return{releaseUrl:i.download,version:i.version,source:"api"};if(e==="latest"&&!i.version.includes("beta")&&!i.version.includes("RC"))return{releaseUrl:i.download,version:i.version,source:"api"};if(i.version.substring(0,e.length)===e)return{releaseUrl:i.download,version:i.version,source:"api"}}return e.match(/^\d+\.\d+\.0$/)&&(e=e.split(".").slice(0,2).join(".")),{releaseUrl:`https://wordpress.org/wordpress-${e}.zip`,version:e,source:"inferred"}}exports.bootRequestHandler=m;exports.bootWordPress=$;exports.bootWordPressAndRequestHandler=L;exports.defineWpConfigConstants=g;exports.ensureWpConfig=w;exports.getFileNotFoundActionForWordPress=P;exports.getLoadedWordPressVersion=W;exports.preloadPhpInfoRoute=R;exports.preloadSqliteIntegration=T;exports.resolveWordPressRelease=C;exports.setupPlatformLevelMuPlugins=E;exports.unzipWordPress=S;exports.versionStringToLoadedWordPressVersion=y;exports.wordPressRewriteRules=k;
763
+ `)}async function v(e,n){e.mkdir("/tmp/unzipped-wordpress"),await c.unzipFile(e,n,"/tmp/unzipped-wordpress"),e.fileExists("/tmp/unzipped-wordpress/wordpress.zip")&&await c.unzipFile(e,"/tmp/unzipped-wordpress/wordpress.zip","/tmp/unzipped-wordpress");let t=e.fileExists("/tmp/unzipped-wordpress/wordpress")?"/tmp/unzipped-wordpress/wordpress":e.fileExists("/tmp/unzipped-wordpress/build")?"/tmp/unzipped-wordpress/build":"/tmp/unzipped-wordpress";if(!e.fileExists(a.joinPaths(t,"wp-config-sample.php"))){const r=e.listFiles(t);if(r.length){const o=r[0];e.fileExists(a.joinPaths(t,o,"wp-config-sample.php"))&&(t=a.joinPaths(t,o))}}const i=(r,o,l)=>{if(l.isDir(r)&&l.isDir(o))for(const s of l.listFiles(r)){const d=a.joinPaths(r,s),S=a.joinPaths(o,s);i(d,S,l)}else{if(l.fileExists(o)){const s=r.replace(/^\/tmp\/unzipped-wordpress\//,"/");h.logger.warn(`Cannot unzip WordPress files at ${o}: ${s} already exists.`);return}l.mv(r,o)}};i(t,e.documentRoot,e),e.fileExists(t)&&e.rmdir(t,{recursive:!0}),!e.fileExists(a.joinPaths(e.documentRoot,"wp-config.php"))&&e.fileExists(a.joinPaths(e.documentRoot,"wp-config-sample.php"))&&e.writeFile(a.joinPaths(e.documentRoot,"wp-config.php"),e.readFileAsText(a.joinPaths(e.documentRoot,"/wp-config-sample.php")))}const U=c.createMemoizedFetch(fetch),C="https://github.com/WordPress/WordPress/archive/refs/heads/master.zip";async function O(e="latest"){if(e===null)e="latest";else if(e.startsWith("https://")||e.startsWith("http://")){const i=await crypto.subtle.digest("SHA-1",new TextEncoder().encode(e)),r=Array.from(new Uint8Array(i)).map(o=>o.toString(16).padStart(2,"0")).join("");return{releaseUrl:e,version:"custom-"+r.substring(0,8),source:"inferred"}}else if(e==="trunk"||e==="nightly"){const i=new Date().toISOString().split("T")[0];return{releaseUrl:`${C}?ts=${i}`,version:"trunk",source:"inferred"}}let t=await(await U("https://api.wordpress.org/core/version-check/1.7/?channel=beta")).json();t=t.offers.filter(i=>i.response==="autoupdate");for(const i of t){if(e==="beta"&&(i.version.includes("beta")||i.version.includes("RC")))return{releaseUrl:i.download,version:i.version,source:"api"};if(e==="latest"&&!i.version.includes("beta")&&!i.version.includes("RC"))return{releaseUrl:i.download,version:i.version,source:"api"};if(i.version.substring(0,e.length)===e)return{releaseUrl:i.download,version:i.version,source:"api"}}return e.match(/^\d+\.\d+\.0$/)&&(e=e.split(".").slice(0,2).join(".")),{releaseUrl:`https://wordpress.org/wordpress-${e}.zip`,version:e,source:"inferred"}}exports.bootRequestHandler=m;exports.bootWordPress=$;exports.bootWordPressAndRequestHandler=I;exports.defineWpConfigConstants=g;exports.ensureWpConfig=w;exports.getFileNotFoundActionForWordPress=P;exports.getLoadedWordPressVersion=W;exports.preloadPhpInfoRoute=R;exports.preloadSqliteIntegration=T;exports.resolveWordPressRelease=O;exports.setupPlatformLevelMuPlugins=E;exports.unzipWordPress=v;exports.versionStringToLoadedWordPressVersion=y;exports.wordPressRewriteRules=k;
764
764
  //# sourceMappingURL=index.cjs.map
package/index.d.ts CHANGED
@@ -33,25 +33,6 @@ export declare function preloadSqliteIntegration(php: UniversalPHP, sqliteZip: F
33
33
  * as that's viable.
34
34
  */
35
35
  export declare function unzipWordPress(php: PHP, wpZip: File): Promise<void>;
36
- /**
37
- * Resolves a specific WordPress release URL and version string based on
38
- * a version query string such as "latest", "beta", or "6.6".
39
- *
40
- * Examples:
41
- * ```js
42
- * const { releaseUrl, version } = await resolveWordPressRelease('latest')
43
- * // becomes https://wordpress.org/wordpress-6.6.2.zip and '6.6.2'
44
- *
45
- * const { releaseUrl, version } = await resolveWordPressRelease('beta')
46
- * // becomes https://wordpress.org/wordpress-6.6.2-RC1.zip and '6.6.2-RC1'
47
- *
48
- * const { releaseUrl, version } = await resolveWordPressRelease('6.6')
49
- * // becomes https://wordpress.org/wordpress-6.6.2.zip and '6.6.2'
50
- * ```
51
- *
52
- * @param versionQuery - The WordPress version query string to resolve.
53
- * @returns The resolved WordPress release URL and version string.
54
- */
55
36
  export declare function resolveWordPressRelease(versionQuery?: string): Promise<{
56
37
  releaseUrl: any;
57
38
  version: any;
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { phpVars as m, joinPaths as s, dirname as b, basename as y, phpVar as u } from "@php-wasm/util";
2
- import { createMemoizedFetch as k, unzipFile as f } from "@wp-playground/common";
2
+ import { createMemoizedFetch as P, unzipFile as c } from "@wp-playground/common";
3
3
  import { logger as g } from "@php-wasm/logger";
4
- import { sandboxedSpawnHandlerFactory as P, PHPRequestHandler as E, withPHPIniValues as T, PHP as R, setPhpIniEntries as S, writeFiles as c } from "@php-wasm/universal";
5
- const v = `<?php
4
+ import { sandboxedSpawnHandlerFactory as k, PHPRequestHandler as E, withPHPIniValues as R, PHP as T, setPhpIniEntries as v, writeFiles as f } from "@php-wasm/universal";
5
+ const S = `<?php
6
6
 
7
7
  /**
8
8
  * Rewrites the wp-config.php file to ensure specific constants are defined
@@ -352,7 +352,7 @@ async function x(e, n, t, i = "rewrite") {
352
352
  const r = m({ wpConfigPath: n, constants: t, whenAlreadyDefined: i });
353
353
  if ((await e.run({
354
354
  code: `<?php ob_start(); ?>
355
- ${v}
355
+ ${S}
356
356
  $wp_config_path = ${r.wpConfigPath};
357
357
  $wp_config = file_get_contents($wp_config_path);
358
358
  $new_wp_config = rewrite_wp_config_to_define_constants($wp_config, ${r.constants}, ${r.whenAlreadyDefined});
@@ -364,7 +364,7 @@ async function x(e, n, t, i = "rewrite") {
364
364
  })).text !== "1")
365
365
  throw new Error("Failed to rewrite constants in wp-config.php.");
366
366
  }
367
- async function L(e, n) {
367
+ async function I(e, n) {
368
368
  const t = s(n, "wp-config.php"), i = {
369
369
  DB_NAME: "wordpress"
370
370
  };
@@ -375,17 +375,17 @@ async function L(e, n) {
375
375
  )
376
376
  ), await x(e, t, i, "skip");
377
377
  }
378
- async function Q(e) {
378
+ async function V(e) {
379
379
  const n = await U(e);
380
- return await I(n, e), n;
380
+ return await L(n, e), n;
381
381
  }
382
- async function I(e, n) {
382
+ async function L(e, n) {
383
383
  var l, o;
384
384
  const t = await e.getPrimaryPhp();
385
385
  if ((l = n.hooks) != null && l.beforeWordPressFiles && await n.hooks.beforeWordPressFiles(t), n.wordPressZip && await q(t, await n.wordPressZip), n.constants)
386
386
  for (const d in n.constants)
387
387
  t.defineConstant(d, n.constants[d]);
388
- n.dataSqlPath && (t.defineConstant("DB_DIR", b(n.dataSqlPath)), t.defineConstant("DB_FILE", y(n.dataSqlPath))), t.defineConstant("WP_HOME", n.siteUrl), t.defineConstant("WP_SITEURL", n.siteUrl), await L(t, e.documentRoot), (o = n.hooks) != null && o.beforeDatabaseSetup && await n.hooks.beforeDatabaseSetup(t);
388
+ n.dataSqlPath && (t.defineConstant("DB_DIR", b(n.dataSqlPath)), t.defineConstant("DB_FILE", y(n.dataSqlPath))), t.defineConstant("WP_HOME", n.siteUrl), t.defineConstant("WP_SITEURL", n.siteUrl), await I(t, e.documentRoot), (o = n.hooks) != null && o.beforeDatabaseSetup && await n.hooks.beforeDatabaseSetup(t);
389
389
  let i = !1;
390
390
  n.sqliteIntegrationPluginZip && (i = !0, await N(
391
391
  t,
@@ -435,7 +435,7 @@ async function _(e, {
435
435
  }
436
436
  async function p(e) {
437
437
  const n = await e.getPrimaryPhp();
438
- if (await W(n))
438
+ if (await C(n))
439
439
  return;
440
440
  if (n.isFile("/internal/shared/preload/0-sqlite.php"))
441
441
  throw new Error("Error connecting to the SQLite database.");
@@ -446,10 +446,10 @@ async function p(e) {
446
446
  throw n.isDir(i) ? new Error("Error connecting to the SQLite database.") : new Error("Error connecting to the MySQL database.");
447
447
  }
448
448
  async function U(e) {
449
- const n = e.spawnHandler ?? P;
450
- async function t(r, a) {
451
- const l = await e.createPhpRuntime(a), o = new R(l);
452
- return e.sapiName && o.setSapiName(e.sapiName), r && (o.requestHandler = r), e.phpIniEntries && S(o, e.phpIniEntries), o.defineConstant("WP_SQLITE_AST_DRIVER", !0), a && /**
449
+ const n = e.spawnHandler ?? k;
450
+ async function t(r, a = !1) {
451
+ const l = await e.createPhpRuntime(a), o = new T(l);
452
+ return e.sapiName && o.setSapiName(e.sapiName), r && (o.requestHandler = r), e.phpIniEntries && v(o, e.phpIniEntries), o.defineConstant("WP_SQLITE_AST_DRIVER", !0), a && /**
453
453
  * Only the first PHP instance of the first worker created
454
454
  * during WordPress boot writes these files – otherwise we'll keep
455
455
  * overwriting them with concurrent writers living in other worker
@@ -459,25 +459,43 @@ async function U(e) {
459
459
  * mechanism. It works, because secondary workers are only booted
460
460
  * once the primary worker has fully booted.
461
461
  */
462
- !o.isFile("/internal/.boot-files-written") && (await A(o), await c(o, "/", e.createFiles || {}), await F(
462
+ !o.isFile("/internal/.boot-files-written") && (await A(o), await f(o, "/", e.createFiles || {}), await F(
463
463
  o,
464
464
  s(new URL(e.siteUrl).pathname, "phpinfo.php")
465
- ), await c(o, "/internal", {
465
+ ), await f(o, "/internal", {
466
466
  ".boot-files-written": ""
467
467
  })), n && await o.setSpawnHandler(
468
- n(r.processManager)
468
+ n(
469
+ r ? () => r.instanceManager.acquirePHPInstance(
470
+ {
471
+ considerPrimary: !1
472
+ }
473
+ ) : void 0
474
+ )
469
475
  ), o.enableRuntimeRotation({
470
476
  recreateRuntime: e.createPhpRuntime,
471
477
  maxRequests: 400
472
478
  }), e.onPHPInstanceCreated && await e.onPHPInstanceCreated(o, { isPrimary: a }), o;
473
479
  }
474
480
  const i = new E({
475
- phpFactory: async ({ isPrimary: r }) => t(i, r),
476
481
  documentRoot: e.documentRoot || "/wordpress",
477
482
  absoluteUrl: e.siteUrl,
478
483
  rewriteRules: D,
479
- getFileNotFoundAction: e.getFileNotFoundAction ?? C,
480
- cookieStore: e.cookieStore
484
+ getFileNotFoundAction: e.getFileNotFoundAction ?? W,
485
+ cookieStore: e.cookieStore,
486
+ /**
487
+ * If maxPhpInstances is 1, the PHPRequestHandler constructor needs
488
+ * a PHP instance. Internally, it creates a SinglePHPInstanceManager
489
+ * and uses the same PHP instance to handle all requests.
490
+ */
491
+ php: e.maxPhpInstances === 1 ? await t(void 0, !0) : void 0,
492
+ /**
493
+ * If maxPhpInstances is not 1, the PHPRequestHandler constructor needs
494
+ * a PHP factory function. Internally, it creates a PHPProcessManager that
495
+ * dynamically starts new PHP instances and reaps them after they're used.
496
+ */
497
+ phpFactory: e.maxPhpInstances !== 1 ? async ({ isPrimary: r }) => t(i, r) : void 0,
498
+ maxPhpInstances: e.maxPhpInstances
481
499
  });
482
500
  return i;
483
501
  }
@@ -502,7 +520,7 @@ async function w(e) {
502
520
  }
503
521
  async function h(e) {
504
522
  var i;
505
- const n = await T(
523
+ const n = await R(
506
524
  e,
507
525
  {
508
526
  disable_functions: "fsockopen",
@@ -559,13 +577,13 @@ async function h(e) {
559
577
  }
560
578
  })).text !== "1" && g.warn("Failed to default to pretty permalinks after WP install.");
561
579
  }
562
- function C(e) {
580
+ function W(e) {
563
581
  return {
564
582
  type: "internal-redirect",
565
583
  uri: "/index.php"
566
584
  };
567
585
  }
568
- async function W(e) {
586
+ async function C(e) {
569
587
  return (await e.run({
570
588
  code: `<?php
571
589
  ob_start();
@@ -584,8 +602,8 @@ async function W(e) {
584
602
  }
585
603
  })).text === "1";
586
604
  }
587
- async function V(e) {
588
- const { php: n, reap: t } = await e.processManager.acquirePHPInstance({
605
+ async function j(e) {
606
+ const { php: n, reap: t } = await e.instanceManager.acquirePHPInstance({
589
607
  considerPrimary: !0
590
608
  });
591
609
  try {
@@ -604,7 +622,7 @@ async function V(e) {
604
622
  }
605
623
  function O(e) {
606
624
  if (/-(alpha|beta|RC)\d*-\d+$/.test(e))
607
- return "nightly";
625
+ return "trunk";
608
626
  if (/-(beta|RC)\d*$/.test(e))
609
627
  return "beta";
610
628
  const i = e.match(/^(\d+\.\d+)(?:\.\d+)?$/);
@@ -929,7 +947,7 @@ async function F(e, n = "/phpinfo.php") {
929
947
  async function N(e, n) {
930
948
  await e.isDir("/tmp/sqlite-database-integration") && await e.rmdir("/tmp/sqlite-database-integration", {
931
949
  recursive: !0
932
- }), await e.mkdir("/tmp/sqlite-database-integration"), await f(e, n, "/tmp/sqlite-database-integration");
950
+ }), await e.mkdir("/tmp/sqlite-database-integration"), await c(e, n, "/tmp/sqlite-database-integration");
933
951
  const t = "/internal/shared/sqlite-database-integration", i = `/tmp/sqlite-database-integration/${(await e.listFiles("/tmp/sqlite-database-integration"))[0]}`;
934
952
  await e.mv(i, t), await e.defineConstant("SQLITE_MAIN_FILE", "1");
935
953
  const a = (await e.readFileAsText(
@@ -1036,7 +1054,7 @@ if(!function_exists('mysqli_connect')) {
1036
1054
  );
1037
1055
  }
1038
1056
  async function q(e, n) {
1039
- e.mkdir("/tmp/unzipped-wordpress"), await f(e, n, "/tmp/unzipped-wordpress"), e.fileExists("/tmp/unzipped-wordpress/wordpress.zip") && await f(
1057
+ e.mkdir("/tmp/unzipped-wordpress"), await c(e, n, "/tmp/unzipped-wordpress"), e.fileExists("/tmp/unzipped-wordpress/wordpress.zip") && await c(
1040
1058
  e,
1041
1059
  "/tmp/unzipped-wordpress/wordpress.zip",
1042
1060
  "/tmp/unzipped-wordpress"
@@ -1078,8 +1096,8 @@ async function q(e, n) {
1078
1096
  )
1079
1097
  );
1080
1098
  }
1081
- const G = k(fetch);
1082
- async function j(e = "latest") {
1099
+ const G = P(fetch), M = "https://github.com/WordPress/WordPress/archive/refs/heads/master.zip";
1100
+ async function Z(e = "latest") {
1083
1101
  if (e === null)
1084
1102
  e = "latest";
1085
1103
  else if (e.startsWith("https://") || e.startsWith("http://")) {
@@ -1092,12 +1110,14 @@ async function j(e = "latest") {
1092
1110
  version: "custom-" + r.substring(0, 8),
1093
1111
  source: "inferred"
1094
1112
  };
1095
- } else if (e === "trunk" || e === "nightly")
1113
+ } else if (e === "trunk" || e === "nightly") {
1114
+ const i = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1096
1115
  return {
1097
- releaseUrl: "https://wordpress.org/nightly-builds/wordpress-latest.zip",
1098
- version: "nightly-" + (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
1116
+ releaseUrl: `${M}?ts=${i}`,
1117
+ version: "trunk",
1099
1118
  source: "inferred"
1100
1119
  };
1120
+ }
1101
1121
  let t = await (await G(
1102
1122
  "https://api.wordpress.org/core/version-check/1.7/?channel=beta"
1103
1123
  )).json();
@@ -1132,15 +1152,15 @@ async function j(e = "latest") {
1132
1152
  }
1133
1153
  export {
1134
1154
  U as bootRequestHandler,
1135
- I as bootWordPress,
1136
- Q as bootWordPressAndRequestHandler,
1155
+ L as bootWordPress,
1156
+ V as bootWordPressAndRequestHandler,
1137
1157
  x as defineWpConfigConstants,
1138
- L as ensureWpConfig,
1139
- C as getFileNotFoundActionForWordPress,
1140
- V as getLoadedWordPressVersion,
1158
+ I as ensureWpConfig,
1159
+ W as getFileNotFoundActionForWordPress,
1160
+ j as getLoadedWordPressVersion,
1141
1161
  F as preloadPhpInfoRoute,
1142
1162
  N as preloadSqliteIntegration,
1143
- j as resolveWordPressRelease,
1163
+ Z as resolveWordPressRelease,
1144
1164
  A as setupPlatformLevelMuPlugins,
1145
1165
  q as unzipWordPress,
1146
1166
  O as versionStringToLoadedWordPressVersion,
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wp-playground/wordpress",
3
- "version": "3.0.22",
3
+ "version": "3.0.31",
4
4
  "description": "WordPress-related plumbing for WordPress Playground",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,18 +35,18 @@
35
35
  "access": "public",
36
36
  "directory": "../../../dist/packages/playground/wordpress"
37
37
  },
38
- "gitHead": "a624d1a97dc639e152d335e6a801b2fad7f6b594",
38
+ "gitHead": "e28b6d2a2e663abc3cbb8fce9a3c5cc8abaa5bbe",
39
39
  "dependencies": {
40
40
  "express": "4.21.2",
41
41
  "ini": "4.1.2",
42
42
  "wasm-feature-detect": "1.8.0",
43
43
  "ws": "8.18.3",
44
44
  "yargs": "17.7.2",
45
- "@php-wasm/universal": "3.0.22",
46
- "@php-wasm/util": "3.0.22",
47
- "@php-wasm/logger": "3.0.22",
48
- "@wp-playground/common": "3.0.22",
49
- "@php-wasm/node": "3.0.22"
45
+ "@php-wasm/universal": "3.0.31",
46
+ "@php-wasm/util": "3.0.31",
47
+ "@php-wasm/logger": "3.0.31",
48
+ "@wp-playground/common": "3.0.31",
49
+ "@php-wasm/node": "3.0.31"
50
50
  },
51
51
  "packageManager": "npm@10.9.2",
52
52
  "overrides": {
@@ -54,8 +54,8 @@
54
54
  "react": "18.3.1",
55
55
  "react-dom": "18.3.1",
56
56
  "typescript": "5.4.5",
57
- "@playwright/test": "1.47.1",
58
- "ws": "^8.18.0",
57
+ "@playwright/test": "1.55.1",
58
+ "ws": "8.18.3",
59
59
  "tmp": "0.2.5",
60
60
  "form-data": "^4.0.4"
61
61
  },