@wp-playground/blueprints 0.9.14 → 0.9.15
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 +41 -61
- package/index.js +398 -1256
- package/package.json +2 -2
package/index.cjs
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("
|
|
2
|
-
`):JSON.stringify(e,null,2),ce=[],X=e=>{ce.push(e)},B=e=>{if(e.raw===!0)X(e.message);else{const t=Ve(typeof e.message=="object"?ze(e.message):e.message,e.severity??"Info",e.prefix??"JavaScript");X(t)}};class He extends EventTarget{constructor(t=[]){super(),this.handlers=t,this.fatalErrorEvent="playground-fatal-error"}getLogs(){return this.handlers.includes(B)?[...ce]:(this.error(`Logs aren't stored because the logToMemory handler isn't registered.
|
|
3
|
-
If you're using a custom logger instance, make sure to register logToMemory handler.
|
|
4
|
-
`),[])}logMessage(t,...n){for(const r of this.handlers)r(t,...n)}log(t,...n){this.logMessage({message:t,severity:void 0,prefix:"JavaScript",raw:!1},...n)}debug(t,...n){this.logMessage({message:t,severity:"Debug",prefix:"JavaScript",raw:!1},...n)}info(t,...n){this.logMessage({message:t,severity:"Info",prefix:"JavaScript",raw:!1},...n)}warn(t,...n){this.logMessage({message:t,severity:"Warn",prefix:"JavaScript",raw:!1},...n)}error(t,...n){this.logMessage({message:t,severity:"Error",prefix:"JavaScript",raw:!1},...n)}}const Ge=()=>{try{if(process.env.NODE_ENV==="test")return[B,K]}catch{}return[B,Me,K]},g=new He(Ge()),D=e=>e.replace(/\t/g,""),Ve=(e,t,n)=>{const r=new Date,i=new Intl.DateTimeFormat("en-GB",{year:"numeric",month:"short",day:"2-digit",timeZone:"UTC"}).format(r).replace(/ /g,"-"),s=new Intl.DateTimeFormat("en-GB",{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZone:"UTC",timeZoneName:"short"}).format(r),o=i+" "+s;return e=D(e),`[${o}] ${n} ${t}: ${e}`},q=async(e,{pluginPath:t,pluginName:n},r)=>{r==null||r.tracker.setCaption(`Activating ${n||t}`);const i=await e.documentRoot,s=await e.run({code:`<?php
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("@php-wasm/node-polyfills");const o=require("@php-wasm/util"),g=require("@php-wasm/logger"),N=require("@php-wasm/scopes"),he=require("@wp-playground/common"),z=require("@php-wasm/progress"),P=require("@php-wasm/universal"),fe=require("/home/runner/work/wordpress-playground/wordpress-playground/node_modules/ajv/dist/ajv.js"),j=["db.php","plugins/akismet","plugins/hello.php","plugins/wordpress-importer","mu-plugins/sqlite-database-integration","mu-plugins/playground-includes","mu-plugins/0-playground.php","mu-plugins/0-sqlite.php","themes/twentytwenty","themes/twentytwentyone","themes/twentytwentytwo","themes/twentytwentythree","themes/twentytwentyfour","themes/twentytwentyfive","themes/twentytwentysix"],R=async(e,{pluginPath:t,pluginName:n},i)=>{i==null||i.tracker.setCaption(`Activating ${n||t}`);const r=await e.documentRoot,s=await e.run({code:`<?php
|
|
5
2
|
define( 'WP_ADMIN', true );
|
|
6
|
-
require_once( ${
|
|
7
|
-
require_once( ${
|
|
3
|
+
require_once( ${o.phpVar(r)}. "/wp-load.php" );
|
|
4
|
+
require_once( ${o.phpVar(r)}. "/wp-admin/includes/plugin.php" );
|
|
8
5
|
|
|
9
6
|
// Set current user to admin
|
|
10
7
|
wp_set_current_user( get_users(array('role' => 'Administrator') )[0]->ID );
|
|
11
8
|
|
|
12
|
-
$plugin_path = ${
|
|
9
|
+
$plugin_path = ${o.phpVar(t)};
|
|
13
10
|
$response = false;
|
|
14
11
|
if (!is_dir($plugin_path)) {
|
|
15
12
|
$response = activate_plugin($plugin_path);
|
|
@@ -33,9 +30,9 @@
|
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
throw new Exception( 'Unable to activate plugin' );
|
|
36
|
-
`});if(s.text!=="Plugin activated successfully")throw g.debug(s),new Error(`Plugin ${t} could not be activated – WordPress exited with no error. Sometimes, when $_SERVER or site options are not configured correctly, WordPress exits early with a 301 redirect. Inspect the "debug" logs in the console for more details`)},
|
|
33
|
+
`});if(s.text!=="Plugin activated successfully")throw g.logger.debug(s),new Error(`Plugin ${t} could not be activated – WordPress exited with no error. Sometimes, when $_SERVER or site options are not configured correctly, WordPress exits early with a 301 redirect. Inspect the "debug" logs in the console for more details`)},L=async(e,{themeFolderName:t},n)=>{n==null||n.tracker.setCaption(`Activating ${t}`);const i=await e.documentRoot,r=`${i}/wp-content/themes/${t}`;if(!await e.fileExists(r))throw new Error(`
|
|
37
34
|
Couldn't activate theme ${t}.
|
|
38
|
-
Theme not found at the provided theme path: ${
|
|
35
|
+
Theme not found at the provided theme path: ${r}.
|
|
39
36
|
Check the theme path to ensure it's correct.
|
|
40
37
|
If the theme is not installed, you can install it using the installTheme step.
|
|
41
38
|
More info can be found in the Blueprint documentation: https://wordpress.github.io/wordpress-playground/blueprints-api/steps/#ActivateThemeStep
|
|
@@ -52,7 +49,7 @@
|
|
|
52
49
|
throw new Exception( 'Theme ' . getenv('themeFolderName') . ' could not be activated.' );
|
|
53
50
|
}
|
|
54
51
|
die('Theme activated successfully');
|
|
55
|
-
`,env:{docroot:
|
|
52
|
+
`,env:{docroot:i,themeFolderName:t}});if(s.text!=="Theme activated successfully")throw g.logger.debug(s),new Error(`Theme ${t} could not be activated – WordPress exited with no error. Sometimes, when $_SERVER or site options are not configured correctly, WordPress exits early with a 301 redirect. Inspect the "debug" logs in the console for more details`)},G=async(e,{code:t})=>await e.run({code:t}),V=async(e,{options:t})=>await e.run(t),q=async(e,{path:t})=>{await e.unlink(t)},Q=async(e,{sql:t},n)=>{n==null||n.tracker.setCaption("Executing SQL Queries");const i=`/tmp/${o.randomFilename()}.sql`;await e.writeFile(i,new Uint8Array(await t.arrayBuffer()));const r=await e.documentRoot,s=o.phpVars({docroot:r,sqlFilename:i}),a=await e.run({code:`<?php
|
|
56
53
|
require_once ${s.docroot} . '/wp-load.php';
|
|
57
54
|
|
|
58
55
|
$handle = fopen(${s.sqlFilename}, 'r');
|
|
@@ -71,7 +68,7 @@
|
|
|
71
68
|
$wpdb->query($buffer);
|
|
72
69
|
$buffer = '';
|
|
73
70
|
}
|
|
74
|
-
`});return await
|
|
71
|
+
`});return await q(e,{path:i}),a},k=async(e,{request:t})=>{g.logger.warn('Deprecated: The Blueprint step "request" is deprecated and will be removed in a future release.');const n=await e.request(t);if(n.httpStatusCode>399||n.httpStatusCode<200)throw g.logger.warn("WordPress response was",{response:n}),new Error(`Request failed with status ${n.httpStatusCode}`);return n},me=`<?php
|
|
75
72
|
|
|
76
73
|
/**
|
|
77
74
|
* Rewrites the wp-config.php file to ensure specific constants are defined
|
|
@@ -402,33 +399,33 @@ function skip_whitespace($tokens) {
|
|
|
402
399
|
}
|
|
403
400
|
return $output;
|
|
404
401
|
}
|
|
405
|
-
`,
|
|
402
|
+
`,b=async(e,{consts:t,method:n="define-before-run"})=>{switch(n){case"define-before-run":await we(e,t);break;case"rewrite-wp-config":{const i=await e.documentRoot,r=o.joinPaths(i,"/wp-config.php"),s=await e.readFileAsText(r),a=await ge(e,s,t);await e.writeFile(r,a);break}default:throw new Error(`Invalid method: ${n}`)}};async function we(e,t){for(const n in t)await e.defineConstant(n,t[n])}async function ge(e,t,n){await e.writeFile("/tmp/code.php",t);const i=o.phpVars({consts:n});return await e.run({code:`${me}
|
|
406
403
|
$wp_config_path = '/tmp/code.php';
|
|
407
404
|
$wp_config = file_get_contents($wp_config_path);
|
|
408
|
-
$new_wp_config = rewrite_wp_config_to_define_constants($wp_config, ${
|
|
405
|
+
$new_wp_config = rewrite_wp_config_to_define_constants($wp_config, ${i.consts});
|
|
409
406
|
file_put_contents($wp_config_path, $new_wp_config);
|
|
410
|
-
`}),await e.readFileAsText("/tmp/code.php")}const
|
|
411
|
-
include ${
|
|
412
|
-
$site_options = ${
|
|
407
|
+
`}),await e.readFileAsText("/tmp/code.php")}const v=async(e,{username:t="admin",password:n="password"}={},i)=>{var s,a,d;i==null||i.tracker.setCaption((i==null?void 0:i.initialCaption)||"Logging in"),await e.request({url:"/wp-login.php"});const r=await e.request({url:"/wp-login.php",method:"POST",body:{log:t,pwd:n,rememberme:"forever"}});if(!((d=(a=(s=r.headers)==null?void 0:s.location)==null?void 0:a[0])!=null&&d.includes("/wp-admin/")))throw g.logger.warn("WordPress response was",{response:r,text:r.text}),new Error(`Failed to log in as ${t} with password ${n}`)},O=async(e,{options:t})=>{const n=await e.documentRoot;await e.run({code:`<?php
|
|
408
|
+
include ${o.phpVar(n)} . '/wp-load.php';
|
|
409
|
+
$site_options = ${o.phpVar(t)};
|
|
413
410
|
foreach($site_options as $name => $value) {
|
|
414
411
|
update_option($name, $value);
|
|
415
412
|
}
|
|
416
413
|
echo "Success";
|
|
417
|
-
`})},
|
|
418
|
-
include ${
|
|
419
|
-
$meta = ${
|
|
414
|
+
`})},Y=async(e,{meta:t,userId:n})=>{const i=await e.documentRoot;await e.run({code:`<?php
|
|
415
|
+
include ${o.phpVar(i)} . '/wp-load.php';
|
|
416
|
+
$meta = ${o.phpVar(t)};
|
|
420
417
|
foreach($meta as $name => $value) {
|
|
421
|
-
update_user_meta(${
|
|
418
|
+
update_user_meta(${o.phpVar(n)}, $name, $value);
|
|
422
419
|
}
|
|
423
|
-
`})}
|
|
420
|
+
`})},Z=async e=>{var u;await b(e,{consts:{WP_ALLOW_MULTISITE:1}});const t=new URL(await e.absoluteUrl);if(t.port!==""){let m=`The current host is ${t.host}, but WordPress multisites do not support custom ports.`;throw t.hostname==="localhost"&&(m+=" For development, you can set up a playground.test domain using the instructions at https://wordpress.github.io/wordpress-playground/contributing/code."),new Error(m)}const n=t.pathname.replace(/\/$/,"")+"/",i=`${t.protocol}//${t.hostname}${n}`;await O(e,{options:{siteurl:i,home:i}}),await v(e,{});const r=await e.documentRoot,a=(await e.run({code:`<?php
|
|
424
421
|
define( 'WP_ADMIN', true );
|
|
425
|
-
require_once(${
|
|
422
|
+
require_once(${o.phpVar(r)} . "/wp-load.php");
|
|
426
423
|
|
|
427
424
|
// Set current user to admin
|
|
428
425
|
( get_users(array('role' => 'Administrator') )[0] );
|
|
429
426
|
|
|
430
|
-
require_once(${
|
|
431
|
-
$plugins_root = ${
|
|
427
|
+
require_once(${o.phpVar(r)} . "/wp-admin/includes/plugin.php");
|
|
428
|
+
$plugins_root = ${o.phpVar(r)} . "/wp-content/plugins";
|
|
432
429
|
$plugins = glob($plugins_root . "/*");
|
|
433
430
|
|
|
434
431
|
$deactivated_plugins = [];
|
|
@@ -452,9 +449,9 @@ foreach($plugins as $plugin_path) {
|
|
|
452
449
|
}
|
|
453
450
|
}
|
|
454
451
|
echo json_encode($deactivated_plugins);
|
|
455
|
-
`})).json,p=(
|
|
456
|
-
$_SERVER['HTTP_HOST'] = ${
|
|
457
|
-
$folder = ${
|
|
452
|
+
`})).json,p=(u=(await k(e,{request:{url:"/wp-admin/network.php"}})).text.match(/name="_wpnonce"\s+value="([^"]+)"/))==null?void 0:u[1],h=await k(e,{request:{url:"/wp-admin/network.php",method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:ye({_wpnonce:p,_wp_http_referer:n+"wp-admin/network.php",sitename:"My WordPress Website Sites",email:"admin@localhost.com",submit:"Install"})}});if(h.httpStatusCode!==200)throw g.logger.warn("WordPress response was",{response:h,text:h.text,headers:h.headers}),new Error(`Failed to enable multisite. Response code was ${h.httpStatusCode}`);await b(e,{consts:{MULTISITE:!0,SUBDOMAIN_INSTALL:!1,SITE_ID_CURRENT_SITE:1,BLOG_ID_CURRENT_SITE:1,DOMAIN_CURRENT_SITE:t.hostname,PATH_CURRENT_SITE:n}});const f=new URL(await e.absoluteUrl),l=N.isURLScoped(f)?"scope:"+N.getURLScope(f):null;await e.writeFile("/internal/shared/preload/sunrise.php",`<?php
|
|
453
|
+
$_SERVER['HTTP_HOST'] = ${o.phpVar(f.hostname)};
|
|
454
|
+
$folder = ${o.phpVar(l)};
|
|
458
455
|
if ($folder && strpos($_SERVER['REQUEST_URI'],"/$folder") === false) {
|
|
459
456
|
$_SERVER['REQUEST_URI'] = "/$folder/" . ltrim($_SERVER['REQUEST_URI'], '/');
|
|
460
457
|
}
|
|
@@ -462,9 +459,9 @@ echo json_encode($deactivated_plugins);
|
|
|
462
459
|
if ( !defined( 'BLOG_ID_CURRENT_SITE' ) ) {
|
|
463
460
|
define( 'BLOG_ID_CURRENT_SITE', 1 );
|
|
464
461
|
}
|
|
465
|
-
`),await
|
|
466
|
-
require ${
|
|
467
|
-
require ${
|
|
462
|
+
`),await v(e,{});for(const m of a)await R(e,{pluginPath:m})};function ye(e){return Object.keys(e).map(t=>encodeURIComponent(t)+"="+encodeURIComponent(e[t])).join("&")}const X=async(e,{fromPath:t,toPath:n})=>{await e.writeFile(n,await e.readFileAsBuffer(t))},J=async(e,{fromPath:t,toPath:n})=>{await e.mv(t,n)},K=async(e,{path:t})=>{await e.mkdir(t)},ee=async(e,{path:t})=>{await e.rmdir(t)},C=async(e,{path:t,data:n})=>{n instanceof File&&(n=new Uint8Array(await n.arrayBuffer())),t.startsWith("/wordpress/wp-content/mu-plugins")&&!await e.fileExists("/wordpress/wp-content/mu-plugins")&&await e.mkdir("/wordpress/wp-content/mu-plugins"),await e.writeFile(t,n)},W=async(e,{siteUrl:t})=>{await b(e,{consts:{WP_HOME:t,WP_SITEURL:t}})},te=async(e,{file:t},n)=>{var r;(r=n==null?void 0:n.tracker)==null||r.setCaption("Importing content"),await C(e,{path:"/tmp/import.wxr",data:t});const i=await e.documentRoot;await e.run({code:`<?php
|
|
463
|
+
require ${o.phpVar(i)} . '/wp-load.php';
|
|
464
|
+
require ${o.phpVar(i)} . '/wp-admin/includes/admin.php';
|
|
468
465
|
|
|
469
466
|
kses_remove_filters();
|
|
470
467
|
$admin_id = get_users(array('role' => 'Administrator') )[0]->ID;
|
|
@@ -482,27 +479,10 @@ echo json_encode($deactivated_plugins);
|
|
|
482
479
|
});
|
|
483
480
|
|
|
484
481
|
$result = $importer->import( '/tmp/import.wxr' );
|
|
485
|
-
`})},
|
|
486
|
-
function unzip($zipPath, $extractTo, $overwrite = true)
|
|
487
|
-
{
|
|
488
|
-
if (!is_dir($extractTo)) {
|
|
489
|
-
mkdir($extractTo, 0777, true);
|
|
490
|
-
}
|
|
491
|
-
$zip = new ZipArchive;
|
|
492
|
-
$res = $zip->open($zipPath);
|
|
493
|
-
if ($res === TRUE) {
|
|
494
|
-
$zip->extractTo($extractTo);
|
|
495
|
-
$zip->close();
|
|
496
|
-
chmod($extractTo, 0777);
|
|
497
|
-
} else {
|
|
498
|
-
throw new Exception("Could not unzip file");
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
unzip(${r.zipPath}, ${r.extractToPath});
|
|
502
|
-
`}),await e.fileExists(F)&&await e.unlink(F)},I=async(e,{zipFile:t,zipPath:n,extractToPath:r})=>{if(n)g.warn('The "zipPath" option of the unzip() Blueprint step is deprecated and will be removed. Use "zipFile" instead.');else if(!t)throw new Error("Either zipPath or zipFile must be provided");await Xe(e,t||n,r)},_e=async(e,{wordPressFilesZip:t,pathInZip:n=""})=>{const r=await e.documentRoot;let i=f("/tmp","import");await e.mkdir(i),await I(e,{zipFile:t,extractToPath:i}),i=f(i,n);const s=f(i,"wp-content"),o=f(r,"wp-content");for(const u of N){const d=f(s,u);await ee(e,d);const h=f(o,u);await e.fileExists(h)&&(await e.mkdir(oe(d)),await e.mv(h,d))}const a=f(i,"wp-content","database");await e.fileExists(a)||await e.mv(f(r,"wp-content","database"),a);const p=await e.listFiles(i);for(const u of p)await ee(e,f(r,u)),await e.mv(f(i,u),f(r,u));await e.rmdir(i),await H(e,{siteUrl:await e.absoluteUrl});const l=m(f(r,"wp-admin","upgrade.php"));await e.run({code:`<?php
|
|
482
|
+
`})},S=async(e,{zipFile:t,zipPath:n,extractToPath:i})=>{if(n)g.logger.warn('The "zipPath" option of the unzip() Blueprint step is deprecated and will be removed. Use "zipFile" instead.');else if(!t)throw new Error("Either zipPath or zipFile must be provided");await he.unzipFile(e,t||n,i)},ne=async(e,{wordPressFilesZip:t,pathInZip:n=""})=>{const i=await e.documentRoot;let r=o.joinPaths("/tmp","import");await e.mkdir(r),await S(e,{zipFile:t,extractToPath:r}),r=o.joinPaths(r,n);const s=o.joinPaths(r,"wp-content"),a=o.joinPaths(i,"wp-content");for(const f of j){const l=o.joinPaths(s,f);await D(e,l);const u=o.joinPaths(a,f);await e.fileExists(u)&&(await e.mkdir(o.dirname(l)),await e.mv(u,l))}const d=o.joinPaths(r,"wp-content","database");await e.fileExists(d)||await e.mv(o.joinPaths(i,"wp-content","database"),d);const p=await e.listFiles(r);for(const f of p)await D(e,o.joinPaths(i,f)),await e.mv(o.joinPaths(r,f),o.joinPaths(i,f));await e.rmdir(r),await W(e,{siteUrl:await e.absoluteUrl});const h=o.phpVar(o.joinPaths(i,"wp-admin","upgrade.php"));await e.run({code:`<?php
|
|
503
483
|
$_GET['step'] = 'upgrade_db';
|
|
504
|
-
require ${
|
|
505
|
-
`})};async function
|
|
484
|
+
require ${h};
|
|
485
|
+
`})};async function D(e,t){await e.fileExists(t)&&(await e.isDir(t)?await e.rmdir(t):await e.unlink(t))}async function ie(e){const t=await e.request({url:"/wp-admin/export.php?download=true&content=all"});return new File([t.bytes],"export.xml")}async function re(e,{targetPath:t,zipFile:n,ifAlreadyInstalled:i="overwrite"}){const s=n.name.replace(/\.zip$/,""),a=o.joinPaths(await e.documentRoot,"wp-content"),d=o.joinPaths(a,o.randomString()),p=o.joinPaths(d,"assets",s);await e.fileExists(p)&&await e.rmdir(d,{recursive:!0}),await e.mkdir(d);try{await S(e,{zipFile:n,extractToPath:p});let h=await e.listFiles(p,{prependPath:!0});h=h.filter(E=>!E.endsWith("/__MACOSX"));const f=h.length===1&&await e.isDir(h[0]);let l,u="";f?(u=h[0],l=h[0].split("/").pop()):(u=p,l=s);const m=`${t}/${l}`;if(await e.fileExists(m)){if(!await e.isDir(m))throw new Error(`Cannot install asset ${l} to ${m} because a file with the same name already exists. Note it's a file, not a directory! Is this by mistake?`);if(i==="overwrite")await e.rmdir(m,{recursive:!0});else{if(i==="skip")return{assetFolderPath:m,assetFolderName:l};throw new Error(`Cannot install asset ${l} to ${t} because it already exists and the ifAlreadyInstalled option was set to ${i}`)}}return await e.mv(u,m),{assetFolderPath:m,assetFolderName:l}}finally{await e.rmdir(d,{recursive:!0})}}function x(e){const t=e.split(".").shift().replace(/-/g," ");return t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()}const se=async(e,{pluginZipFile:t,ifAlreadyInstalled:n,options:i={}},r)=>{const s=t.name.split("/").pop()||"plugin.zip",a=x(s);r==null||r.tracker.setCaption(`Installing the ${a} plugin`);const{assetFolderPath:d}=await re(e,{ifAlreadyInstalled:n,zipFile:t,targetPath:`${await e.documentRoot}/wp-content/plugins`});("activate"in i?i.activate:!0)&&await R(e,{pluginPath:d,pluginName:a},r)},oe=async(e,{themeZipFile:t,ifAlreadyInstalled:n,options:i={}},r)=>{const s=x(t.name);r==null||r.tracker.setCaption(`Installing the ${s} theme`);const{assetFolderName:a}=await re(e,{ifAlreadyInstalled:n,zipFile:t,targetPath:`${await e.documentRoot}/wp-content/themes`});("activate"in i?i.activate:!0)&&await L(e,{themeFolderName:a},r)},ae=async(e,t,n)=>{var r;(r=n==null?void 0:n.tracker)==null||r.setCaption("Resetting WordPress data");const i=await e.documentRoot;await e.run({env:{DOCROOT:i},code:`<?php
|
|
506
486
|
require getenv('DOCROOT') . '/wp-load.php';
|
|
507
487
|
|
|
508
488
|
$GLOBALS['@pdo']->query('DELETE FROM wp_posts WHERE id > 0');
|
|
@@ -516,11 +496,11 @@ echo json_encode($deactivated_plugins);
|
|
|
516
496
|
|
|
517
497
|
$GLOBALS['@pdo']->query('DELETE FROM wp_commentmeta');
|
|
518
498
|
$GLOBALS['@pdo']->query("UPDATE SQLITE_SEQUENCE SET SEQ=0 WHERE NAME='wp_commentmeta'");
|
|
519
|
-
`})},
|
|
520
|
-
'exclude_paths' => ${
|
|
521
|
-
'zip_root' => ${
|
|
522
|
-
'additional_paths' => ${
|
|
523
|
-
));`);const
|
|
499
|
+
`})},pe=async(e,{options:t})=>{await e.request({url:"/wp-admin/install.php?step=2",method:"POST",body:{language:"en",prefix:"wp_",weblog_title:"My WordPress Website",user_name:t.adminPassword||"admin",admin_password:t.adminPassword||"password",admin_password2:t.adminPassword||"password",Submit:"Install WordPress",pw_weak:"1",admin_email:"admin@localhost.com"}})},ce=async(e,{selfContained:t=!1}={})=>{const n="/tmp/wordpress-playground.zip",i=await e.documentRoot,r=o.joinPaths(i,"wp-content");let s=j;t&&(s=s.filter(p=>!p.startsWith("themes/twenty")).filter(p=>p!=="mu-plugins/sqlite-database-integration"));const a=o.phpVars({zipPath:n,wpContentPath:r,documentRoot:i,exceptPaths:s.map(p=>o.joinPaths(i,"wp-content",p)),additionalPaths:t?{[o.joinPaths(i,"wp-config.php")]:"wp-config.php"}:{}});await _e(e,`zipDir(${a.wpContentPath}, ${a.zipPath}, array(
|
|
500
|
+
'exclude_paths' => ${a.exceptPaths},
|
|
501
|
+
'zip_root' => ${a.documentRoot},
|
|
502
|
+
'additional_paths' => ${a.additionalPaths}
|
|
503
|
+
));`);const d=await e.readFileAsBuffer(n);return e.unlink(n),d},$e=`<?php
|
|
524
504
|
|
|
525
505
|
function zipDir($root, $output, $options = array())
|
|
526
506
|
{
|
|
@@ -579,7 +559,7 @@ function join_paths()
|
|
|
579
559
|
|
|
580
560
|
return preg_replace('#/+#', '/', join('/', $paths));
|
|
581
561
|
}
|
|
582
|
-
`;async function
|
|
562
|
+
`;async function _e(e,t){return await e.run({code:$e+t})}const de=async(e,{command:t,wpCliPath:n="/tmp/wp-cli.phar"})=>{if(!await e.fileExists(n))throw new Error(`wp-cli.phar not found at ${n}`);let i;if(typeof t=="string"?(t=t.trim(),i=Pe(t)):i=t,i.shift()!=="wp")throw new Error('The first argument must be "wp".');await e.writeFile("/tmp/stdout",""),await e.writeFile("/tmp/stderr",""),await e.writeFile("/wordpress/run-cli.php",`<?php
|
|
583
563
|
// Set up the environment to emulate a shell script
|
|
584
564
|
// call.
|
|
585
565
|
|
|
@@ -592,7 +572,7 @@ function join_paths()
|
|
|
592
572
|
$GLOBALS['argv'] = array_merge([
|
|
593
573
|
"/tmp/wp-cli.phar",
|
|
594
574
|
"--path=/wordpress"
|
|
595
|
-
], ${
|
|
575
|
+
], ${o.phpVar(i)});
|
|
596
576
|
|
|
597
577
|
// Provide stdin, stdout, stderr streams outside of
|
|
598
578
|
// the CLI SAPI.
|
|
@@ -600,8 +580,8 @@ function join_paths()
|
|
|
600
580
|
define('STDOUT', fopen('php://stdout', 'wb'));
|
|
601
581
|
define('STDERR', fopen('php://stderr', 'wb'));
|
|
602
582
|
|
|
603
|
-
require( ${
|
|
604
|
-
`);const s=await e.run({scriptPath:"/wordpress/run-cli.php"});if(s.errors)throw new Error(s.errors);return s};function nt(e){let r=0,i="";const s=[];let o="";for(let a=0;a<e.length;a++){const p=e[a];r===0?p==='"'||p==="'"?(r=1,i=p):p.match(/\s/)?(o&&s.push(o),o=""):o+=p:r===1&&(p==="\\"?(a++,o+=e[a]):p===i?(r=0,i=""):o+=p)}return o&&s.push(o),s}const rt=Object.freeze(Object.defineProperty({__proto__:null,activatePlugin:q,activateTheme:A,cp:ye,defineSiteUrl:H,defineWpConfigConsts:k,enableMultisite:me,exportWXR:Pe,importWordPressFiles:_e,importWxr:be,installPlugin:ve,installTheme:Te,login:L,mkdir:we,mv:ge,request:S,resetData:ke,rm:U,rmdir:$e,runPHP:le,runPHPWithOptions:de,runSql:ue,runWpInstallationWizard:Re,setSiteOptions:M,unzip:I,updateUserMeta:fe,wpCLI:Se,writeFile:z,zipWpContent:xe},Symbol.toStringTag,{value:"Module"})),it=5*1024*1024;function st(e,t){const n=e.headers.get("content-length")||"",r=parseInt(n,10)||it;function i(s,o){t(new CustomEvent("progress",{detail:{loaded:s,total:o}}))}return new Response(new ReadableStream({async start(s){if(!e.body){s.close();return}const o=e.body.getReader();let a=0;for(;;)try{const{done:p,value:l}=await o.read();if(l&&(a+=l.byteLength),p){i(a,a),s.close();break}else i(a,r),s.enqueue(l)}catch(p){g.error({e:p}),s.error(p);break}}}),{status:e.status,statusText:e.statusText,headers:e.headers})}const j=1e-5;class G extends EventTarget{constructor({weight:t=1,caption:n="",fillTime:r=4}={}){super(),this._selfWeight=1,this._selfDone=!1,this._selfProgress=0,this._selfCaption="",this._isFilling=!1,this._subTrackers=[],this._weight=t,this._selfCaption=n,this._fillTime=r}stage(t,n=""){if(t||(t=this._selfWeight),this._selfWeight-t<-j)throw new Error(`Cannot add a stage with weight ${t} as the total weight of registered stages would exceed 1.`);this._selfWeight-=t;const r=new G({caption:n,weight:t,fillTime:this._fillTime});return this._subTrackers.push(r),r.addEventListener("progress",()=>this.notifyProgress()),r.addEventListener("done",()=>{this.done&&this.notifyDone()}),r}fillSlowly({stopBeforeFinishing:t=!0}={}){if(this._isFilling)return;this._isFilling=!0;const n=100,r=this._fillTime/n;this._fillInterval=setInterval(()=>{this.set(this._selfProgress+1),t&&this._selfProgress>=99&&clearInterval(this._fillInterval)},r)}set(t){this._selfProgress=Math.min(t,100),this.notifyProgress(),this._selfProgress+j>=100&&this.finish()}finish(){this._fillInterval&&clearInterval(this._fillInterval),this._selfDone=!0,this._selfProgress=100,this._isFilling=!1,this._fillInterval=void 0,this.notifyProgress(),this.notifyDone()}get caption(){for(let t=this._subTrackers.length-1;t>=0;t--)if(!this._subTrackers[t].done){const n=this._subTrackers[t].caption;if(n)return n}return this._selfCaption}setCaption(t){this._selfCaption=t,this.notifyProgress()}get done(){return this.progress+j>=100}get progress(){if(this._selfDone)return 100;const t=this._subTrackers.reduce((n,r)=>n+r.progress*r.weight,this._selfProgress*this._selfWeight);return Math.round(t*1e4)/1e4}get weight(){return this._weight}get observer(){return this._progressObserver||(this._progressObserver=t=>{this.set(t)}),this._progressObserver}get loadingListener(){return this._loadingListener||(this._loadingListener=t=>{this.set(t.detail.loaded/t.detail.total*100)}),this._loadingListener}pipe(t){t.setProgress({progress:this.progress,caption:this.caption}),this.addEventListener("progress",n=>{t.setProgress({progress:n.detail.progress,caption:n.detail.caption})}),this.addEventListener("done",()=>{t.setLoaded()})}addEventListener(t,n){super.addEventListener(t,n)}removeEventListener(t,n){super.removeEventListener(t,n)}notifyProgress(){const t=this;this.dispatchEvent(new CustomEvent("progress",{detail:{get progress(){return t.progress},get caption(){return t.caption}}}))}notifyDone(){this.dispatchEvent(new CustomEvent("done"))}}const C={0:"No error occurred. System call completed successfully.",1:"Argument list too long.",2:"Permission denied.",3:"Address in use.",4:"Address not available.",5:"Address family not supported.",6:"Resource unavailable, or operation would block.",7:"Connection already in progress.",8:"Bad file descriptor.",9:"Bad message.",10:"Device or resource busy.",11:"Operation canceled.",12:"No child processes.",13:"Connection aborted.",14:"Connection refused.",15:"Connection reset.",16:"Resource deadlock would occur.",17:"Destination address required.",18:"Mathematics argument out of domain of function.",19:"Reserved.",20:"File exists.",21:"Bad address.",22:"File too large.",23:"Host is unreachable.",24:"Identifier removed.",25:"Illegal byte sequence.",26:"Operation in progress.",27:"Interrupted function.",28:"Invalid argument.",29:"I/O error.",30:"Socket is connected.",31:"There is a directory under that path.",32:"Too many levels of symbolic links.",33:"File descriptor value too large.",34:"Too many links.",35:"Message too large.",36:"Reserved.",37:"Filename too long.",38:"Network is down.",39:"Connection aborted by network.",40:"Network unreachable.",41:"Too many files open in system.",42:"No buffer space available.",43:"No such device.",44:"There is no such file or directory OR the parent directory does not exist.",45:"Executable file format error.",46:"No locks available.",47:"Reserved.",48:"Not enough space.",49:"No message of the desired type.",50:"Protocol not available.",51:"No space left on device.",52:"Function not supported.",53:"The socket is not connected.",54:"Not a directory or a symbolic link to a directory.",55:"Directory not empty.",56:"State not recoverable.",57:"Not a socket.",58:"Not supported, or operation not supported on socket.",59:"Inappropriate I/O control operation.",60:"No such device or address.",61:"Value too large to be stored in data type.",62:"Previous owner died.",63:"Operation not permitted.",64:"Broken pipe.",65:"Protocol error.",66:"Protocol not supported.",67:"Protocol wrong type for socket.",68:"Result too large.",69:"Read-only file system.",70:"Invalid seek.",71:"No such process.",72:"Reserved.",73:"Connection timed out.",74:"Text file busy.",75:"Cross-device link.",76:"Extension: Capabilities insufficient."};function ot(e){const t=typeof e=="object"?e==null?void 0:e.errno:null;if(t in C)return C[t]}function b(e=""){return function(n,r,i){const s=i.value;i.value=function(...o){try{return s.apply(this,o)}catch(a){const p=typeof a=="object"?a==null?void 0:a.errno:null;if(p in C){const l=C[p],u=typeof o[1]=="string"?o[1]:null,d=u!==null?e.replaceAll("{path}",u):e;throw new Error(`${d}: ${l}`,{cause:a})}throw a}}}}var at=Object.defineProperty,pt=Object.getOwnPropertyDescriptor,_=(e,t,n,r)=>{for(var i=r>1?void 0:r?pt(t,n):t,s=e.length-1,o;s>=0;s--)(o=e[s])&&(i=(r?o(t,n,i):o(i))||i);return r&&i&&at(t,n,i),i};const P=class ${static readFileAsText(t,n){return new TextDecoder().decode($.readFileAsBuffer(t,n))}static readFileAsBuffer(t,n){return t.readFile(n)}static writeFile(t,n,r){t.writeFile(n,r)}static unlink(t,n){t.unlink(n)}static mv(t,n,r){try{const i=t.lookupPath(n).node.mount,s=$.fileExists(t,r)?t.lookupPath(r).node.mount:t.lookupPath(oe(r)).node.mount;i.mountpoint!==s.mountpoint?($.copyRecursive(t,n,r),$.rmdir(t,n,{recursive:!0})):t.rename(n,r)}catch(i){const s=ot(i);throw s?new Error(`Could not move ${n} to ${r}: ${s}`,{cause:i}):i}}static rmdir(t,n,r={recursive:!0}){r!=null&&r.recursive&&$.listFiles(t,n).forEach(i=>{const s=`${n}/${i}`;$.isDir(t,s)?$.rmdir(t,s,r):$.unlink(t,s)}),t.rmdir(n)}static listFiles(t,n,r={prependPath:!1}){if(!$.fileExists(t,n))return[];try{const i=t.readdir(n).filter(s=>s!=="."&&s!=="..");if(r.prependPath){const s=n.replace(/\/$/,"");return i.map(o=>`${s}/${o}`)}return i}catch(i){return g.error(i,{path:n}),[]}}static isDir(t,n){return $.fileExists(t,n)?t.isDir(t.lookupPath(n).node.mode):!1}static fileExists(t,n){try{return t.lookupPath(n),!0}catch{return!1}}static mkdir(t,n){t.mkdirTree(n)}static copyRecursive(t,n,r){const i=t.lookupPath(n).node;if(t.isDir(i.mode)){t.mkdirTree(r);const s=t.readdir(n).filter(o=>o!=="."&&o!=="..");for(const o of s)$.copyRecursive(t,f(n,o),f(r,o))}else t.writeFile(r,t.readFile(n))}};_([b('Could not read "{path}"')],P,"readFileAsText",1);_([b('Could not read "{path}"')],P,"readFileAsBuffer",1);_([b('Could not write to "{path}"')],P,"writeFile",1);_([b('Could not unlink "{path}"')],P,"unlink",1);_([b('Could not remove directory "{path}"')],P,"rmdir",1);_([b('Could not list files in "{path}"')],P,"listFiles",1);_([b('Could not stat "{path}"')],P,"isDir",1);_([b('Could not stat "{path}"')],P,"fileExists",1);_([b('Could not create directory "{path}"')],P,"mkdir",1);_([b('Could not copy files from "{path}"')],P,"copyRecursive",1);(function(){var e;return typeof process<"u"&&((e=process.release)==null?void 0:e.name)==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"})();ReadableStream.prototype[Symbol.asyncIterator]||(ReadableStream.prototype[Symbol.asyncIterator]=async function*(){const e=this.getReader();try{for(;;){const{done:t,value:n}=await e.read();if(t)return;yield n}}finally{e.releaseLock()}},ReadableStream.prototype.iterate=ReadableStream.prototype[Symbol.asyncIterator]);const Le=["8.3","8.2","8.1","8.0","7.4","7.3","7.2","7.1","7.0"],ct=Le[0],Ce=["iconv","mbstring","xml-bundle","gd"],te={"kitchen-sink":Ce,light:[]},lt=["vfs","literal","wordpress.org/themes","wordpress.org/plugins","url"];function dt(e){return e&&typeof e=="object"&&typeof e.resource=="string"&<.includes(e.resource)}class T{static create(t,{semaphore:n,progress:r}){let i;switch(t.resource){case"vfs":i=new ut(t,r);break;case"literal":i=new ft(t,r);break;case"wordpress.org/themes":i=new yt(t,r);break;case"wordpress.org/plugins":i=new gt(t,r);break;case"url":i=new mt(t,r);break;default:throw new Error(`Invalid resource: ${t}`)}return i=new wt(i),n&&(i=new $t(i,n)),i}setPlayground(t){this.playground=t}get isAsync(){return!1}}class ut extends T{constructor(t,n){super(),this.resource=t,this.progress=n}async resolve(){var n;const t=await this.playground.readFileAsBuffer(this.resource.path);return(n=this.progress)==null||n.set(100),new File([t],this.name)}get name(){return this.resource.path.split("/").pop()||""}}class ft extends T{constructor(t,n){super(),this.resource=t,this.progress=n}async resolve(){var t;return(t=this.progress)==null||t.set(100),new File([this.resource.contents],this.resource.name)}get name(){return this.resource.name}}class V extends T{constructor(t){super(),this.progress=t}async resolve(){var n,r;(n=this.progress)==null||n.setCaption(this.caption);const t=this.getURL();try{let i=await fetch(t);if(!i.ok)throw new Error(`Could not download "${t}"`);if(i=await st(i,((r=this.progress)==null?void 0:r.loadingListener)??ht),i.status!==200)throw new Error(`Could not download "${t}"`);return new File([await i.blob()],this.name)}catch(i){throw new Error(`Could not download "${t}".
|
|
583
|
+
require( ${o.phpVar(n)} );
|
|
584
|
+
`);const s=await e.run({scriptPath:"/wordpress/run-cli.php"});if(s.errors)throw new Error(s.errors);return s};function Pe(e){let i=0,r="";const s=[];let a="";for(let d=0;d<e.length;d++){const p=e[d];i===0?p==='"'||p==="'"?(i=1,r=p):p.match(/\s/)?(a&&s.push(a),a=""):a+=p:i===1&&(p==="\\"?(d++,a+=e[d]):p===r?(i=0,r=""):a+=p)}return a&&s.push(a),s}const be=Object.freeze(Object.defineProperty({__proto__:null,activatePlugin:R,activateTheme:L,cp:X,defineSiteUrl:W,defineWpConfigConsts:b,enableMultisite:Z,exportWXR:ie,importWordPressFiles:ne,importWxr:te,installPlugin:se,installTheme:oe,login:v,mkdir:K,mv:J,request:k,resetData:ae,rm:q,rmdir:ee,runPHP:G,runPHPWithOptions:V,runSql:Q,runWpInstallationWizard:pe,setSiteOptions:O,unzip:S,updateUserMeta:Y,wpCLI:de,writeFile:C,zipWpContent:ce},Symbol.toStringTag,{value:"Module"})),Ee=["vfs","literal","wordpress.org/themes","wordpress.org/plugins","url"];function Te(e){return e&&typeof e=="object"&&typeof e.resource=="string"&&Ee.includes(e.resource)}class _{static create(t,{semaphore:n,progress:i}){let r;switch(t.resource){case"vfs":r=new ke(t,i);break;case"literal":r=new ve(t,i);break;case"wordpress.org/themes":r=new xe(t,i);break;case"wordpress.org/plugins":r=new je(t,i);break;case"url":r=new Se(t,i);break;default:throw new Error(`Invalid resource: ${t}`)}return r=new Le(r),n&&(r=new qe(r,n)),r}setPlayground(t){this.playground=t}get isAsync(){return!1}}class ke extends _{constructor(t,n){super(),this.resource=t,this.progress=n}async resolve(){var n;const t=await this.playground.readFileAsBuffer(this.resource.path);return(n=this.progress)==null||n.set(100),new File([t],this.name)}get name(){return this.resource.path.split("/").pop()||""}}class ve extends _{constructor(t,n){super(),this.resource=t,this.progress=n}async resolve(){var t;return(t=this.progress)==null||t.set(100),new File([this.resource.contents],this.resource.name)}get name(){return this.resource.name}}class U extends _{constructor(t){super(),this.progress=t}async resolve(){var n,i;(n=this.progress)==null||n.setCaption(this.caption);const t=this.getURL();try{let r=await fetch(t);if(!r.ok)throw new Error(`Could not download "${t}"`);if(r=await z.cloneResponseMonitorProgress(r,((i=this.progress)==null?void 0:i.loadingListener)??Re),r.status!==200)throw new Error(`Could not download "${t}"`);return new File([await r.blob()],this.name)}catch(r){throw new Error(`Could not download "${t}".
|
|
605
585
|
Check if the URL is correct and the server is reachable.
|
|
606
586
|
If it is reachable, the server might be blocking the request.
|
|
607
587
|
Check the browser console and network tabs for more information.
|
|
@@ -625,10 +605,10 @@ function join_paths()
|
|
|
625
605
|
https://raw.githubusercontent.com/username/repository/branch/filename
|
|
626
606
|
|
|
627
607
|
Error:
|
|
628
|
-
${
|
|
608
|
+
${r}`)}}get caption(){return`Downloading ${this.name}`}get name(){try{return new URL(this.getURL(),"http://example.com").pathname.split("/").pop()}catch{return this.getURL()}}get isAsync(){return!0}}const Re=()=>{};class Se extends U{constructor(t,n){super(n),this.resource=t}getURL(){return this.resource.url}get caption(){return this.resource.caption??super.caption}}class xe extends U{constructor(t,n){super(n),this.resource=t}get name(){return x(this.resource.slug)}getURL(){return`https://downloads.wordpress.org/theme/${le(this.resource.slug)}`}}class je extends U{constructor(t,n){super(n),this.resource=t}get name(){return x(this.resource.slug)}getURL(){return`https://downloads.wordpress.org/plugin/${le(this.resource.slug)}`}}function le(e){return!e||e.endsWith(".zip")?e:e+".latest-stable.zip"}class ue extends _{constructor(t){super(),this.resource=t}async resolve(){return this.resource.resolve()}async setPlayground(t){return this.resource.setPlayground(t)}get progress(){return this.resource.progress}set progress(t){this.resource.progress=t}get name(){return this.resource.name}get isAsync(){return this.resource.isAsync}}class Le extends ue{async resolve(){return this.promise||(this.promise=super.resolve()),this.promise}}class qe extends ue{constructor(t,n){super(t),this.semaphore=n}async resolve(){return this.isAsync?this.semaphore.run(()=>super.resolve()):super.resolve()}}const Oe="http://json-schema.org/schema",Ce="#/definitions/Blueprint",We={Blueprint:{type:"object",properties:{landingPage:{type:"string",description:"The URL to navigate to after the blueprint has been run."},description:{type:"string",description:"Optional description. It doesn't do anything but is exposed as a courtesy to developers who may want to document which blueprint file does what.",deprecated:"Use meta.description instead."},meta:{type:"object",properties:{title:{type:"string",description:"A clear and concise name for your Blueprint."},description:{type:"string",description:"A brief explanation of what your Blueprint offers."},author:{type:"string",description:"A GitHub username of the author of this Blueprint."},categories:{type:"array",items:{type:"string"},description:"Relevant categories to help users find your Blueprint in the future Blueprints section on WordPress.org."}},required:["title","author"],additionalProperties:!1,description:"Optional metadata. Used by the Blueprints gallery at https://github.com/WordPress/blueprints"},preferredVersions:{type:"object",properties:{php:{anyOf:[{$ref:"#/definitions/SupportedPHPVersion"},{type:"string",const:"latest"}],description:"The preferred PHP version to use. If not specified, the latest supported version will be used"},wp:{type:"string",description:"The preferred WordPress version to use. If not specified, the latest supported version will be used"}},required:["php","wp"],additionalProperties:!1,description:"The preferred PHP and WordPress versions to use."},features:{type:"object",properties:{networking:{type:"boolean",description:"Should boot with support for network request via wp_safe_remote_get?"}},additionalProperties:!1},constants:{type:"object",additionalProperties:{type:"string"},description:"PHP Constants to define on every request",deprecated:"This experimental option will change without warning.\nUse `steps` instead."},plugins:{type:"array",items:{anyOf:[{type:"string"},{$ref:"#/definitions/FileReference"}]},description:"WordPress plugins to install and activate",deprecated:"This experimental option will change without warning.\nUse `steps` instead."},siteOptions:{type:"object",additionalProperties:{type:"string"},properties:{blogname:{type:"string",description:"The site title"}},description:"WordPress site options to define",deprecated:"This experimental option will change without warning.\nUse `steps` instead."},login:{anyOf:[{type:"boolean"},{type:"object",properties:{username:{type:"string"},password:{type:"string"}},required:["username","password"],additionalProperties:!1}],description:"User to log in as. If true, logs the user in as admin/password."},phpExtensionBundles:{type:"array",items:{$ref:"#/definitions/SupportedPHPExtensionBundle"},description:"The PHP extensions to use."},steps:{type:"array",items:{anyOf:[{$ref:"#/definitions/StepDefinition"},{type:"string"},{not:{}},{type:"boolean",const:!1},{type:"null"}]},description:"The steps to run after every other operation in this Blueprint was executed."},$schema:{type:"string"}},additionalProperties:!1},SupportedPHPVersion:{type:"string",enum:["8.3","8.2","8.1","8.0","7.4","7.3","7.2","7.1","7.0"]},FileReference:{anyOf:[{$ref:"#/definitions/VFSReference"},{$ref:"#/definitions/LiteralReference"},{$ref:"#/definitions/CoreThemeReference"},{$ref:"#/definitions/CorePluginReference"},{$ref:"#/definitions/UrlReference"}]},VFSReference:{type:"object",properties:{resource:{type:"string",const:"vfs",description:"Identifies the file resource as Virtual File System (VFS)"},path:{type:"string",description:"The path to the file in the VFS"}},required:["resource","path"],additionalProperties:!1},LiteralReference:{type:"object",properties:{resource:{type:"string",const:"literal",description:"Identifies the file resource as a literal file"},name:{type:"string",description:"The name of the file"},contents:{anyOf:[{type:"string"},{type:"object",properties:{BYTES_PER_ELEMENT:{type:"number"},buffer:{type:"object",properties:{byteLength:{type:"number"}},required:["byteLength"],additionalProperties:!1},byteLength:{type:"number"},byteOffset:{type:"number"},length:{type:"number"}},required:["BYTES_PER_ELEMENT","buffer","byteLength","byteOffset","length"],additionalProperties:{type:"number"}}],description:"The contents of the file"}},required:["resource","name","contents"],additionalProperties:!1},CoreThemeReference:{type:"object",properties:{resource:{type:"string",const:"wordpress.org/themes",description:"Identifies the file resource as a WordPress Core theme"},slug:{type:"string",description:"The slug of the WordPress Core theme"}},required:["resource","slug"],additionalProperties:!1},CorePluginReference:{type:"object",properties:{resource:{type:"string",const:"wordpress.org/plugins",description:"Identifies the file resource as a WordPress Core plugin"},slug:{type:"string",description:"The slug of the WordPress Core plugin"}},required:["resource","slug"],additionalProperties:!1},UrlReference:{type:"object",properties:{resource:{type:"string",const:"url",description:"Identifies the file resource as a URL"},url:{type:"string",description:"The URL of the file"},caption:{type:"string",description:"Optional caption for displaying a progress message"}},required:["resource","url"],additionalProperties:!1},SupportedPHPExtensionBundle:{type:"string",enum:["kitchen-sink","light"]},StepDefinition:{type:"object",discriminator:{propertyName:"step"},required:["step"],oneOf:[{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"activatePlugin"},pluginPath:{type:"string",description:"Path to the plugin directory as absolute path (/wordpress/wp-content/plugins/plugin-name); or the plugin entry file relative to the plugins directory (plugin-name/plugin-name.php)."},pluginName:{type:"string",description:"Optional. Plugin name to display in the progress bar."}},required:["pluginPath","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"activateTheme"},themeFolderName:{type:"string",description:"The name of the theme folder inside wp-content/themes/"}},required:["step","themeFolderName"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"cp"},fromPath:{type:"string",description:"Source path"},toPath:{type:"string",description:"Target path"}},required:["fromPath","step","toPath"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"defineWpConfigConsts"},consts:{type:"object",additionalProperties:{},description:"The constants to define"},method:{type:"string",enum:["rewrite-wp-config","define-before-run"],description:`The method of defining the constants in wp-config.php. Possible values are:
|
|
629
609
|
|
|
630
610
|
- rewrite-wp-config: Default. Rewrites the wp-config.php file to explicitly call define() with the requested name and value. This method alters the file on the disk, but it doesn't conflict with existing define() calls in wp-config.php.
|
|
631
611
|
|
|
632
612
|
- define-before-run: Defines the constant before running the requested script. It doesn't alter any files on the disk, but constants defined this way may conflict with existing define() calls in wp-config.php.`},virtualize:{type:"boolean",deprecated:`This option is noop and will be removed in a future version.
|
|
633
613
|
This option is only kept in here to avoid breaking Blueprint schema validation
|
|
634
|
-
for existing apps using this option.`}},required:["consts","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"defineSiteUrl"},siteUrl:{type:"string",description:"The URL"}},required:["siteUrl","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"enableMultisite"}},required:["step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"importWxr"},file:{$ref:"#/definitions/FileReference",description:"The file to import"}},required:["file","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"importWordPressFiles"},wordPressFilesZip:{$ref:"#/definitions/FileReference",description:"The zip file containing the top-level WordPress files and directories."},pathInZip:{type:"string",description:"The path inside the zip file where the WordPress files are."}},required:["step","wordPressFilesZip"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},ifAlreadyInstalled:{type:"string",enum:["overwrite","skip","error"],description:"What to do if the asset already exists."},step:{type:"string",const:"installPlugin",description:"The step identifier."},pluginZipFile:{$ref:"#/definitions/FileReference",description:"The plugin zip file to install."},options:{$ref:"#/definitions/InstallPluginOptions",description:"Optional installation options."}},required:["pluginZipFile","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},ifAlreadyInstalled:{type:"string",enum:["overwrite","skip","error"],description:"What to do if the asset already exists."},step:{type:"string",const:"installTheme",description:"The step identifier."},themeZipFile:{$ref:"#/definitions/FileReference",description:"The theme zip file to install."},options:{type:"object",properties:{activate:{type:"boolean",description:"Whether to activate the theme after installing it."}},additionalProperties:!1,description:"Optional installation options."}},required:["step","themeZipFile"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"login"},username:{type:"string",description:"The user to log in as. Defaults to 'admin'."},password:{type:"string",description:"The password to log in with. Defaults to 'password'."}},required:["step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"mkdir"},path:{type:"string",description:"The path of the directory you want to create"}},required:["path","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"mv"},fromPath:{type:"string",description:"Source path"},toPath:{type:"string",description:"Target path"}},required:["fromPath","step","toPath"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"resetData"}},required:["step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"request"},request:{$ref:"#/definitions/PHPRequest",description:"Request details (See /wordpress-playground/api/universal/interface/PHPRequest)"}},required:["request","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"rm"},path:{type:"string",description:"The path to remove"}},required:["path","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"rmdir"},path:{type:"string",description:"The path to remove"}},required:["path","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"runPHP",description:"The step identifier."},code:{type:"string",description:"The PHP code to run."}},required:["code","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"runPHPWithOptions"},options:{$ref:"#/definitions/PHPRunOptions",description:"Run options (See /wordpress-playground/api/universal/interface/PHPRunOptions/))"}},required:["options","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"runWpInstallationWizard"},options:{$ref:"#/definitions/WordPressInstallationOptions"}},required:["options","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"runSql",description:"The step identifier."},sql:{$ref:"#/definitions/FileReference",description:"The SQL to run. Each non-empty line must contain a valid SQL query."}},required:["sql","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"setSiteOptions",description:'The name of the step. Must be "setSiteOptions".'},options:{type:"object",additionalProperties:{},description:"The options to set on the site."}},required:["options","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"unzip"},zipFile:{$ref:"#/definitions/FileReference",description:"The zip file to extract"},zipPath:{type:"string",description:"The path of the zip file to extract",deprecated:"Use zipFile instead."},extractToPath:{type:"string",description:"The path to extract the zip file to"}},required:["extractToPath","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"updateUserMeta"},meta:{type:"object",additionalProperties:{},description:'An object of user meta values to set, e.g. { "first_name": "John" }'},userId:{type:"number",description:"User ID"}},required:["meta","step","userId"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"writeFile"},path:{type:"string",description:"The path of the file to write to"},data:{anyOf:[{$ref:"#/definitions/FileReference"},{type:"string"},{type:"object",properties:{BYTES_PER_ELEMENT:{type:"number"},buffer:{type:"object",properties:{byteLength:{type:"number"}},required:["byteLength"],additionalProperties:!1},byteLength:{type:"number"},byteOffset:{type:"number"},length:{type:"number"}},required:["BYTES_PER_ELEMENT","buffer","byteLength","byteOffset","length"],additionalProperties:{type:"number"}}],description:"The data to write"}},required:["data","path","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"wp-cli",description:"The step identifier."},command:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:"The WP CLI command to run."},wpCliPath:{type:"string",description:"wp-cli.phar path"}},required:["command","step"]}]},InstallPluginOptions:{type:"object",properties:{activate:{type:"boolean",description:"Whether to activate the plugin after installing it."}},additionalProperties:!1},PHPRequest:{type:"object",properties:{method:{$ref:"#/definitions/HTTPMethod",description:"Request method. Default: `GET`."},url:{type:"string",description:"Request path or absolute URL."},headers:{$ref:"#/definitions/PHPRequestHeaders",description:"Request headers."},body:{anyOf:[{type:"string"},{type:"object",properties:{BYTES_PER_ELEMENT:{type:"number"},buffer:{type:"object",properties:{byteLength:{type:"number"}},required:["byteLength"],additionalProperties:!1},byteLength:{type:"number"},byteOffset:{type:"number"},length:{type:"number"}},required:["BYTES_PER_ELEMENT","buffer","byteLength","byteOffset","length"],additionalProperties:{type:"number"}},{type:"object",additionalProperties:{anyOf:[{type:"string"},{type:"object",properties:{BYTES_PER_ELEMENT:{type:"number"},buffer:{type:"object",properties:{byteLength:{type:"number"}},required:["byteLength"],additionalProperties:!1},byteLength:{type:"number"},byteOffset:{type:"number"},length:{type:"number"}},required:["BYTES_PER_ELEMENT","buffer","byteLength","byteOffset","length"],additionalProperties:{type:"number"}},{type:"object",properties:{size:{type:"number"},type:{type:"string"},lastModified:{type:"number"},name:{type:"string"},webkitRelativePath:{type:"string"}},required:["lastModified","name","size","type","webkitRelativePath"],additionalProperties:!1}]}}],description:"Request body. If an object is given, the request will be encoded as multipart and sent with a `multipart/form-data` header."}},required:["url"],additionalProperties:!1},HTTPMethod:{type:"string",enum:["GET","POST","HEAD","OPTIONS","PATCH","PUT","DELETE"]},PHPRequestHeaders:{type:"object",additionalProperties:{type:"string"}},PHPRunOptions:{type:"object",properties:{relativeUri:{type:"string",description:"Request path following the domain:port part."},scriptPath:{type:"string",description:"Path of the .php file to execute."},protocol:{type:"string",description:"Request protocol."},method:{$ref:"#/definitions/HTTPMethod",description:"Request method. Default: `GET`."},headers:{$ref:"#/definitions/PHPRequestHeaders",description:"Request headers."},body:{anyOf:[{type:"string"},{type:"object",properties:{BYTES_PER_ELEMENT:{type:"number"},buffer:{type:"object",properties:{byteLength:{type:"number"}},required:["byteLength"],additionalProperties:!1},byteLength:{type:"number"},byteOffset:{type:"number"},length:{type:"number"}},required:["BYTES_PER_ELEMENT","buffer","byteLength","byteOffset","length"],additionalProperties:{type:"number"}}],description:"Request body."},env:{type:"object",additionalProperties:{type:"string"},description:"Environment variables to set for this run."},$_SERVER:{type:"object",additionalProperties:{type:"string"},description:"$_SERVER entries to set for this run."},code:{type:"string",description:"The code snippet to eval instead of a php file."}},additionalProperties:!1},WordPressInstallationOptions:{type:"object",properties:{adminUsername:{type:"string"},adminPassword:{type:"string"}},additionalProperties:!1}},Et={$schema:bt,$ref:_t,definitions:Pt},{wpCLI:vt,...ne}=rt,Tt={...ne,"wp-cli":vt,importFile:ne.importWxr};function kt(e,{progress:t=new G,semaphore:n=new je({concurrency:3}),onStepCompleted:r=()=>{}}={}){var d,h,y,R,Q,Z,Y;e={...e,steps:(e.steps||[]).filter(Ct).filter(Ot)};for(const c of e.steps)typeof c=="object"&&c.step==="importFile"&&(c.step="importWxr",g.warn('The "importFile" step is deprecated. Use "importWxr" instead.'));if(e.constants&&e.steps.unshift({step:"defineWpConfigConsts",consts:e.constants}),e.siteOptions&&e.steps.unshift({step:"setSiteOptions",options:e.siteOptions}),e.plugins){const c=e.plugins.map(w=>typeof w=="string"?w.startsWith("https://")?{resource:"url",url:w}:{resource:"wordpress.org/plugins",slug:w}:w).map(w=>({step:"installPlugin",pluginZipFile:w}));e.steps.unshift(...c)}e.login&&e.steps.push({step:"login",...e.login===!0?{username:"admin",password:"password"}:e.login}),e.phpExtensionBundles||(e.phpExtensionBundles=[]),e.phpExtensionBundles||(e.phpExtensionBundles=[]),e.phpExtensionBundles.length===0&&e.phpExtensionBundles.push("kitchen-sink");const i=(d=e.steps)==null?void 0:d.findIndex(c=>typeof c=="object"&&(c==null?void 0:c.step)==="wp-cli");i!==void 0&&i>-1&&(e.phpExtensionBundles.includes("light")&&(e.phpExtensionBundles=e.phpExtensionBundles.filter(c=>c!=="light"),g.warn("The wpCli step used in your Blueprint requires the iconv and mbstring PHP extensions. However, you did not specify the kitchen-sink extension bundle. Playground will override your choice and load the kitchen-sink PHP extensions bundle to prevent the WP-CLI step from failing. ")),(h=e.steps)==null||h.splice(i,0,{step:"writeFile",data:{resource:"url",url:"https://playground.wordpress.net/wp-cli.phar"},path:"/tmp/wp-cli.phar"}));const s=(y=e.steps)==null?void 0:y.findIndex(c=>typeof c=="object"&&(c==null?void 0:c.step)==="importWxr");s!==void 0&&s>-1&&(e.phpExtensionBundles.includes("light")&&(e.phpExtensionBundles=e.phpExtensionBundles.filter(c=>c!=="light"),g.warn("The importWxr step used in your Blueprint requires the iconv and mbstring PHP extensions. However, you did not specify the kitchen-sink extension bundle. Playground will override your choice and load the kitchen-sink PHP extensions bundle to prevent the WP-CLI step from failing. ")),(R=e.steps)==null||R.splice(s,0,{step:"installPlugin",pluginZipFile:{resource:"url",url:"https://playground.wordpress.net/wordpress-importer.zip",caption:"Downloading the WordPress Importer plugin"}}));const{valid:o,errors:a}=xt(e);if(!o){const c=new Error(`Invalid blueprint: ${a[0].message} at ${a[0].instancePath}`);throw c.errors=a,c}const p=e.steps||[],l=p.reduce((c,w)=>{var E;return c+(((E=w.progress)==null?void 0:E.weight)||1)},0),u=p.map(c=>qt(c,{semaphore:n,rootProgressTracker:t,totalProgressWeight:l}));return{versions:{php:St((Q=e.preferredVersions)==null?void 0:Q.php,Le,ct),wp:((Z=e.preferredVersions)==null?void 0:Z.wp)||"latest"},phpExtensions:Lt([],e.phpExtensionBundles||[]),features:{networking:((Y=e.features)==null?void 0:Y.networking)??!1},run:async c=>{try{for(const{resources:w}of u)for(const E of w)E.setPlayground(c),E.isAsync&&E.resolve();for(const[w,{run:E,step:J}]of Object.entries(u))try{const v=await E(c);r(v,J)}catch(v){throw g.error(v),new Error(`Error when executing the blueprint step #${w} (${JSON.stringify(J)}) ${v instanceof Error?`: ${v.message}`:v}`,{cause:v})}}finally{try{await c.goTo(e.landingPage||"/")}catch{}t.finish()}}}}const Rt=new Ie({discriminator:!0});let x;function xt(e){var i;x=Rt.compile(Et);const t=x(e);if(t)return{valid:t};const n=new Set;for(const s of x.errors)s.schemaPath.startsWith("#/properties/steps/items/anyOf")||n.add(s.instancePath);const r=(i=x.errors)==null?void 0:i.filter(s=>!(s.schemaPath.startsWith("#/properties/steps/items/anyOf")&&n.has(s.instancePath)));return{valid:t,errors:r}}function St(e,t,n){return e&&t.includes(e)?e:n}function Lt(e,t){const n=Ce.filter(i=>e.includes(i)),r=t.flatMap(i=>i in te?te[i]:[]);return Array.from(new Set([...n,...r]))}function Ct(e){return!!(typeof e=="object"&&e)}function Ot(e){return["setPhpIniEntry","request"].includes(e.step)?(g.warn(`The "${e.step}" Blueprint is no longer supported and you can remove it from your Blueprint.`),!1):!0}function qt(e,{semaphore:t,rootProgressTracker:n,totalProgressWeight:r}){var u;const i=n.stage((((u=e.progress)==null?void 0:u.weight)||1)/r),s={};for(const d of Object.keys(e)){let h=e[d];dt(h)&&(h=T.create(h,{semaphore:t})),s[d]=h}const o=async d=>{var h;try{return i.fillSlowly(),await Tt[e.step](d,await It(s),{tracker:i,initialCaption:(h=e.progress)==null?void 0:h.caption})}finally{i.finish()}},a=re(s),p=re(s).filter(d=>d.isAsync),l=1/(p.length+1);for(const d of p)d.progress=i.stage(l);return{run:o,step:e,resources:a}}function re(e){const t=[];for(const n in e){const r=e[n];r instanceof T&&t.push(r)}return t}async function It(e){const t={};for(const n in e){const r=e[n];r instanceof T?t[n]=await r.resolve():t[n]=r}return t}async function Wt(e,t){await e.run(t)}function Ft(){}exports.activatePlugin=q;exports.activateTheme=A;exports.compileBlueprint=kt;exports.cp=ye;exports.defineSiteUrl=H;exports.defineWpConfigConsts=k;exports.enableMultisite=me;exports.exportWXR=Pe;exports.importWordPressFiles=_e;exports.importWxr=be;exports.installPlugin=ve;exports.installTheme=Te;exports.login=L;exports.mkdir=we;exports.mv=ge;exports.request=S;exports.resetData=ke;exports.rm=U;exports.rmdir=$e;exports.runBlueprintSteps=Wt;exports.runPHP=le;exports.runPHPWithOptions=de;exports.runSql=ue;exports.runWpInstallationWizard=Re;exports.setPluginProxyURL=Ft;exports.setSiteOptions=M;exports.unzip=I;exports.updateUserMeta=fe;exports.wpCLI=Se;exports.wpContentFilesExcludedFromExport=N;exports.writeFile=z;exports.zipWpContent=xe;
|
|
614
|
+
for existing apps using this option.`}},required:["consts","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"defineSiteUrl"},siteUrl:{type:"string",description:"The URL"}},required:["siteUrl","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"enableMultisite"}},required:["step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"importWxr"},file:{$ref:"#/definitions/FileReference",description:"The file to import"}},required:["file","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"importWordPressFiles"},wordPressFilesZip:{$ref:"#/definitions/FileReference",description:"The zip file containing the top-level WordPress files and directories."},pathInZip:{type:"string",description:"The path inside the zip file where the WordPress files are."}},required:["step","wordPressFilesZip"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},ifAlreadyInstalled:{type:"string",enum:["overwrite","skip","error"],description:"What to do if the asset already exists."},step:{type:"string",const:"installPlugin",description:"The step identifier."},pluginZipFile:{$ref:"#/definitions/FileReference",description:"The plugin zip file to install."},options:{$ref:"#/definitions/InstallPluginOptions",description:"Optional installation options."}},required:["pluginZipFile","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},ifAlreadyInstalled:{type:"string",enum:["overwrite","skip","error"],description:"What to do if the asset already exists."},step:{type:"string",const:"installTheme",description:"The step identifier."},themeZipFile:{$ref:"#/definitions/FileReference",description:"The theme zip file to install."},options:{type:"object",properties:{activate:{type:"boolean",description:"Whether to activate the theme after installing it."}},additionalProperties:!1,description:"Optional installation options."}},required:["step","themeZipFile"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"login"},username:{type:"string",description:"The user to log in as. Defaults to 'admin'."},password:{type:"string",description:"The password to log in with. Defaults to 'password'."}},required:["step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"mkdir"},path:{type:"string",description:"The path of the directory you want to create"}},required:["path","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"mv"},fromPath:{type:"string",description:"Source path"},toPath:{type:"string",description:"Target path"}},required:["fromPath","step","toPath"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"resetData"}},required:["step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"request"},request:{$ref:"#/definitions/PHPRequest",description:"Request details (See /wordpress-playground/api/universal/interface/PHPRequest)"}},required:["request","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"rm"},path:{type:"string",description:"The path to remove"}},required:["path","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"rmdir"},path:{type:"string",description:"The path to remove"}},required:["path","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"runPHP",description:"The step identifier."},code:{type:"string",description:"The PHP code to run."}},required:["code","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"runPHPWithOptions"},options:{$ref:"#/definitions/PHPRunOptions",description:"Run options (See /wordpress-playground/api/universal/interface/PHPRunOptions/))"}},required:["options","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"runWpInstallationWizard"},options:{$ref:"#/definitions/WordPressInstallationOptions"}},required:["options","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"runSql",description:"The step identifier."},sql:{$ref:"#/definitions/FileReference",description:"The SQL to run. Each non-empty line must contain a valid SQL query."}},required:["sql","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"setSiteOptions",description:'The name of the step. Must be "setSiteOptions".'},options:{type:"object",additionalProperties:{},description:"The options to set on the site."}},required:["options","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"unzip"},zipFile:{$ref:"#/definitions/FileReference",description:"The zip file to extract"},zipPath:{type:"string",description:"The path of the zip file to extract",deprecated:"Use zipFile instead."},extractToPath:{type:"string",description:"The path to extract the zip file to"}},required:["extractToPath","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"updateUserMeta"},meta:{type:"object",additionalProperties:{},description:'An object of user meta values to set, e.g. { "first_name": "John" }'},userId:{type:"number",description:"User ID"}},required:["meta","step","userId"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"writeFile"},path:{type:"string",description:"The path of the file to write to"},data:{anyOf:[{$ref:"#/definitions/FileReference"},{type:"string"},{type:"object",properties:{BYTES_PER_ELEMENT:{type:"number"},buffer:{type:"object",properties:{byteLength:{type:"number"}},required:["byteLength"],additionalProperties:!1},byteLength:{type:"number"},byteOffset:{type:"number"},length:{type:"number"}},required:["BYTES_PER_ELEMENT","buffer","byteLength","byteOffset","length"],additionalProperties:{type:"number"}}],description:"The data to write"}},required:["data","path","step"]},{type:"object",additionalProperties:!1,properties:{progress:{type:"object",properties:{weight:{type:"number"},caption:{type:"string"}},additionalProperties:!1},step:{type:"string",const:"wp-cli",description:"The step identifier."},command:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:"The WP CLI command to run."},wpCliPath:{type:"string",description:"wp-cli.phar path"}},required:["command","step"]}]},InstallPluginOptions:{type:"object",properties:{activate:{type:"boolean",description:"Whether to activate the plugin after installing it."}},additionalProperties:!1},PHPRequest:{type:"object",properties:{method:{$ref:"#/definitions/HTTPMethod",description:"Request method. Default: `GET`."},url:{type:"string",description:"Request path or absolute URL."},headers:{$ref:"#/definitions/PHPRequestHeaders",description:"Request headers."},body:{anyOf:[{type:"string"},{type:"object",properties:{BYTES_PER_ELEMENT:{type:"number"},buffer:{type:"object",properties:{byteLength:{type:"number"}},required:["byteLength"],additionalProperties:!1},byteLength:{type:"number"},byteOffset:{type:"number"},length:{type:"number"}},required:["BYTES_PER_ELEMENT","buffer","byteLength","byteOffset","length"],additionalProperties:{type:"number"}},{type:"object",additionalProperties:{anyOf:[{type:"string"},{type:"object",properties:{BYTES_PER_ELEMENT:{type:"number"},buffer:{type:"object",properties:{byteLength:{type:"number"}},required:["byteLength"],additionalProperties:!1},byteLength:{type:"number"},byteOffset:{type:"number"},length:{type:"number"}},required:["BYTES_PER_ELEMENT","buffer","byteLength","byteOffset","length"],additionalProperties:{type:"number"}},{type:"object",properties:{size:{type:"number"},type:{type:"string"},lastModified:{type:"number"},name:{type:"string"},webkitRelativePath:{type:"string"}},required:["lastModified","name","size","type","webkitRelativePath"],additionalProperties:!1}]}}],description:"Request body. If an object is given, the request will be encoded as multipart and sent with a `multipart/form-data` header."}},required:["url"],additionalProperties:!1},HTTPMethod:{type:"string",enum:["GET","POST","HEAD","OPTIONS","PATCH","PUT","DELETE"]},PHPRequestHeaders:{type:"object",additionalProperties:{type:"string"}},PHPRunOptions:{type:"object",properties:{relativeUri:{type:"string",description:"Request path following the domain:port part."},scriptPath:{type:"string",description:"Path of the .php file to execute."},protocol:{type:"string",description:"Request protocol."},method:{$ref:"#/definitions/HTTPMethod",description:"Request method. Default: `GET`."},headers:{$ref:"#/definitions/PHPRequestHeaders",description:"Request headers."},body:{anyOf:[{type:"string"},{type:"object",properties:{BYTES_PER_ELEMENT:{type:"number"},buffer:{type:"object",properties:{byteLength:{type:"number"}},required:["byteLength"],additionalProperties:!1},byteLength:{type:"number"},byteOffset:{type:"number"},length:{type:"number"}},required:["BYTES_PER_ELEMENT","buffer","byteLength","byteOffset","length"],additionalProperties:{type:"number"}}],description:"Request body."},env:{type:"object",additionalProperties:{type:"string"},description:"Environment variables to set for this run."},$_SERVER:{type:"object",additionalProperties:{type:"string"},description:"$_SERVER entries to set for this run."},code:{type:"string",description:"The code snippet to eval instead of a php file."}},additionalProperties:!1},WordPressInstallationOptions:{type:"object",properties:{adminUsername:{type:"string"},adminPassword:{type:"string"}},additionalProperties:!1}},Ue={$schema:Oe,$ref:Ce,definitions:We},{wpCLI:Ie,...M}=be,Fe={...M,"wp-cli":Ie,importFile:M.importWxr};function Be(e,{progress:t=new z.ProgressTracker,semaphore:n=new o.Semaphore({concurrency:3}),onStepCompleted:i=()=>{}}={}){var l,u,m,E,I,F,B;e={...e,steps:(e.steps||[]).filter(He).filter(ze)};for(const c of e.steps)typeof c=="object"&&c.step==="importFile"&&(c.step="importWxr",g.logger.warn('The "importFile" step is deprecated. Use "importWxr" instead.'));if(e.constants&&e.steps.unshift({step:"defineWpConfigConsts",consts:e.constants}),e.siteOptions&&e.steps.unshift({step:"setSiteOptions",options:e.siteOptions}),e.plugins){const c=e.plugins.map(w=>typeof w=="string"?w.startsWith("https://")?{resource:"url",url:w}:{resource:"wordpress.org/plugins",slug:w}:w).map(w=>({step:"installPlugin",pluginZipFile:w}));e.steps.unshift(...c)}e.login&&e.steps.push({step:"login",...e.login===!0?{username:"admin",password:"password"}:e.login}),e.phpExtensionBundles||(e.phpExtensionBundles=[]),e.phpExtensionBundles||(e.phpExtensionBundles=[]),e.phpExtensionBundles.length===0&&e.phpExtensionBundles.push("kitchen-sink");const r=(l=e.steps)==null?void 0:l.findIndex(c=>typeof c=="object"&&(c==null?void 0:c.step)==="wp-cli");r!==void 0&&r>-1&&(e.phpExtensionBundles.includes("light")&&(e.phpExtensionBundles=e.phpExtensionBundles.filter(c=>c!=="light"),g.logger.warn("The wpCli step used in your Blueprint requires the iconv and mbstring PHP extensions. However, you did not specify the kitchen-sink extension bundle. Playground will override your choice and load the kitchen-sink PHP extensions bundle to prevent the WP-CLI step from failing. ")),(u=e.steps)==null||u.splice(r,0,{step:"writeFile",data:{resource:"url",url:"https://playground.wordpress.net/wp-cli.phar"},path:"/tmp/wp-cli.phar"}));const s=(m=e.steps)==null?void 0:m.findIndex(c=>typeof c=="object"&&(c==null?void 0:c.step)==="importWxr");s!==void 0&&s>-1&&(e.phpExtensionBundles.includes("light")&&(e.phpExtensionBundles=e.phpExtensionBundles.filter(c=>c!=="light"),g.logger.warn("The importWxr step used in your Blueprint requires the iconv and mbstring PHP extensions. However, you did not specify the kitchen-sink extension bundle. Playground will override your choice and load the kitchen-sink PHP extensions bundle to prevent the WP-CLI step from failing. ")),(E=e.steps)==null||E.splice(s,0,{step:"installPlugin",pluginZipFile:{resource:"url",url:"https://playground.wordpress.net/wordpress-importer.zip",caption:"Downloading the WordPress Importer plugin"}}));const{valid:a,errors:d}=Ne(e);if(!a){const c=new Error(`Invalid blueprint: ${d[0].message} at ${d[0].instancePath}`);throw c.errors=d,c}const p=e.steps||[],h=p.reduce((c,w)=>{var y;return c+(((y=w.progress)==null?void 0:y.weight)||1)},0),f=p.map(c=>Ge(c,{semaphore:n,rootProgressTracker:t,totalProgressWeight:h}));return{versions:{php:De((I=e.preferredVersions)==null?void 0:I.php,P.SupportedPHPVersions,P.LatestSupportedPHPVersion),wp:((F=e.preferredVersions)==null?void 0:F.wp)||"latest"},phpExtensions:Me([],e.phpExtensionBundles||[]),features:{networking:((B=e.features)==null?void 0:B.networking)??!1},run:async c=>{try{for(const{resources:w}of f)for(const y of w)y.setPlayground(c),y.isAsync&&y.resolve();for(const[w,{run:y,step:A}]of Object.entries(f))try{const $=await y(c);i($,A)}catch($){throw g.logger.error($),new Error(`Error when executing the blueprint step #${w} (${JSON.stringify(A)}) ${$ instanceof Error?`: ${$.message}`:$}`,{cause:$})}}finally{try{await c.goTo(e.landingPage||"/")}catch{}t.finish()}}}}const Ae=new fe({discriminator:!0});let T;function Ne(e){var r;T=Ae.compile(Ue);const t=T(e);if(t)return{valid:t};const n=new Set;for(const s of T.errors)s.schemaPath.startsWith("#/properties/steps/items/anyOf")||n.add(s.instancePath);const i=(r=T.errors)==null?void 0:r.filter(s=>!(s.schemaPath.startsWith("#/properties/steps/items/anyOf")&&n.has(s.instancePath)));return{valid:t,errors:i}}function De(e,t,n){return e&&t.includes(e)?e:n}function Me(e,t){const n=P.SupportedPHPExtensionsList.filter(r=>e.includes(r)),i=t.flatMap(r=>r in P.SupportedPHPExtensionBundles?P.SupportedPHPExtensionBundles[r]:[]);return Array.from(new Set([...n,...i]))}function He(e){return!!(typeof e=="object"&&e)}function ze(e){return["setPhpIniEntry","request"].includes(e.step)?(g.logger.warn(`The "${e.step}" Blueprint is no longer supported and you can remove it from your Blueprint.`),!1):!0}function Ge(e,{semaphore:t,rootProgressTracker:n,totalProgressWeight:i}){var f;const r=n.stage((((f=e.progress)==null?void 0:f.weight)||1)/i),s={};for(const l of Object.keys(e)){let u=e[l];Te(u)&&(u=_.create(u,{semaphore:t})),s[l]=u}const a=async l=>{var u;try{return r.fillSlowly(),await Fe[e.step](l,await Ve(s),{tracker:r,initialCaption:(u=e.progress)==null?void 0:u.caption})}finally{r.finish()}},d=H(s),p=H(s).filter(l=>l.isAsync),h=1/(p.length+1);for(const l of p)l.progress=r.stage(h);return{run:a,step:e,resources:d}}function H(e){const t=[];for(const n in e){const i=e[n];i instanceof _&&t.push(i)}return t}async function Ve(e){const t={};for(const n in e){const i=e[n];i instanceof _?t[n]=await i.resolve():t[n]=i}return t}async function Qe(e,t){await e.run(t)}function Ye(){}exports.activatePlugin=R;exports.activateTheme=L;exports.compileBlueprint=Be;exports.cp=X;exports.defineSiteUrl=W;exports.defineWpConfigConsts=b;exports.enableMultisite=Z;exports.exportWXR=ie;exports.importWordPressFiles=ne;exports.importWxr=te;exports.installPlugin=se;exports.installTheme=oe;exports.login=v;exports.mkdir=K;exports.mv=J;exports.request=k;exports.resetData=ae;exports.rm=q;exports.rmdir=ee;exports.runBlueprintSteps=Qe;exports.runPHP=G;exports.runPHPWithOptions=V;exports.runSql=Q;exports.runWpInstallationWizard=pe;exports.setPluginProxyURL=Ye;exports.setSiteOptions=O;exports.unzip=S;exports.updateUserMeta=Y;exports.wpCLI=de;exports.wpContentFilesExcludedFromExport=j;exports.writeFile=C;exports.zipWpContent=ce;
|