@wp-playground/blueprints 0.9.18 → 0.9.19

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.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import "@php-wasm/node-polyfills";
2
- import { phpVar as m, randomFilename as Y, phpVars as S, joinPaths as u, dirname as Z, randomString as X, Semaphore as J } from "@php-wasm/util";
3
- import { logger as g } from "@php-wasm/logger";
4
- import { isURLScoped as K, getURLScope as ee } from "@php-wasm/scopes";
5
- import { unzipFile as te } from "@wp-playground/common";
6
- import { cloneResponseMonitorProgress as ne, ProgressTracker as ie } from "@php-wasm/progress";
7
- import { SupportedPHPExtensionsList as re, SupportedPHPExtensionBundles as I, LatestSupportedPHPVersion as se, SupportedPHPVersions as oe } from "@php-wasm/universal";
8
- import ae from "ajv";
9
- const B = [
2
+ import { phpVar as f, randomFilename as X, phpVars as S, joinPaths as w, dirname as J, randomString as K, Semaphore as ee } from "@php-wasm/util";
3
+ import { logger as y } from "@php-wasm/logger";
4
+ import { isURLScoped as te, getURLScope as ne } from "@php-wasm/scopes";
5
+ import { unzipFile as B } from "@wp-playground/common";
6
+ import { cloneResponseMonitorProgress as ie, ProgressTracker as re } from "@php-wasm/progress";
7
+ import { SupportedPHPExtensionsList as se, SupportedPHPExtensionBundles as I, LatestSupportedPHPVersion as oe, SupportedPHPVersions as ae } from "@php-wasm/universal";
8
+ import pe from "ajv";
9
+ const D = [
10
10
  "db.php",
11
11
  "plugins/akismet",
12
12
  "plugins/hello.php",
@@ -32,13 +32,13 @@ const B = [
32
32
  const r = await e.documentRoot, s = await e.run({
33
33
  code: `<?php
34
34
  define( 'WP_ADMIN', true );
35
- require_once( ${m(r)}. "/wp-load.php" );
36
- require_once( ${m(r)}. "/wp-admin/includes/plugin.php" );
35
+ require_once( ${f(r)}. "/wp-load.php" );
36
+ require_once( ${f(r)}. "/wp-admin/includes/plugin.php" );
37
37
 
38
38
  // Set current user to admin
39
39
  wp_set_current_user( get_users(array('role' => 'Administrator') )[0]->ID );
40
40
 
41
- $plugin_path = ${m(t)};
41
+ $plugin_path = ${f(t)};
42
42
  $response = false;
43
43
  if (!is_dir($plugin_path)) {
44
44
  $response = activate_plugin($plugin_path);
@@ -65,7 +65,7 @@ const B = [
65
65
  `
66
66
  });
67
67
  if (s.text !== "Plugin activated successfully")
68
- throw g.debug(s), new Error(
68
+ throw y.debug(s), new Error(
69
69
  `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`
70
70
  );
71
71
  }, N = async (e, { themeFolderName: t }, n) => {
@@ -100,14 +100,14 @@ const B = [
100
100
  }
101
101
  });
102
102
  if (s.text !== "Theme activated successfully")
103
- throw g.debug(s), new Error(
103
+ throw y.debug(s), new Error(
104
104
  `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`
105
105
  );
106
- }, pe = async (e, { code: t }) => await e.run({ code: t }), ce = async (e, { options: t }) => await e.run(t), D = async (e, { path: t }) => {
106
+ }, ce = async (e, { code: t }) => await e.run({ code: t }), de = async (e, { options: t }) => await e.run(t), z = async (e, { path: t }) => {
107
107
  await e.unlink(t);
108
- }, de = async (e, { sql: t }, n) => {
108
+ }, le = async (e, { sql: t }, n) => {
109
109
  n == null || n.tracker.setCaption("Executing SQL Queries");
110
- const i = `/tmp/${Y()}.sql`;
110
+ const i = `/tmp/${X()}.sql`;
111
111
  await e.writeFile(
112
112
  i,
113
113
  new Uint8Array(await t.arrayBuffer())
@@ -134,18 +134,18 @@ const B = [
134
134
  }
135
135
  `
136
136
  });
137
- return await D(e, { path: i }), o;
138
- }, R = async (e, { request: t }) => {
139
- g.warn(
137
+ return await z(e, { path: i }), o;
138
+ }, v = async (e, { request: t }) => {
139
+ y.warn(
140
140
  'Deprecated: The Blueprint step "request" is deprecated and will be removed in a future release.'
141
141
  );
142
142
  const n = await e.request(t);
143
143
  if (n.httpStatusCode > 399 || n.httpStatusCode < 200)
144
- throw g.warn("WordPress response was", { response: n }), new Error(
144
+ throw y.warn("WordPress response was", { response: n }), new Error(
145
145
  `Request failed with status ${n.httpStatusCode}`
146
146
  );
147
147
  return n;
148
- }, le = `<?php
148
+ }, ue = `<?php
149
149
 
150
150
  /**
151
151
  * Rewrites the wp-config.php file to ensure specific constants are defined
@@ -479,10 +479,10 @@ function skip_whitespace($tokens) {
479
479
  `, T = async (e, { consts: t, method: n = "define-before-run" }) => {
480
480
  switch (n) {
481
481
  case "define-before-run":
482
- await ue(e, t);
482
+ await he(e, t);
483
483
  break;
484
484
  case "rewrite-wp-config": {
485
- const i = await e.documentRoot, r = u(i, "/wp-config.php"), s = await e.readFileAsText(r), o = await he(
485
+ const i = await e.documentRoot, r = w(i, "/wp-config.php"), s = await e.readFileAsText(r), o = await fe(
486
486
  e,
487
487
  s,
488
488
  t
@@ -494,17 +494,17 @@ function skip_whitespace($tokens) {
494
494
  throw new Error(`Invalid method: ${n}`);
495
495
  }
496
496
  };
497
- async function ue(e, t) {
497
+ async function he(e, t) {
498
498
  for (const n in t)
499
499
  await e.defineConstant(n, t[n]);
500
500
  }
501
- async function he(e, t, n) {
501
+ async function fe(e, t, n) {
502
502
  await e.writeFile("/tmp/code.php", t);
503
503
  const i = S({
504
504
  consts: n
505
505
  });
506
506
  return await e.run({
507
- code: `${le}
507
+ code: `${ue}
508
508
  $wp_config_path = '/tmp/code.php';
509
509
  $wp_config = file_get_contents($wp_config_path);
510
510
  $new_wp_config = rewrite_wp_config_to_define_constants($wp_config, ${i.consts});
@@ -512,7 +512,7 @@ async function he(e, t, n) {
512
512
  `
513
513
  }), await e.readFileAsText("/tmp/code.php");
514
514
  }
515
- const v = async (e, { username: t = "admin", password: n = "password" } = {}, i) => {
515
+ const R = async (e, { username: t = "admin", password: n = "password" } = {}, i) => {
516
516
  var s, o, c;
517
517
  i == null || i.tracker.setCaption((i == null ? void 0 : i.initialCaption) || "Logging in"), await e.request({
518
518
  url: "/wp-login.php"
@@ -527,7 +527,7 @@ const v = async (e, { username: t = "admin", password: n = "password" } = {}, i)
527
527
  }
528
528
  });
529
529
  if (!((c = (o = (s = r.headers) == null ? void 0 : s.location) == null ? void 0 : o[0]) != null && c.includes("/wp-admin/")))
530
- throw g.warn("WordPress response was", {
530
+ throw y.warn("WordPress response was", {
531
531
  response: r,
532
532
  text: r.text
533
533
  }), new Error(
@@ -537,26 +537,26 @@ const v = async (e, { username: t = "admin", password: n = "password" } = {}, i)
537
537
  const n = await e.documentRoot;
538
538
  await e.run({
539
539
  code: `<?php
540
- include ${m(n)} . '/wp-load.php';
541
- $site_options = ${m(t)};
540
+ include ${f(n)} . '/wp-load.php';
541
+ $site_options = ${f(t)};
542
542
  foreach($site_options as $name => $value) {
543
543
  update_option($name, $value);
544
544
  }
545
545
  echo "Success";
546
546
  `
547
547
  });
548
- }, fe = async (e, { meta: t, userId: n }) => {
548
+ }, me = async (e, { meta: t, userId: n }) => {
549
549
  const i = await e.documentRoot;
550
550
  await e.run({
551
551
  code: `<?php
552
- include ${m(i)} . '/wp-load.php';
553
- $meta = ${m(t)};
552
+ include ${f(i)} . '/wp-load.php';
553
+ $meta = ${f(t)};
554
554
  foreach($meta as $name => $value) {
555
- update_user_meta(${m(n)}, $name, $value);
555
+ update_user_meta(${f(n)}, $name, $value);
556
556
  }
557
557
  `
558
558
  });
559
- }, me = async (e) => {
559
+ }, we = async (e) => {
560
560
  var l;
561
561
  await T(e, {
562
562
  consts: {
@@ -565,8 +565,8 @@ const v = async (e, { username: t = "admin", password: n = "password" } = {}, i)
565
565
  });
566
566
  const t = new URL(await e.absoluteUrl);
567
567
  if (t.port !== "") {
568
- let w = `The current host is ${t.host}, but WordPress multisites do not support custom ports.`;
569
- throw t.hostname === "localhost" && (w += " For development, you can set up a playground.test domain using the instructions at https://wordpress.github.io/wordpress-playground/contributing/code."), new Error(w);
568
+ let m = `The current host is ${t.host}, but WordPress multisites do not support custom ports.`;
569
+ 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);
570
570
  }
571
571
  const n = t.pathname.replace(/\/$/, "") + "/", i = `${t.protocol}//${t.hostname}${n}`;
572
572
  await M(e, {
@@ -574,17 +574,17 @@ const v = async (e, { username: t = "admin", password: n = "password" } = {}, i)
574
574
  siteurl: i,
575
575
  home: i
576
576
  }
577
- }), await v(e, {});
577
+ }), await R(e, {});
578
578
  const r = await e.documentRoot, o = (await e.run({
579
579
  code: `<?php
580
580
  define( 'WP_ADMIN', true );
581
- require_once(${m(r)} . "/wp-load.php");
581
+ require_once(${f(r)} . "/wp-load.php");
582
582
 
583
583
  // Set current user to admin
584
584
  ( get_users(array('role' => 'Administrator') )[0] );
585
585
 
586
- require_once(${m(r)} . "/wp-admin/includes/plugin.php");
587
- $plugins_root = ${m(r)} . "/wp-content/plugins";
586
+ require_once(${f(r)} . "/wp-admin/includes/plugin.php");
587
+ $plugins_root = ${f(r)} . "/wp-content/plugins";
588
588
  $plugins = glob($plugins_root . "/*");
589
589
 
590
590
  $deactivated_plugins = [];
@@ -609,21 +609,21 @@ foreach($plugins as $plugin_path) {
609
609
  }
610
610
  echo json_encode($deactivated_plugins);
611
611
  `
612
- })).json, a = (l = (await R(e, {
612
+ })).json, p = (l = (await v(e, {
613
613
  request: {
614
614
  url: "/wp-admin/network.php"
615
615
  }
616
616
  })).text.match(
617
617
  /name="_wpnonce"\s+value="([^"]+)"/
618
- )) == null ? void 0 : l[1], h = await R(e, {
618
+ )) == null ? void 0 : l[1], h = await v(e, {
619
619
  request: {
620
620
  url: "/wp-admin/network.php",
621
621
  method: "POST",
622
622
  headers: {
623
623
  "Content-Type": "application/x-www-form-urlencoded"
624
624
  },
625
- body: we({
626
- _wpnonce: a,
625
+ body: ge({
626
+ _wpnonce: p,
627
627
  _wp_http_referer: n + "wp-admin/network.php",
628
628
  sitename: "My WordPress Website Sites",
629
629
  email: "admin@localhost.com",
@@ -632,7 +632,7 @@ echo json_encode($deactivated_plugins);
632
632
  }
633
633
  });
634
634
  if (h.httpStatusCode !== 200)
635
- throw g.warn("WordPress response was", {
635
+ throw y.warn("WordPress response was", {
636
636
  response: h,
637
637
  text: h.text,
638
638
  headers: h.headers
@@ -649,12 +649,12 @@ echo json_encode($deactivated_plugins);
649
649
  PATH_CURRENT_SITE: n
650
650
  }
651
651
  });
652
- const f = new URL(await e.absoluteUrl), d = K(f) ? "scope:" + ee(f) : null;
652
+ const u = new URL(await e.absoluteUrl), a = te(u) ? "scope:" + ne(u) : null;
653
653
  await e.writeFile(
654
654
  "/internal/shared/preload/sunrise.php",
655
655
  `<?php
656
- $_SERVER['HTTP_HOST'] = ${m(f.hostname)};
657
- $folder = ${m(d)};
656
+ $_SERVER['HTTP_HOST'] = ${f(u.hostname)};
657
+ $folder = ${f(a)};
658
658
  if ($folder && strpos($_SERVER['REQUEST_URI'],"/$folder") === false) {
659
659
  $_SERVER['REQUEST_URI'] = "/$folder/" . ltrim($_SERVER['REQUEST_URI'], '/');
660
660
  }
@@ -666,13 +666,13 @@ echo json_encode($deactivated_plugins);
666
666
  define( 'BLOG_ID_CURRENT_SITE', 1 );
667
667
  }
668
668
  `
669
- ), await v(e, {});
670
- for (const w of o)
669
+ ), await R(e, {});
670
+ for (const m of o)
671
671
  await x(e, {
672
- pluginPath: w
672
+ pluginPath: m
673
673
  });
674
674
  };
675
- function we(e) {
675
+ function ge(e) {
676
676
  return Object.keys(e).map(
677
677
  (t) => encodeURIComponent(t) + "=" + encodeURIComponent(e[t])
678
678
  ).join("&");
@@ -682,22 +682,22 @@ const ye = async (e, { fromPath: t, toPath: n }) => {
682
682
  n,
683
683
  await e.readFileAsBuffer(t)
684
684
  );
685
- }, ge = async (e, { fromPath: t, toPath: n }) => {
685
+ }, $e = async (e, { fromPath: t, toPath: n }) => {
686
686
  await e.mv(t, n);
687
- }, $e = async (e, { path: t }) => {
688
- await e.mkdir(t);
689
687
  }, _e = async (e, { path: t }) => {
688
+ await e.mkdir(t);
689
+ }, be = async (e, { path: t }) => {
690
690
  await e.rmdir(t);
691
691
  }, H = async (e, { path: t, data: n }) => {
692
692
  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);
693
- }, z = async (e, { siteUrl: t }) => {
693
+ }, G = async (e, { siteUrl: t }) => {
694
694
  await T(e, {
695
695
  consts: {
696
696
  WP_HOME: t,
697
697
  WP_SITEURL: t
698
698
  }
699
699
  });
700
- }, be = async (e, { file: t }, n) => {
700
+ }, Pe = async (e, { file: t }, n) => {
701
701
  var r;
702
702
  (r = n == null ? void 0 : n.tracker) == null || r.setCaption("Importing content"), await H(e, {
703
703
  path: "/tmp/import.wxr",
@@ -706,8 +706,8 @@ const ye = async (e, { fromPath: t, toPath: n }) => {
706
706
  const i = await e.documentRoot;
707
707
  await e.run({
708
708
  code: `<?php
709
- require ${m(i)} . '/wp-load.php';
710
- require ${m(i)} . '/wp-admin/includes/admin.php';
709
+ require ${f(i)} . '/wp-load.php';
710
+ require ${f(i)} . '/wp-admin/includes/admin.php';
711
711
 
712
712
  kses_remove_filters();
713
713
  $admin_id = get_users(array('role' => 'Administrator') )[0]->ID;
@@ -727,51 +727,105 @@ const ye = async (e, { fromPath: t, toPath: n }) => {
727
727
  $result = $importer->import( '/tmp/import.wxr' );
728
728
  `
729
729
  });
730
+ }, V = async (e, { themeSlug: t = "" }, n) => {
731
+ var r;
732
+ (r = n == null ? void 0 : n.tracker) == null || r.setCaption("Importing theme starter content");
733
+ const i = await e.documentRoot;
734
+ await e.run({
735
+ code: `<?php
736
+
737
+ /**
738
+ * Ensure that the customizer loads as an admin user.
739
+ *
740
+ * For compatibility with themes, this MUST be run prior to theme inclusion, which is why this is a plugins_loaded filter instead
741
+ * of running _wp_customize_include() manually after load.
742
+ */
743
+ function importThemeStarterContent_plugins_loaded() {
744
+ // Set as the admin user, this ensures we can customize the site.
745
+ wp_set_current_user(
746
+ get_users( [ 'role' => 'Administrator' ] )[0]
747
+ );
748
+
749
+ // Force the site to be fresh, although it should already be.
750
+ add_filter( 'pre_option_fresh_site', '__return_true' );
751
+
752
+ /*
753
+ * Simulate this request as the customizer loading with the current theme in preview mode.
754
+ *
755
+ * See _wp_customize_include()
756
+ */
757
+ $_REQUEST['wp_customize'] = 'on';
758
+ $_REQUEST['customize_theme'] = ${f(t)} ?: get_stylesheet();
759
+
760
+ /*
761
+ * Claim this is a ajax request saving settings, to avoid the preview filters being applied.
762
+ */
763
+ $_REQUEST['action'] = 'customize_save';
764
+ add_filter( 'wp_doing_ajax', '__return_true' );
765
+
766
+ $_GET = $_REQUEST;
767
+ }
768
+ playground_add_filter( 'plugins_loaded', 'importThemeStarterContent_plugins_loaded', 0 );
769
+
770
+ require ${f(i)} . '/wp-load.php';
771
+
772
+ // Return early if there's no starter content.
773
+ if ( ! get_theme_starter_content() ) {
774
+ return;
775
+ }
776
+
777
+ // Import the Starter Content.
778
+ $wp_customize->import_theme_starter_content();
779
+
780
+ // Publish the changeset, which publishes the starter content.
781
+ wp_publish_post( $wp_customize->changeset_post_id() );
782
+ `
783
+ });
730
784
  }, L = async (e, { zipFile: t, zipPath: n, extractToPath: i }) => {
731
785
  if (n)
732
- g.warn(
786
+ y.warn(
733
787
  'The "zipPath" option of the unzip() Blueprint step is deprecated and will be removed. Use "zipFile" instead.'
734
788
  );
735
789
  else if (!t)
736
790
  throw new Error("Either zipPath or zipFile must be provided");
737
- await te(e, t || n, i);
738
- }, Pe = async (e, { wordPressFilesZip: t, pathInZip: n = "" }) => {
791
+ await B(e, t || n, i);
792
+ }, Ee = async (e, { wordPressFilesZip: t, pathInZip: n = "" }) => {
739
793
  const i = await e.documentRoot;
740
- let r = u("/tmp", "import");
794
+ let r = w("/tmp", "import");
741
795
  await e.mkdir(r), await L(e, {
742
796
  zipFile: t,
743
797
  extractToPath: r
744
- }), r = u(r, n);
745
- const s = u(r, "wp-content"), o = u(i, "wp-content");
746
- for (const f of B) {
747
- const d = u(
798
+ }), r = w(r, n);
799
+ const s = w(r, "wp-content"), o = w(i, "wp-content");
800
+ for (const u of D) {
801
+ const a = w(
748
802
  s,
749
- f
803
+ u
750
804
  );
751
- await U(e, d);
752
- const l = u(o, f);
753
- await e.fileExists(l) && (await e.mkdir(Z(d)), await e.mv(l, d));
805
+ await U(e, a);
806
+ const l = w(o, u);
807
+ await e.fileExists(l) && (await e.mkdir(J(a)), await e.mv(l, a));
754
808
  }
755
- const c = u(
809
+ const c = w(
756
810
  r,
757
811
  "wp-content",
758
812
  "database"
759
813
  );
760
814
  await e.fileExists(c) || await e.mv(
761
- u(i, "wp-content", "database"),
815
+ w(i, "wp-content", "database"),
762
816
  c
763
817
  );
764
- const a = await e.listFiles(r);
765
- for (const f of a)
766
- await U(e, u(i, f)), await e.mv(
767
- u(r, f),
768
- u(i, f)
818
+ const p = await e.listFiles(r);
819
+ for (const u of p)
820
+ await U(e, w(i, u)), await e.mv(
821
+ w(r, u),
822
+ w(i, u)
769
823
  );
770
- await e.rmdir(r), await z(e, {
824
+ await e.rmdir(r), await G(e, {
771
825
  siteUrl: await e.absoluteUrl
772
826
  });
773
- const h = m(
774
- u(i, "wp-admin", "upgrade.php")
827
+ const h = f(
828
+ w(i, "wp-admin", "upgrade.php")
775
829
  );
776
830
  await e.run({
777
831
  code: `<?php
@@ -783,57 +837,57 @@ const ye = async (e, { fromPath: t, toPath: n }) => {
783
837
  async function U(e, t) {
784
838
  await e.fileExists(t) && (await e.isDir(t) ? await e.rmdir(t) : await e.unlink(t));
785
839
  }
786
- async function Ee(e) {
840
+ async function Te(e) {
787
841
  const t = await e.request({
788
842
  url: "/wp-admin/export.php?download=true&content=all"
789
843
  });
790
844
  return new File([t.bytes], "export.xml");
791
845
  }
792
- async function G(e, {
846
+ async function Q(e, {
793
847
  targetPath: t,
794
848
  zipFile: n,
795
849
  ifAlreadyInstalled: i = "overwrite"
796
850
  }) {
797
- const s = n.name.replace(/\.zip$/, ""), o = u(await e.documentRoot, "wp-content"), c = u(o, X()), a = u(c, "assets", s);
798
- await e.fileExists(a) && await e.rmdir(c, {
851
+ const s = n.name.replace(/\.zip$/, ""), o = w(await e.documentRoot, "wp-content"), c = w(o, K()), p = w(c, "assets", s);
852
+ await e.fileExists(p) && await e.rmdir(c, {
799
853
  recursive: !0
800
854
  }), await e.mkdir(c);
801
855
  try {
802
856
  await L(e, {
803
857
  zipFile: n,
804
- extractToPath: a
858
+ extractToPath: p
805
859
  });
806
- let h = await e.listFiles(a, {
860
+ let h = await e.listFiles(p, {
807
861
  prependPath: !0
808
862
  });
809
863
  h = h.filter((P) => !P.endsWith("/__MACOSX"));
810
- const f = h.length === 1 && await e.isDir(h[0]);
811
- let d, l = "";
812
- f ? (l = h[0], d = h[0].split("/").pop()) : (l = a, d = s);
813
- const w = `${t}/${d}`;
814
- if (await e.fileExists(w)) {
815
- if (!await e.isDir(w))
864
+ const u = h.length === 1 && await e.isDir(h[0]);
865
+ let a, l = "";
866
+ u ? (l = h[0], a = h[0].split("/").pop()) : (l = p, a = s);
867
+ const m = `${t}/${a}`;
868
+ if (await e.fileExists(m)) {
869
+ if (!await e.isDir(m))
816
870
  throw new Error(
817
- `Cannot install asset ${d} to ${w} because a file with the same name already exists. Note it's a file, not a directory! Is this by mistake?`
871
+ `Cannot install asset ${a} to ${m} because a file with the same name already exists. Note it's a file, not a directory! Is this by mistake?`
818
872
  );
819
873
  if (i === "overwrite")
820
- await e.rmdir(w, {
874
+ await e.rmdir(m, {
821
875
  recursive: !0
822
876
  });
823
877
  else {
824
878
  if (i === "skip")
825
879
  return {
826
- assetFolderPath: w,
827
- assetFolderName: d
880
+ assetFolderPath: m,
881
+ assetFolderName: a
828
882
  };
829
883
  throw new Error(
830
- `Cannot install asset ${d} to ${t} because it already exists and the ifAlreadyInstalled option was set to ${i}`
884
+ `Cannot install asset ${a} to ${t} because it already exists and the ifAlreadyInstalled option was set to ${i}`
831
885
  );
832
886
  }
833
887
  }
834
- return await e.mv(l, w), {
835
- assetFolderPath: w,
836
- assetFolderName: d
888
+ return await e.mv(l, m), {
889
+ assetFolderPath: m,
890
+ assetFolderName: a
837
891
  };
838
892
  } finally {
839
893
  await e.rmdir(c, {
@@ -845,10 +899,10 @@ function k(e) {
845
899
  const t = e.split(".").shift().replace(/-/g, " ");
846
900
  return t.charAt(0).toUpperCase() + t.slice(1).toLowerCase();
847
901
  }
848
- const Te = async (e, { pluginZipFile: t, ifAlreadyInstalled: n, options: i = {} }, r) => {
902
+ const ke = async (e, { pluginZipFile: t, ifAlreadyInstalled: n, options: i = {} }, r) => {
849
903
  const s = t.name.split("/").pop() || "plugin.zip", o = k(s);
850
904
  r == null || r.tracker.setCaption(`Installing the ${o} plugin`);
851
- const { assetFolderPath: c } = await G(e, {
905
+ const { assetFolderPath: c } = await Q(e, {
852
906
  ifAlreadyInstalled: n,
853
907
  zipFile: t,
854
908
  targetPath: `${await e.documentRoot}/wp-content/plugins`
@@ -861,10 +915,10 @@ const Te = async (e, { pluginZipFile: t, ifAlreadyInstalled: n, options: i = {}
861
915
  },
862
916
  r
863
917
  );
864
- }, ke = async (e, { themeZipFile: t, ifAlreadyInstalled: n, options: i = {} }, r) => {
918
+ }, ve = async (e, { themeZipFile: t, ifAlreadyInstalled: n, options: i = {} }, r) => {
865
919
  const s = k(t.name);
866
920
  r == null || r.tracker.setCaption(`Installing the ${s} theme`);
867
- const { assetFolderName: o } = await G(e, {
921
+ const { assetFolderName: o } = await Q(e, {
868
922
  ifAlreadyInstalled: n,
869
923
  zipFile: t,
870
924
  targetPath: `${await e.documentRoot}/wp-content/themes`
@@ -875,6 +929,12 @@ const Te = async (e, { pluginZipFile: t, ifAlreadyInstalled: n, options: i = {}
875
929
  themeFolderName: o
876
930
  },
877
931
  r
932
+ ), ("importStarterContent" in i ? i.importStarterContent : !1) && await V(
933
+ e,
934
+ {
935
+ themeSlug: o
936
+ },
937
+ r
878
938
  );
879
939
  }, Re = async (e, t, n) => {
880
940
  var r;
@@ -900,7 +960,7 @@ const Te = async (e, { pluginZipFile: t, ifAlreadyInstalled: n, options: i = {}
900
960
  $GLOBALS['@pdo']->query("UPDATE SQLITE_SEQUENCE SET SEQ=0 WHERE NAME='wp_commentmeta'");
901
961
  `
902
962
  });
903
- }, ve = async (e, { options: t }) => {
963
+ }, Se = async (e, { options: t }) => {
904
964
  await e.request({
905
965
  url: "/wp-admin/install.php?step=2",
906
966
  method: "POST",
@@ -917,24 +977,24 @@ const Te = async (e, { pluginZipFile: t, ifAlreadyInstalled: n, options: i = {}
917
977
  admin_email: "admin@localhost.com"
918
978
  }
919
979
  });
920
- }, Se = async (e, { selfContained: t = !1 } = {}) => {
921
- const n = "/tmp/wordpress-playground.zip", i = await e.documentRoot, r = u(i, "wp-content");
922
- let s = B;
923
- t && (s = s.filter((a) => !a.startsWith("themes/twenty")).filter(
924
- (a) => a !== "mu-plugins/sqlite-database-integration"
980
+ }, xe = async (e, { selfContained: t = !1 } = {}) => {
981
+ const n = "/tmp/wordpress-playground.zip", i = await e.documentRoot, r = w(i, "wp-content");
982
+ let s = D;
983
+ t && (s = s.filter((p) => !p.startsWith("themes/twenty")).filter(
984
+ (p) => p !== "mu-plugins/sqlite-database-integration"
925
985
  ));
926
986
  const o = S({
927
987
  zipPath: n,
928
988
  wpContentPath: r,
929
989
  documentRoot: i,
930
990
  exceptPaths: s.map(
931
- (a) => u(i, "wp-content", a)
991
+ (p) => w(i, "wp-content", p)
932
992
  ),
933
993
  additionalPaths: t ? {
934
- [u(i, "wp-config.php")]: "wp-config.php"
994
+ [w(i, "wp-config.php")]: "wp-config.php"
935
995
  } : {}
936
996
  });
937
- await Le(
997
+ await qe(
938
998
  e,
939
999
  `zipDir(${o.wpContentPath}, ${o.zipPath}, array(
940
1000
  'exclude_paths' => ${o.exceptPaths},
@@ -944,7 +1004,7 @@ const Te = async (e, { pluginZipFile: t, ifAlreadyInstalled: n, options: i = {}
944
1004
  );
945
1005
  const c = await e.readFileAsBuffer(n);
946
1006
  return e.unlink(n), c;
947
- }, xe = `<?php
1007
+ }, Le = `<?php
948
1008
 
949
1009
  function zipDir($root, $output, $options = array())
950
1010
  {
@@ -1004,16 +1064,16 @@ function join_paths()
1004
1064
  return preg_replace('#/+#', '/', join('/', $paths));
1005
1065
  }
1006
1066
  `;
1007
- async function Le(e, t) {
1067
+ async function qe(e, t) {
1008
1068
  return await e.run({
1009
- code: xe + t
1069
+ code: Le + t
1010
1070
  });
1011
1071
  }
1012
- const Oe = async (e, { command: t, wpCliPath: n = "/tmp/wp-cli.phar" }) => {
1072
+ const Ce = async (e, { command: t, wpCliPath: n = "/tmp/wp-cli.phar" }) => {
1013
1073
  if (!await e.fileExists(n))
1014
1074
  throw new Error(`wp-cli.phar not found at ${n}`);
1015
1075
  let i;
1016
- if (typeof t == "string" ? (t = t.trim(), i = qe(t)) : i = t, i.shift() !== "wp")
1076
+ if (typeof t == "string" ? (t = t.trim(), i = Oe(t)) : i = t, i.shift() !== "wp")
1017
1077
  throw new Error('The first argument must be "wp".');
1018
1078
  await e.writeFile("/tmp/stdout", ""), await e.writeFile("/tmp/stderr", ""), await e.writeFile(
1019
1079
  "/wordpress/run-cli.php",
@@ -1030,7 +1090,7 @@ const Oe = async (e, { command: t, wpCliPath: n = "/tmp/wp-cli.phar" }) => {
1030
1090
  $GLOBALS['argv'] = array_merge([
1031
1091
  "/tmp/wp-cli.phar",
1032
1092
  "--path=/wordpress"
1033
- ], ${m(i)});
1093
+ ], ${f(i)});
1034
1094
 
1035
1095
  // Provide stdin, stdout, stderr streams outside of
1036
1096
  // the CLI SAPI.
@@ -1038,7 +1098,7 @@ const Oe = async (e, { command: t, wpCliPath: n = "/tmp/wp-cli.phar" }) => {
1038
1098
  define('STDOUT', fopen('php://stdout', 'wb'));
1039
1099
  define('STDERR', fopen('php://stderr', 'wb'));
1040
1100
 
1041
- require( ${m(n)} );
1101
+ require( ${f(n)} );
1042
1102
  `
1043
1103
  );
1044
1104
  const s = await e.run({
@@ -1048,55 +1108,141 @@ const Oe = async (e, { command: t, wpCliPath: n = "/tmp/wp-cli.phar" }) => {
1048
1108
  throw new Error(s.errors);
1049
1109
  return s;
1050
1110
  };
1051
- function qe(e) {
1111
+ function Oe(e) {
1052
1112
  let i = 0, r = "";
1053
1113
  const s = [];
1054
1114
  let o = "";
1055
1115
  for (let c = 0; c < e.length; c++) {
1056
- const a = e[c];
1057
- i === 0 ? a === '"' || a === "'" ? (i = 1, r = a) : a.match(/\s/) ? (o && s.push(o), o = "") : o += a : i === 1 && (a === "\\" ? (c++, o += e[c]) : a === r ? (i = 0, r = "") : o += a);
1116
+ const p = e[c];
1117
+ i === 0 ? p === '"' || p === "'" ? (i = 1, r = p) : p.match(/\s/) ? (o && s.push(o), o = "") : o += p : i === 1 && (p === "\\" ? (c++, o += e[c]) : p === r ? (i = 0, r = "") : o += p);
1058
1118
  }
1059
1119
  return o && s.push(o), s;
1060
1120
  }
1061
- const je = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1121
+ const je = async (e, { language: t }, n) => {
1122
+ n == null || n.tracker.setCaption((n == null ? void 0 : n.initialCaption) || "Translating"), await e.defineConstant("WPLANG", t);
1123
+ const i = await e.documentRoot, s = [
1124
+ {
1125
+ url: `https://downloads.wordpress.org/translation/core/${(await e.run({
1126
+ code: `<?php
1127
+ require '${i}/wp-includes/version.php';
1128
+ echo $wp_version;
1129
+ `
1130
+ })).text}/${t}.zip`,
1131
+ type: "core"
1132
+ }
1133
+ ], c = (await e.run({
1134
+ code: `<?php
1135
+ require_once('${i}/wp-load.php');
1136
+ require_once('${i}/wp-admin/includes/plugin.php');
1137
+ echo json_encode(
1138
+ array_values(
1139
+ array_map(
1140
+ function($plugin) {
1141
+ return [
1142
+ 'slug' => $plugin['TextDomain'],
1143
+ 'version' => $plugin['Version']
1144
+ ];
1145
+ },
1146
+ array_filter(
1147
+ get_plugins(),
1148
+ function($plugin) {
1149
+ return !empty($plugin['TextDomain']);
1150
+ }
1151
+ )
1152
+ )
1153
+ )
1154
+ );`
1155
+ })).json;
1156
+ for (const { slug: u, version: a } of c)
1157
+ s.push({
1158
+ url: `https://downloads.wordpress.org/translation/plugin/${u}/${a}/${t}.zip`,
1159
+ type: "plugin"
1160
+ });
1161
+ const h = (await e.run({
1162
+ code: `<?php
1163
+ require_once('${i}/wp-load.php');
1164
+ require_once('${i}/wp-admin/includes/theme.php');
1165
+ echo json_encode(
1166
+ array_values(
1167
+ array_map(
1168
+ function($theme) {
1169
+ return [
1170
+ 'slug' => $theme->get('TextDomain'),
1171
+ 'version' => $theme->get('Version')
1172
+ ];
1173
+ },
1174
+ wp_get_themes()
1175
+ )
1176
+ )
1177
+ );`
1178
+ })).json;
1179
+ for (const { slug: u, version: a } of h)
1180
+ s.push({
1181
+ url: `https://downloads.wordpress.org/translation/theme/${u}/${a}/${t}.zip`,
1182
+ type: "theme"
1183
+ });
1184
+ await e.isDir(`${i}/wp-content/languages/plugins`) || await e.mkdir(`${i}/wp-content/languages/plugins`), await e.isDir(`${i}/wp-content/languages/themes`) || await e.mkdir(`${i}/wp-content/languages/themes`);
1185
+ for (const { url: u, type: a } of s)
1186
+ try {
1187
+ const l = await fetch(u);
1188
+ if (!l.ok)
1189
+ throw new Error(
1190
+ `Failed to download translations for ${a}: ${l.statusText}`
1191
+ );
1192
+ let m = `${i}/wp-content/languages`;
1193
+ a === "plugin" ? m += "/plugins" : a === "theme" && (m += "/themes"), await B(
1194
+ e,
1195
+ new File([await l.blob()], `${t}-${a}.zip`),
1196
+ m
1197
+ );
1198
+ } catch (l) {
1199
+ if (a === "core")
1200
+ throw new Error(
1201
+ `Failed to download translations for WordPress. Please check if the language code ${t} is correct. You can find all available languages and translations on https://translate.wordpress.org/.`
1202
+ );
1203
+ y.warn(`Error downloading translations for ${a}: ${l}`);
1204
+ }
1205
+ }, We = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1062
1206
  __proto__: null,
1063
1207
  activatePlugin: x,
1064
1208
  activateTheme: N,
1065
1209
  cp: ye,
1066
- defineSiteUrl: z,
1210
+ defineSiteUrl: G,
1067
1211
  defineWpConfigConsts: T,
1068
- enableMultisite: me,
1069
- exportWXR: Ee,
1070
- importWordPressFiles: Pe,
1071
- importWxr: be,
1072
- installPlugin: Te,
1073
- installTheme: ke,
1074
- login: v,
1075
- mkdir: $e,
1076
- mv: ge,
1077
- request: R,
1212
+ enableMultisite: we,
1213
+ exportWXR: Te,
1214
+ importThemeStarterContent: V,
1215
+ importWordPressFiles: Ee,
1216
+ importWxr: Pe,
1217
+ installPlugin: ke,
1218
+ installTheme: ve,
1219
+ login: R,
1220
+ mkdir: _e,
1221
+ mv: $e,
1222
+ request: v,
1078
1223
  resetData: Re,
1079
- rm: D,
1080
- rmdir: _e,
1081
- runPHP: pe,
1082
- runPHPWithOptions: ce,
1083
- runSql: de,
1084
- runWpInstallationWizard: ve,
1224
+ rm: z,
1225
+ rmdir: be,
1226
+ runPHP: ce,
1227
+ runPHPWithOptions: de,
1228
+ runSql: le,
1229
+ runWpInstallationWizard: Se,
1230
+ setSiteLanguage: je,
1085
1231
  setSiteOptions: M,
1086
1232
  unzip: L,
1087
- updateUserMeta: fe,
1088
- wpCLI: Oe,
1233
+ updateUserMeta: me,
1234
+ wpCLI: Ce,
1089
1235
  writeFile: H,
1090
- zipWpContent: Se
1091
- }, Symbol.toStringTag, { value: "Module" })), Ce = [
1236
+ zipWpContent: xe
1237
+ }, Symbol.toStringTag, { value: "Module" })), Ie = [
1092
1238
  "vfs",
1093
1239
  "literal",
1094
1240
  "wordpress.org/themes",
1095
1241
  "wordpress.org/plugins",
1096
1242
  "url"
1097
1243
  ];
1098
- function We(e) {
1099
- return e && typeof e == "object" && typeof e.resource == "string" && Ce.includes(e.resource);
1244
+ function Ue(e) {
1245
+ return e && typeof e == "object" && typeof e.resource == "string" && Ie.includes(e.resource);
1100
1246
  }
1101
1247
  class b {
1102
1248
  /**
@@ -1110,24 +1256,24 @@ class b {
1110
1256
  let r;
1111
1257
  switch (t.resource) {
1112
1258
  case "vfs":
1113
- r = new Ie(t, i);
1259
+ r = new Fe(t, i);
1114
1260
  break;
1115
1261
  case "literal":
1116
- r = new Ue(t, i);
1262
+ r = new Ae(t, i);
1117
1263
  break;
1118
1264
  case "wordpress.org/themes":
1119
- r = new Be(t, i);
1265
+ r = new Ne(t, i);
1120
1266
  break;
1121
1267
  case "wordpress.org/plugins":
1122
- r = new Ne(t, i);
1268
+ r = new ze(t, i);
1123
1269
  break;
1124
1270
  case "url":
1125
- r = new Ae(t, i);
1271
+ r = new De(t, i);
1126
1272
  break;
1127
1273
  default:
1128
1274
  throw new Error(`Invalid resource: ${t}`);
1129
1275
  }
1130
- return r = new De(r), n && (r = new Me(r, n)), r;
1276
+ return r = new Me(r), n && (r = new He(r, n)), r;
1131
1277
  }
1132
1278
  setPlayground(t) {
1133
1279
  this.playground = t;
@@ -1137,7 +1283,7 @@ class b {
1137
1283
  return !1;
1138
1284
  }
1139
1285
  }
1140
- class Ie extends b {
1286
+ class Fe extends b {
1141
1287
  /**
1142
1288
  * Creates a new instance of `VFSResource`.
1143
1289
  * @param playground The playground client.
@@ -1160,7 +1306,7 @@ class Ie extends b {
1160
1306
  return this.resource.path.split("/").pop() || "";
1161
1307
  }
1162
1308
  }
1163
- class Ue extends b {
1309
+ class Ae extends b {
1164
1310
  /**
1165
1311
  * Creates a new instance of `LiteralResource`.
1166
1312
  * @param resource The literal reference.
@@ -1179,7 +1325,7 @@ class Ue extends b {
1179
1325
  return this.resource.name;
1180
1326
  }
1181
1327
  }
1182
- class O extends b {
1328
+ class q extends b {
1183
1329
  /**
1184
1330
  * Creates a new instance of `FetchResource`.
1185
1331
  * @param progress The progress tracker.
@@ -1196,9 +1342,9 @@ class O extends b {
1196
1342
  let r = await fetch(t);
1197
1343
  if (!r.ok)
1198
1344
  throw new Error(`Could not download "${t}"`);
1199
- if (r = await ne(
1345
+ if (r = await ie(
1200
1346
  r,
1201
- ((i = this.progress) == null ? void 0 : i.loadingListener) ?? Fe
1347
+ ((i = this.progress) == null ? void 0 : i.loadingListener) ?? Be
1202
1348
  ), r.status !== 200)
1203
1349
  throw new Error(`Could not download "${t}"`);
1204
1350
  return new File([await r.blob()], this.name);
@@ -1252,9 +1398,9 @@ class O extends b {
1252
1398
  return !0;
1253
1399
  }
1254
1400
  }
1255
- const Fe = () => {
1401
+ const Be = () => {
1256
1402
  };
1257
- class Ae extends O {
1403
+ class De extends q {
1258
1404
  /**
1259
1405
  * Creates a new instance of `UrlResource`.
1260
1406
  * @param resource The URL reference.
@@ -1272,7 +1418,7 @@ class Ae extends O {
1272
1418
  return this.resource.caption ?? super.caption;
1273
1419
  }
1274
1420
  }
1275
- class Be extends O {
1421
+ class Ne extends q {
1276
1422
  constructor(t, n) {
1277
1423
  super(n), this.resource = t;
1278
1424
  }
@@ -1280,10 +1426,10 @@ class Be extends O {
1280
1426
  return k(this.resource.slug);
1281
1427
  }
1282
1428
  getURL() {
1283
- return `https://downloads.wordpress.org/theme/${V(this.resource.slug)}`;
1429
+ return `https://downloads.wordpress.org/theme/${Y(this.resource.slug)}`;
1284
1430
  }
1285
1431
  }
1286
- class Ne extends O {
1432
+ class ze extends q {
1287
1433
  constructor(t, n) {
1288
1434
  super(n), this.resource = t;
1289
1435
  }
@@ -1293,13 +1439,13 @@ class Ne extends O {
1293
1439
  }
1294
1440
  /** @inheritDoc */
1295
1441
  getURL() {
1296
- return `https://downloads.wordpress.org/plugin/${V(this.resource.slug)}`;
1442
+ return `https://downloads.wordpress.org/plugin/${Y(this.resource.slug)}`;
1297
1443
  }
1298
1444
  }
1299
- function V(e) {
1445
+ function Y(e) {
1300
1446
  return !e || e.endsWith(".zip") ? e : e + ".latest-stable.zip";
1301
1447
  }
1302
- class Q extends b {
1448
+ class Z extends b {
1303
1449
  constructor(t) {
1304
1450
  super(), this.resource = t;
1305
1451
  }
@@ -1328,13 +1474,13 @@ class Q extends b {
1328
1474
  return this.resource.isAsync;
1329
1475
  }
1330
1476
  }
1331
- class De extends Q {
1477
+ class Me extends Z {
1332
1478
  /** @inheritDoc */
1333
1479
  async resolve() {
1334
1480
  return this.promise || (this.promise = super.resolve()), this.promise;
1335
1481
  }
1336
1482
  }
1337
- class Me extends Q {
1483
+ class He extends Z {
1338
1484
  constructor(t, n) {
1339
1485
  super(t), this.semaphore = n;
1340
1486
  }
@@ -1343,7 +1489,7 @@ class Me extends Q {
1343
1489
  return this.isAsync ? this.semaphore.run(() => super.resolve()) : super.resolve();
1344
1490
  }
1345
1491
  }
1346
- const He = "http://json-schema.org/schema", ze = "#/definitions/Blueprint", Ge = {
1492
+ const Ge = "http://json-schema.org/schema", Ve = "#/definitions/Blueprint", Qe = {
1347
1493
  Blueprint: {
1348
1494
  type: "object",
1349
1495
  properties: {
@@ -1428,8 +1574,7 @@ const He = "http://json-schema.org/schema", ze = "#/definitions/Blueprint", Ge =
1428
1574
  additionalProperties: {
1429
1575
  type: "string"
1430
1576
  },
1431
- description: "PHP Constants to define on every request",
1432
- deprecated: "This experimental option will change without warning.\nUse `steps` instead."
1577
+ description: "PHP Constants to define on every request"
1433
1578
  },
1434
1579
  plugins: {
1435
1580
  type: "array",
@@ -1443,8 +1588,7 @@ const He = "http://json-schema.org/schema", ze = "#/definitions/Blueprint", Ge =
1443
1588
  }
1444
1589
  ]
1445
1590
  },
1446
- description: "WordPress plugins to install and activate",
1447
- deprecated: "This experimental option will change without warning.\nUse `steps` instead."
1591
+ description: "WordPress plugins to install and activate"
1448
1592
  },
1449
1593
  siteOptions: {
1450
1594
  type: "object",
@@ -1457,8 +1601,7 @@ const He = "http://json-schema.org/schema", ze = "#/definitions/Blueprint", Ge =
1457
1601
  description: "The site title"
1458
1602
  }
1459
1603
  },
1460
- description: "WordPress site options to define",
1461
- deprecated: "This experimental option will change without warning.\nUse `steps` instead."
1604
+ description: "WordPress site options to define"
1462
1605
  },
1463
1606
  login: {
1464
1607
  anyOf: [
@@ -1950,6 +2093,37 @@ for existing apps using this option.`
1950
2093
  "step"
1951
2094
  ]
1952
2095
  },
2096
+ {
2097
+ type: "object",
2098
+ additionalProperties: !1,
2099
+ properties: {
2100
+ progress: {
2101
+ type: "object",
2102
+ properties: {
2103
+ weight: {
2104
+ type: "number"
2105
+ },
2106
+ caption: {
2107
+ type: "string"
2108
+ }
2109
+ },
2110
+ additionalProperties: !1
2111
+ },
2112
+ step: {
2113
+ type: "string",
2114
+ const: "importThemeStarterContent",
2115
+ description: "The step identifier."
2116
+ },
2117
+ themeSlug: {
2118
+ type: "string",
2119
+ description: "The name of the theme to import content from."
2120
+ }
2121
+ },
2122
+ required: [
2123
+ "step",
2124
+ "themeSlug"
2125
+ ]
2126
+ },
1953
2127
  {
1954
2128
  type: "object",
1955
2129
  additionalProperties: !1,
@@ -2068,6 +2242,10 @@ for existing apps using this option.`
2068
2242
  activate: {
2069
2243
  type: "boolean",
2070
2244
  description: "Whether to activate the theme after installing it."
2245
+ },
2246
+ importStarterContent: {
2247
+ type: "boolean",
2248
+ description: "Whether to import the theme's starter content after installing it."
2071
2249
  }
2072
2250
  },
2073
2251
  additionalProperties: !1,
@@ -2645,6 +2823,36 @@ for existing apps using this option.`
2645
2823
  "command",
2646
2824
  "step"
2647
2825
  ]
2826
+ },
2827
+ {
2828
+ type: "object",
2829
+ additionalProperties: !1,
2830
+ properties: {
2831
+ progress: {
2832
+ type: "object",
2833
+ properties: {
2834
+ weight: {
2835
+ type: "number"
2836
+ },
2837
+ caption: {
2838
+ type: "string"
2839
+ }
2840
+ },
2841
+ additionalProperties: !1
2842
+ },
2843
+ step: {
2844
+ type: "string",
2845
+ const: "setSiteLanguage"
2846
+ },
2847
+ language: {
2848
+ type: "string",
2849
+ description: "The language to set, e.g. 'en_US'"
2850
+ }
2851
+ },
2852
+ required: [
2853
+ "language",
2854
+ "step"
2855
+ ]
2648
2856
  }
2649
2857
  ]
2650
2858
  },
@@ -2924,28 +3132,28 @@ for existing apps using this option.`
2924
3132
  },
2925
3133
  additionalProperties: !1
2926
3134
  }
2927
- }, Ve = {
2928
- $schema: He,
2929
- $ref: ze,
2930
- definitions: Ge
2931
- }, { wpCLI: Qe, ...F } = je, Ye = {
3135
+ }, Ye = {
3136
+ $schema: Ge,
3137
+ $ref: Ve,
3138
+ definitions: Qe
3139
+ }, { wpCLI: Ze, ...F } = We, Xe = {
2932
3140
  ...F,
2933
- "wp-cli": Qe,
3141
+ "wp-cli": Ze,
2934
3142
  importFile: F.importWxr
2935
3143
  };
2936
- function ut(e, {
2937
- progress: t = new ie(),
2938
- semaphore: n = new J({ concurrency: 3 }),
3144
+ function ft(e, {
3145
+ progress: t = new re(),
3146
+ semaphore: n = new ee({ concurrency: 3 }),
2939
3147
  onStepCompleted: i = () => {
2940
3148
  }
2941
3149
  } = {}) {
2942
- var d, l, w, P, q, j, C;
3150
+ var a, l, m, P, C, O, j;
2943
3151
  e = {
2944
3152
  ...e,
2945
- steps: (e.steps || []).filter(et).filter(tt)
3153
+ steps: (e.steps || []).filter(nt).filter(it)
2946
3154
  };
2947
- for (const p of e.steps)
2948
- typeof p == "object" && p.step === "importFile" && (p.step = "importWxr", g.warn(
3155
+ for (const d of e.steps)
3156
+ typeof d == "object" && d.step === "importFile" && (d.step = "importWxr", y.warn(
2949
3157
  'The "importFile" step is deprecated. Use "importWxr" instead.'
2950
3158
  ));
2951
3159
  if (e.constants && e.steps.unshift({
@@ -2955,28 +3163,28 @@ function ut(e, {
2955
3163
  step: "setSiteOptions",
2956
3164
  options: e.siteOptions
2957
3165
  }), e.plugins) {
2958
- const p = e.plugins.map((y) => typeof y == "string" ? y.startsWith("https://") ? {
3166
+ const d = e.plugins.map((g) => typeof g == "string" ? g.startsWith("https://") ? {
2959
3167
  resource: "url",
2960
- url: y
3168
+ url: g
2961
3169
  } : {
2962
3170
  resource: "wordpress.org/plugins",
2963
- slug: y
2964
- } : y).map((y) => ({
3171
+ slug: g
3172
+ } : g).map((g) => ({
2965
3173
  step: "installPlugin",
2966
- pluginZipFile: y
3174
+ pluginZipFile: g
2967
3175
  }));
2968
- e.steps.unshift(...p);
3176
+ e.steps.unshift(...d);
2969
3177
  }
2970
3178
  e.login && e.steps.push({
2971
3179
  step: "login",
2972
3180
  ...e.login === !0 ? { username: "admin", password: "password" } : e.login
2973
3181
  }), e.phpExtensionBundles || (e.phpExtensionBundles = []), e.phpExtensionBundles || (e.phpExtensionBundles = []), e.phpExtensionBundles.length === 0 && e.phpExtensionBundles.push("kitchen-sink");
2974
- const r = (d = e.steps) == null ? void 0 : d.findIndex(
2975
- (p) => typeof p == "object" && (p == null ? void 0 : p.step) === "wp-cli"
3182
+ const r = (a = e.steps) == null ? void 0 : a.findIndex(
3183
+ (d) => typeof d == "object" && (d == null ? void 0 : d.step) === "wp-cli"
2976
3184
  );
2977
3185
  r !== void 0 && r > -1 && (e.phpExtensionBundles.includes("light") && (e.phpExtensionBundles = e.phpExtensionBundles.filter(
2978
- (p) => p !== "light"
2979
- ), g.warn(
3186
+ (d) => d !== "light"
3187
+ ), y.warn(
2980
3188
  "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. "
2981
3189
  )), (l = e.steps) == null || l.splice(r, 0, {
2982
3190
  step: "writeFile",
@@ -2996,12 +3204,12 @@ function ut(e, {
2996
3204
  },
2997
3205
  path: "/tmp/wp-cli.phar"
2998
3206
  }));
2999
- const s = (w = e.steps) == null ? void 0 : w.findIndex(
3000
- (p) => typeof p == "object" && (p == null ? void 0 : p.step) === "importWxr"
3207
+ const s = (m = e.steps) == null ? void 0 : m.findIndex(
3208
+ (d) => typeof d == "object" && (d == null ? void 0 : d.step) === "importWxr"
3001
3209
  );
3002
3210
  s !== void 0 && s > -1 && (e.phpExtensionBundles.includes("light") && (e.phpExtensionBundles = e.phpExtensionBundles.filter(
3003
- (p) => p !== "light"
3004
- ), g.warn(
3211
+ (d) => d !== "light"
3212
+ ), y.warn(
3005
3213
  "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. "
3006
3214
  )), (P = e.steps) == null || P.splice(s, 0, {
3007
3215
  step: "installPlugin",
@@ -3011,21 +3219,21 @@ function ut(e, {
3011
3219
  caption: "Downloading the WordPress Importer plugin"
3012
3220
  }
3013
3221
  }));
3014
- const { valid: o, errors: c } = Xe(e);
3222
+ const { valid: o, errors: c } = Ke(e);
3015
3223
  if (!o) {
3016
- const p = new Error(
3224
+ const d = new Error(
3017
3225
  `Invalid blueprint: ${c[0].message} at ${c[0].instancePath}`
3018
3226
  );
3019
- throw p.errors = c, p;
3227
+ throw d.errors = c, d;
3020
3228
  }
3021
- const a = e.steps || [], h = a.reduce(
3022
- (p, y) => {
3229
+ const p = e.steps || [], h = p.reduce(
3230
+ (d, g) => {
3023
3231
  var $;
3024
- return p + ((($ = y.progress) == null ? void 0 : $.weight) || 1);
3232
+ return d + ((($ = g.progress) == null ? void 0 : $.weight) || 1);
3025
3233
  },
3026
3234
  0
3027
- ), f = a.map(
3028
- (p) => nt(p, {
3235
+ ), u = p.map(
3236
+ (d) => rt(d, {
3029
3237
  semaphore: n,
3030
3238
  rootProgressTracker: t,
3031
3239
  totalProgressWeight: h
@@ -3033,33 +3241,33 @@ function ut(e, {
3033
3241
  );
3034
3242
  return {
3035
3243
  versions: {
3036
- php: Je(
3037
- (q = e.preferredVersions) == null ? void 0 : q.php,
3038
- oe,
3039
- se
3244
+ php: et(
3245
+ (C = e.preferredVersions) == null ? void 0 : C.php,
3246
+ ae,
3247
+ oe
3040
3248
  ),
3041
- wp: ((j = e.preferredVersions) == null ? void 0 : j.wp) || "latest"
3249
+ wp: ((O = e.preferredVersions) == null ? void 0 : O.wp) || "latest"
3042
3250
  },
3043
- phpExtensions: Ke(
3251
+ phpExtensions: tt(
3044
3252
  [],
3045
3253
  e.phpExtensionBundles || []
3046
3254
  ),
3047
3255
  features: {
3048
3256
  // Disable networking by default
3049
- networking: ((C = e.features) == null ? void 0 : C.networking) ?? !1
3257
+ networking: ((j = e.features) == null ? void 0 : j.networking) ?? !1
3050
3258
  },
3051
- run: async (p) => {
3259
+ run: async (d) => {
3052
3260
  try {
3053
- for (const { resources: y } of f)
3054
- for (const $ of y)
3055
- $.setPlayground(p), $.isAsync && $.resolve();
3056
- for (const [y, { run: $, step: W }] of Object.entries(f))
3261
+ for (const { resources: g } of u)
3262
+ for (const $ of g)
3263
+ $.setPlayground(d), $.isAsync && $.resolve();
3264
+ for (const [g, { run: $, step: W }] of Object.entries(u))
3057
3265
  try {
3058
- const _ = await $(p);
3266
+ const _ = await $(d);
3059
3267
  i(_, W);
3060
3268
  } catch (_) {
3061
- throw g.error(_), new Error(
3062
- `Error when executing the blueprint step #${y} (${JSON.stringify(
3269
+ throw y.error(_), new Error(
3270
+ `Error when executing the blueprint step #${g} (${JSON.stringify(
3063
3271
  W
3064
3272
  )}) ${_ instanceof Error ? `: ${_.message}` : _}`,
3065
3273
  { cause: _ }
@@ -3067,7 +3275,7 @@ function ut(e, {
3067
3275
  }
3068
3276
  } finally {
3069
3277
  try {
3070
- await p.goTo(
3278
+ await d.goTo(
3071
3279
  e.landingPage || "/"
3072
3280
  );
3073
3281
  } catch {
@@ -3077,11 +3285,11 @@ function ut(e, {
3077
3285
  }
3078
3286
  };
3079
3287
  }
3080
- const Ze = new ae({ discriminator: !0 });
3288
+ const Je = new pe({ discriminator: !0 });
3081
3289
  let E;
3082
- function Xe(e) {
3290
+ function Ke(e) {
3083
3291
  var r;
3084
- E = Ze.compile(Ve);
3292
+ E = Je.compile(Ye);
3085
3293
  const t = E(e);
3086
3294
  if (t)
3087
3295
  return { valid: t };
@@ -3096,46 +3304,46 @@ function Xe(e) {
3096
3304
  errors: i
3097
3305
  };
3098
3306
  }
3099
- function Je(e, t, n) {
3307
+ function et(e, t, n) {
3100
3308
  return e && t.includes(e) ? e : n;
3101
3309
  }
3102
- function Ke(e, t) {
3103
- const n = re.filter(
3310
+ function tt(e, t) {
3311
+ const n = se.filter(
3104
3312
  (r) => e.includes(r)
3105
3313
  ), i = t.flatMap(
3106
3314
  (r) => r in I ? I[r] : []
3107
3315
  );
3108
3316
  return Array.from(/* @__PURE__ */ new Set([...n, ...i]));
3109
3317
  }
3110
- function et(e) {
3318
+ function nt(e) {
3111
3319
  return !!(typeof e == "object" && e);
3112
3320
  }
3113
- function tt(e) {
3114
- return ["setPhpIniEntry", "request"].includes(e.step) ? (g.warn(
3321
+ function it(e) {
3322
+ return ["setPhpIniEntry", "request"].includes(e.step) ? (y.warn(
3115
3323
  `The "${e.step}" Blueprint is no longer supported and you can remove it from your Blueprint.`
3116
3324
  ), !1) : !0;
3117
3325
  }
3118
- function nt(e, {
3326
+ function rt(e, {
3119
3327
  semaphore: t,
3120
3328
  rootProgressTracker: n,
3121
3329
  totalProgressWeight: i
3122
3330
  }) {
3123
- var f;
3331
+ var u;
3124
3332
  const r = n.stage(
3125
- (((f = e.progress) == null ? void 0 : f.weight) || 1) / i
3333
+ (((u = e.progress) == null ? void 0 : u.weight) || 1) / i
3126
3334
  ), s = {};
3127
- for (const d of Object.keys(e)) {
3128
- let l = e[d];
3129
- We(l) && (l = b.create(l, {
3335
+ for (const a of Object.keys(e)) {
3336
+ let l = e[a];
3337
+ Ue(l) && (l = b.create(l, {
3130
3338
  semaphore: t
3131
- })), s[d] = l;
3339
+ })), s[a] = l;
3132
3340
  }
3133
- const o = async (d) => {
3341
+ const o = async (a) => {
3134
3342
  var l;
3135
3343
  try {
3136
- return r.fillSlowly(), await Ye[e.step](
3137
- d,
3138
- await it(s),
3344
+ return r.fillSlowly(), await Xe[e.step](
3345
+ a,
3346
+ await st(s),
3139
3347
  {
3140
3348
  tracker: r,
3141
3349
  initialCaption: (l = e.progress) == null ? void 0 : l.caption
@@ -3144,11 +3352,11 @@ function nt(e, {
3144
3352
  } finally {
3145
3353
  r.finish();
3146
3354
  }
3147
- }, c = A(s), a = A(s).filter(
3148
- (d) => d.isAsync
3149
- ), h = 1 / (a.length + 1);
3150
- for (const d of a)
3151
- d.progress = r.stage(h);
3355
+ }, c = A(s), p = A(s).filter(
3356
+ (a) => a.isAsync
3357
+ ), h = 1 / (p.length + 1);
3358
+ for (const a of p)
3359
+ a.progress = r.stage(h);
3152
3360
  return { run: o, step: e, resources: c };
3153
3361
  }
3154
3362
  function A(e) {
@@ -3159,7 +3367,7 @@ function A(e) {
3159
3367
  }
3160
3368
  return t;
3161
3369
  }
3162
- async function it(e) {
3370
+ async function st(e) {
3163
3371
  const t = {};
3164
3372
  for (const n in e) {
3165
3373
  const i = e[n];
@@ -3167,42 +3375,44 @@ async function it(e) {
3167
3375
  }
3168
3376
  return t;
3169
3377
  }
3170
- async function ht(e, t) {
3378
+ async function mt(e, t) {
3171
3379
  await e.run(t);
3172
3380
  }
3173
- function ft() {
3381
+ function wt() {
3174
3382
  }
3175
3383
  export {
3176
3384
  x as activatePlugin,
3177
3385
  N as activateTheme,
3178
- ut as compileBlueprint,
3386
+ ft as compileBlueprint,
3179
3387
  ye as cp,
3180
- z as defineSiteUrl,
3388
+ G as defineSiteUrl,
3181
3389
  T as defineWpConfigConsts,
3182
- me as enableMultisite,
3183
- Ee as exportWXR,
3184
- Pe as importWordPressFiles,
3185
- be as importWxr,
3186
- Te as installPlugin,
3187
- ke as installTheme,
3188
- v as login,
3189
- $e as mkdir,
3190
- ge as mv,
3191
- R as request,
3390
+ we as enableMultisite,
3391
+ Te as exportWXR,
3392
+ V as importThemeStarterContent,
3393
+ Ee as importWordPressFiles,
3394
+ Pe as importWxr,
3395
+ ke as installPlugin,
3396
+ ve as installTheme,
3397
+ R as login,
3398
+ _e as mkdir,
3399
+ $e as mv,
3400
+ v as request,
3192
3401
  Re as resetData,
3193
- D as rm,
3194
- _e as rmdir,
3195
- ht as runBlueprintSteps,
3196
- pe as runPHP,
3197
- ce as runPHPWithOptions,
3198
- de as runSql,
3199
- ve as runWpInstallationWizard,
3200
- ft as setPluginProxyURL,
3402
+ z as rm,
3403
+ be as rmdir,
3404
+ mt as runBlueprintSteps,
3405
+ ce as runPHP,
3406
+ de as runPHPWithOptions,
3407
+ le as runSql,
3408
+ Se as runWpInstallationWizard,
3409
+ wt as setPluginProxyURL,
3410
+ je as setSiteLanguage,
3201
3411
  M as setSiteOptions,
3202
3412
  L as unzip,
3203
- fe as updateUserMeta,
3204
- Oe as wpCLI,
3205
- B as wpContentFilesExcludedFromExport,
3413
+ me as updateUserMeta,
3414
+ Ce as wpCLI,
3415
+ D as wpContentFilesExcludedFromExport,
3206
3416
  H as writeFile,
3207
- Se as zipWpContent
3417
+ xe as zipWpContent
3208
3418
  };