@styleflow.app/flowpress-deploy 1.0.0-beta.3 → 1.0.0-beta.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/CHANGELOG.md +162 -0
  2. package/README.md +5 -0
  3. package/composer.json +1 -1
  4. package/containers/cms/Dockerfile +35 -0
  5. package/containers/cms/Dockerfile.dockerignore +20 -0
  6. package/containers/cms/healthz.php +17 -0
  7. package/containers/cms/install-languages.sh +16 -0
  8. package/containers/cms/mpm.conf +10 -0
  9. package/containers/cms/php.ini +16 -0
  10. package/containers/cms/sanitize-integrations.php +14 -0
  11. package/containers/cms/sanitize.php +40 -0
  12. package/containers/cms/smtp.php +13 -0
  13. package/containers/cms/vhost.conf +61 -0
  14. package/containers/cms/wp-cli.yml +1 -0
  15. package/containers/local/cms/Dockerfile +18 -0
  16. package/containers/local/cms/entrypoint.sh +7 -0
  17. package/containers/local/cms/php.ini +8 -0
  18. package/containers/local/cms/vhost.conf +14 -0
  19. package/containers/local/runtimes.json +14 -0
  20. package/containers/local/web/Dockerfile +8 -0
  21. package/containers/local/web/entrypoint.sh +21 -0
  22. package/containers/php-runtime/Dockerfile +21 -0
  23. package/containers/web-ssr/Dockerfile +27 -0
  24. package/containers/web-ssr/Dockerfile.dockerignore +10 -0
  25. package/containers/web-static/Caddyfile +40 -0
  26. package/containers/web-static/Dockerfile +17 -0
  27. package/containers/web-static/Dockerfile.dockerignore +7 -0
  28. package/dist/development.d.ts +12 -0
  29. package/dist/development.d.ts.map +1 -0
  30. package/dist/development.js +57 -0
  31. package/dist/development.js.map +1 -0
  32. package/dist/node-fetch.d.ts +3 -0
  33. package/dist/node-fetch.d.ts.map +1 -0
  34. package/dist/node-fetch.js +20 -0
  35. package/dist/node-fetch.js.map +1 -0
  36. package/dist/ops/bootstrap.d.ts +24 -0
  37. package/dist/ops/bootstrap.d.ts.map +1 -0
  38. package/dist/ops/bootstrap.js +156 -0
  39. package/dist/ops/bootstrap.js.map +1 -0
  40. package/dist/ops/build.d.ts +45 -0
  41. package/dist/ops/build.d.ts.map +1 -0
  42. package/dist/ops/build.js +119 -0
  43. package/dist/ops/build.js.map +1 -0
  44. package/dist/ops/check.d.ts +14 -0
  45. package/dist/ops/check.d.ts.map +1 -0
  46. package/dist/ops/check.js +42 -0
  47. package/dist/ops/check.js.map +1 -0
  48. package/dist/ops/cli.d.ts +3 -0
  49. package/dist/ops/cli.d.ts.map +1 -0
  50. package/dist/ops/cli.js +198 -0
  51. package/dist/ops/cli.js.map +1 -0
  52. package/dist/ops/cms-migrate.d.ts +14 -0
  53. package/dist/ops/cms-migrate.d.ts.map +1 -0
  54. package/dist/ops/cms-migrate.js +133 -0
  55. package/dist/ops/cms-migrate.js.map +1 -0
  56. package/dist/ops/cms-template/command.d.mts +19 -0
  57. package/dist/ops/cms-template/command.d.mts.map +1 -0
  58. package/dist/ops/cms-template/command.mjs +145 -0
  59. package/dist/ops/cms-template/command.mjs.map +1 -0
  60. package/dist/ops/cms-template/confirm.d.mts +11 -0
  61. package/dist/ops/cms-template/confirm.d.mts.map +1 -0
  62. package/dist/ops/cms-template/confirm.mjs +18 -0
  63. package/dist/ops/cms-template/confirm.mjs.map +1 -0
  64. package/dist/ops/cms-template/entry.d.mts +2 -0
  65. package/dist/ops/cms-template/entry.d.mts.map +1 -0
  66. package/dist/ops/cms-template/entry.mjs +22 -0
  67. package/dist/ops/cms-template/entry.mjs.map +1 -0
  68. package/dist/ops/cms-template/git.d.mts +7 -0
  69. package/dist/ops/cms-template/git.d.mts.map +1 -0
  70. package/dist/ops/cms-template/git.mjs +22 -0
  71. package/dist/ops/cms-template/git.mjs.map +1 -0
  72. package/dist/ops/cms-template/plan.d.mts +7 -0
  73. package/dist/ops/cms-template/plan.d.mts.map +1 -0
  74. package/dist/ops/cms-template/plan.mjs +54 -0
  75. package/dist/ops/cms-template/plan.mjs.map +1 -0
  76. package/dist/ops/cms-template/store.d.mts +21 -0
  77. package/dist/ops/cms-template/store.d.mts.map +1 -0
  78. package/dist/ops/cms-template/store.mjs +184 -0
  79. package/dist/ops/cms-template/store.mjs.map +1 -0
  80. package/dist/ops/cms-template/target.d.mts +15 -0
  81. package/dist/ops/cms-template/target.d.mts.map +1 -0
  82. package/dist/ops/cms-template/target.mjs +24 -0
  83. package/dist/ops/cms-template/target.mjs.map +1 -0
  84. package/dist/ops/cms-template/transport.d.mts +26 -0
  85. package/dist/ops/cms-template/transport.d.mts.map +1 -0
  86. package/dist/ops/cms-template/transport.mjs +115 -0
  87. package/dist/ops/cms-template/transport.mjs.map +1 -0
  88. package/dist/ops/config.d.ts +54 -0
  89. package/dist/ops/config.d.ts.map +1 -0
  90. package/dist/ops/config.js +221 -0
  91. package/dist/ops/config.js.map +1 -0
  92. package/dist/ops/coolify.d.ts +2 -0
  93. package/dist/ops/coolify.d.ts.map +1 -0
  94. package/dist/ops/coolify.js +44 -0
  95. package/dist/ops/coolify.js.map +1 -0
  96. package/dist/ops/data.d.ts +31 -0
  97. package/dist/ops/data.d.ts.map +1 -0
  98. package/dist/ops/data.js +165 -0
  99. package/dist/ops/data.js.map +1 -0
  100. package/dist/ops/deploy.d.ts +38 -0
  101. package/dist/ops/deploy.d.ts.map +1 -0
  102. package/dist/ops/deploy.js +127 -0
  103. package/dist/ops/deploy.js.map +1 -0
  104. package/dist/ops/editorial.d.ts +23 -0
  105. package/dist/ops/editorial.d.ts.map +1 -0
  106. package/dist/ops/editorial.js +79 -0
  107. package/dist/ops/editorial.js.map +1 -0
  108. package/dist/ops/environment-files.d.ts +9 -0
  109. package/dist/ops/environment-files.d.ts.map +1 -0
  110. package/dist/ops/environment-files.js +127 -0
  111. package/dist/ops/environment-files.js.map +1 -0
  112. package/dist/ops/environment.d.ts +31 -0
  113. package/dist/ops/environment.d.ts.map +1 -0
  114. package/dist/ops/environment.js +165 -0
  115. package/dist/ops/environment.js.map +1 -0
  116. package/dist/ops/features.d.ts +12 -0
  117. package/dist/ops/features.d.ts.map +1 -0
  118. package/dist/ops/features.js +71 -0
  119. package/dist/ops/features.js.map +1 -0
  120. package/dist/ops/health.d.ts +26 -0
  121. package/dist/ops/health.d.ts.map +1 -0
  122. package/dist/ops/health.js +27 -0
  123. package/dist/ops/health.js.map +1 -0
  124. package/dist/ops/local.d.ts +198 -0
  125. package/dist/ops/local.d.ts.map +1 -0
  126. package/dist/ops/local.js +187 -0
  127. package/dist/ops/local.js.map +1 -0
  128. package/dist/ops/media-config.d.ts +61 -0
  129. package/dist/ops/media-config.d.ts.map +1 -0
  130. package/dist/ops/media-config.js +96 -0
  131. package/dist/ops/media-config.js.map +1 -0
  132. package/dist/ops/media.d.ts +47 -0
  133. package/dist/ops/media.d.ts.map +1 -0
  134. package/dist/ops/media.js +81 -0
  135. package/dist/ops/media.js.map +1 -0
  136. package/dist/ops/monitor.d.ts +25 -0
  137. package/dist/ops/monitor.d.ts.map +1 -0
  138. package/dist/ops/monitor.js +143 -0
  139. package/dist/ops/monitor.js.map +1 -0
  140. package/dist/ops/process.d.ts +9 -0
  141. package/dist/ops/process.d.ts.map +1 -0
  142. package/dist/ops/process.js +56 -0
  143. package/dist/ops/process.js.map +1 -0
  144. package/dist/ops/provision.d.ts +41 -0
  145. package/dist/ops/provision.d.ts.map +1 -0
  146. package/dist/ops/provision.js +268 -0
  147. package/dist/ops/provision.js.map +1 -0
  148. package/dist/ops/registry.d.ts +14 -0
  149. package/dist/ops/registry.d.ts.map +1 -0
  150. package/dist/ops/registry.js +112 -0
  151. package/dist/ops/registry.js.map +1 -0
  152. package/dist/ops/release.d.ts +26 -0
  153. package/dist/ops/release.d.ts.map +1 -0
  154. package/dist/ops/release.js +79 -0
  155. package/dist/ops/release.js.map +1 -0
  156. package/dist/ops/runtimes.d.ts +16 -0
  157. package/dist/ops/runtimes.d.ts.map +1 -0
  158. package/dist/ops/runtimes.js +70 -0
  159. package/dist/ops/runtimes.js.map +1 -0
  160. package/dist/ops/s3.d.ts +8 -0
  161. package/dist/ops/s3.d.ts.map +1 -0
  162. package/dist/ops/s3.js +38 -0
  163. package/dist/ops/s3.js.map +1 -0
  164. package/dist/ops/static-config.d.ts +14 -0
  165. package/dist/ops/static-config.d.ts.map +1 -0
  166. package/dist/ops/static-config.js +92 -0
  167. package/dist/ops/static-config.js.map +1 -0
  168. package/dist/ops/storage.d.ts +39 -0
  169. package/dist/ops/storage.d.ts.map +1 -0
  170. package/dist/ops/storage.js +108 -0
  171. package/dist/ops/storage.js.map +1 -0
  172. package/flowpress-deploy.php +2 -2
  173. package/includes/pilot-aliases.php +69 -0
  174. package/package.json +43 -6
  175. package/schema/deployment.schema.json +306 -0
@@ -0,0 +1,42 @@
1
+ import { existsSync, readdirSync, statSync } from "node:fs";
2
+ import { join, extname } from "node:path";
3
+ import { readJson, readManifest } from "./config.js";
4
+ import { checkFeatures } from "./features.js";
5
+ import { run } from "./process.js";
6
+ export const projectChecks = ["styleflow:validate", "styleflow:build", "components:check", "features:check", "check:boundaries", "check:forbidden", "check:php", "typecheck", "test", "web:check", "test:static-build"];
7
+ export function checkProject(root, kind) {
8
+ if (kind === "features") {
9
+ return checkFeatures(root);
10
+ }
11
+ if (kind === "php") {
12
+ const files = [];
13
+ function collect(path) {
14
+ if (!existsSync(path))
15
+ return;
16
+ if (statSync(path).isFile()) {
17
+ if (extname(path) === ".php")
18
+ files.push(path);
19
+ return;
20
+ }
21
+ for (const item of readdirSync(path))
22
+ if (!["vendor", "node_modules", "dist"].includes(item))
23
+ collect(join(path, item));
24
+ }
25
+ for (const name of ["check-updates.php", "config", "project", "tests", "web/index.php", "web/wp-config.php", "web/app/mu-plugins/bedrock-autoloader.php"])
26
+ collect(join(root, "apps/cms", name));
27
+ for (const file of files)
28
+ run("php", ["-l", file], { stdio: "pipe", encoding: "utf8" });
29
+ return { phpFiles: files.length };
30
+ }
31
+ if (kind)
32
+ throw new Error("Use check [features|php].");
33
+ readManifest(root);
34
+ const scripts = readJson(join(root, "package.json")).scripts || {};
35
+ const selected = projectChecks.filter(key => scripts[key]);
36
+ for (const key of selected) {
37
+ console.info("[check] " + key);
38
+ run("pnpm", ["run", key], { cwd: root });
39
+ }
40
+ return { checks: selected, manifest: "valid" };
41
+ }
42
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/ops/check.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,oBAAoB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,mBAAmB,CAAC,CAAC;AACxN,MAAM,UAAU,YAAY,CAAC,IAAI,EAAE,IAAI;IACrC,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG,EAAE,CAAC;QACjB,SAAS,OAAO,CAAC,IAAI;YACnB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBAAE,OAAO;YAC9B,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;gBAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,MAAM;oBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAAC,OAAO;YAAC,CAAC;YACxF,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC;gBAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;oBAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1H,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,CAAC,mBAAmB,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,2CAA2C,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;QACjM,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QACxF,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;IACpC,CAAC;IACD,IAAI,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IACvD,YAAY,CAAC,IAAI,CAAC,CAAC;IACnB,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC;IACnE,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3D,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC;QAC/B,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AACjD,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/ops/cli.js"],"names":[],"mappings":""}
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env node
2
+ import { mediaCommand, migrateMediaManifest } from "./media.js";
3
+ import { allowedComponents, identity, loadState, operatorEnvironment, platformConfig, projectRoot, readManifest, saveState } from "./config.js";
4
+ import { argValue, containerFor, shellQuote, ssh } from "./process.js";
5
+ import { build, buildBase, frontendBuild } from "./build.js";
6
+ import { deploy, deployedRelease } from "./deploy.js";
7
+ import { provision, provisionPlatform } from "./provision.js";
8
+ import { pullSource, prepareData, pushData, pushUploads, cleanIntegrations } from "./data.js";
9
+ import { backupRun, backupVerify, status } from "./monitor.js";
10
+ import { coolifyClient } from "./coolify.js";
11
+ import { release, editorialCommit } from "./release.js";
12
+ import { readFileSync, appendFileSync } from "node:fs";
13
+ import { provisionRegistry, provisionDns } from "./bootstrap.js";
14
+ import { synchronizeEnvironmentFiles } from "./environment-files.js";
15
+ import { localCommand } from "./local.js";
16
+ import { checkProject } from "./check.js";
17
+ import { cmsTemplate } from "./cms-template/entry.mjs";
18
+ import { cmsMigrate } from "./cms-migrate.js";
19
+ import { featureCommand } from "./features.js";
20
+ import { printLocalStorage } from "./storage.js";
21
+ const args = process.argv.slice(2);
22
+ const [command, name, component] = args;
23
+ function help() {
24
+ return "FlowPress Ops\n\n"
25
+ + " flowpress-ops plan|provision <environment> [component] [--apply]\n"
26
+ + " flowpress-ops env sync [--apply] [--local-secrets]\n"
27
+ + " flowpress-ops local start|stop|status|doctor|logs|exec|backup|datagrip|storage\n"
28
+ + " flowpress-ops local clean [--apply] [--include-legacy]\n"
29
+ + " flowpress-ops cms template <status|pull|push|restore> [options]\n"
30
+ + " flowpress-ops cms migrate pilot-aliases --target <environment> --dry-run|--apply\n"
31
+ + " flowpress-ops feature list|check|install|remove [id] [--version <exact>]\n"
32
+ + " flowpress-ops check [features|php] | cms install\n"
33
+ + " flowpress-ops platform plan|provision|build-base [--apply] [--push|--load]\n"
34
+ + " flowpress-ops registry [--apply] | dns <environment> [--apply]\n"
35
+ + " flowpress-ops build <environment> <cms|web-static|web-ssr> <--push|--load> [--sha SHA]\n"
36
+ + " flowpress-ops frontend <environment> [--sha SHA] [--build-id ID]\n"
37
+ + " flowpress-ops deploy|rollback <environment> <component>\n"
38
+ + " flowpress-ops release <environment> [component] [--editorial]\n"
39
+ + " flowpress-ops db pull <source> | prepare <environment> --from FILE | push <environment> --from FILE\n"
40
+ + " flowpress-ops db clean-integrations <environment>\n"
41
+ + " flowpress-ops uploads <environment> --from ARCHIVE\n"
42
+ + " flowpress-ops backup run|verify <environment>\n"
43
+ + " flowpress-ops media status|check <environment> [--json] | media migrate [--apply]\n"
44
+ + " flowpress-ops preview start|stop [--backend staging|production]\n"
45
+ + " flowpress-ops status [environment] [--check] [--json]\n"
46
+ + " flowpress-ops logs <environment> [component]\n\n"
47
+ + "Provisioning is read-only without --apply. Publish lists are enforced by every remote write.\n";
48
+ }
49
+ async function main() {
50
+ if (!command || ["--help", "-h"].includes(command)) {
51
+ console.log(help());
52
+ return;
53
+ }
54
+ const root = projectRoot(), manifest = readManifest(root);
55
+ const file = argValue(args, "--platform-file");
56
+ let result;
57
+ if (command === "cms" && name === "template") {
58
+ process.exitCode = await cmsTemplate(root, manifest, args.slice(2));
59
+ return;
60
+ }
61
+ else if (command === "cms" && name === "migrate") {
62
+ result = await cmsMigrate(root, manifest, args.slice(2));
63
+ }
64
+ else if (command === "feature") {
65
+ result = featureCommand(root, args.slice(1));
66
+ }
67
+ else if (command === "check") {
68
+ result = checkProject(root, name);
69
+ }
70
+ else if (command === "cms" && name === "install") {
71
+ const { run } = await import("./process.js");
72
+ run("composer", ["install", "--working-dir=apps/cms", "--no-interaction", "--prefer-dist", "--optimize-autoloader"], { cwd: root });
73
+ result = { cms: "installed" };
74
+ }
75
+ else if (command === "local") {
76
+ result = await localCommand(root, manifest, name, args.slice(2));
77
+ }
78
+ else if (command === "env") {
79
+ if (name !== "sync")
80
+ throw new Error("Use env sync [--apply] [--local-secrets].");
81
+ result = synchronizeEnvironmentFiles(root, { apply: args.includes("--apply"), localSecrets: args.includes("--local-secrets") });
82
+ }
83
+ else if (command === "validate") {
84
+ result = { project: identity(root).slug, profile: manifest.profile, environments: Object.fromEntries(Object.entries(manifest.environments).map(([key, value]) => [key, value.publish])) };
85
+ }
86
+ else if (command === "plan" || command === "provision") {
87
+ result = await provision(root, manifest, name, { file, apply: command === "provision" && args.includes("--apply"), components: component && !component.startsWith("--") ? [component] : [] });
88
+ }
89
+ else if (command === "platform") {
90
+ if (name === "build-base")
91
+ result = buildBase(root, platformConfig(root, manifest, file), { push: args.includes("--push"), load: args.includes("--load") });
92
+ else if (["plan", "provision"].includes(name))
93
+ result = await provisionPlatform(root, manifest, { file, apply: name === "provision" && args.includes("--apply") });
94
+ else
95
+ throw new Error("Use platform plan|provision|build-base.");
96
+ }
97
+ else if (command === "registry") {
98
+ result = await provisionRegistry(root, manifest, { file, apply: args.includes("--apply") });
99
+ }
100
+ else if (command === "dns") {
101
+ result = await provisionDns(root, manifest, name, { file, apply: args.includes("--apply") });
102
+ }
103
+ else if (command === "build") {
104
+ result = await build(root, manifest, name, component, { file, push: args.includes("--push"), load: args.includes("--load"), sha: argValue(args, "--sha"), buildId: argValue(args, "--build-id"), skipFrontend: args.includes("--skip-frontend") });
105
+ }
106
+ else if (command === "frontend") {
107
+ result = frontendBuild(root, manifest, name, { sha: argValue(args, "--sha") || (await import("./process.js")).capture("git", ["rev-parse", "HEAD"], { cwd: root }), buildId: argValue(args, "--build-id") || String(Date.now()) });
108
+ result = { environment: name, output: result.dist };
109
+ }
110
+ else if (command === "deploy" || command === "rollback") {
111
+ result = await deploy(root, manifest, name, component, { rollback: command === "rollback" });
112
+ }
113
+ else if (command === "release") {
114
+ result = await release(root, manifest, name, { component: component && !component.startsWith("--") ? component : undefined, sha: argValue(args, "--sha"), buildId: argValue(args, "--build-id"), editorial: args.includes("--editorial") });
115
+ }
116
+ else if (command === "editorial") {
117
+ const event = JSON.parse(readFileSync(process.env.GITHUB_EVENT_PATH, "utf8"));
118
+ result = await editorialCommit(root, manifest, event.client_payload);
119
+ if (process.env.GITHUB_OUTPUT)
120
+ appendFileSync(process.env.GITHUB_OUTPUT, "sha=" + result.sha + "\ntarget=" + result.request.target + "\n");
121
+ }
122
+ else if (command === "db") {
123
+ const target = component;
124
+ if (name === "pull")
125
+ result = await pullSource(root, manifest, target);
126
+ else if (name === "prepare")
127
+ result = await prepareData(root, manifest, target, { file: argValue(args, "--from"), source: argValue(args, "--source") || "production", image: argValue(args, "--image") });
128
+ else if (name === "clean-integrations")
129
+ result = await cleanIntegrations(root, manifest, target);
130
+ else if (name === "push")
131
+ result = await pushData(root, manifest, target, argValue(args, "--from"));
132
+ else
133
+ throw new Error("Use db pull|prepare|push.");
134
+ }
135
+ else if (command === "uploads")
136
+ result = await pushUploads(root, manifest, name, argValue(args, "--from"));
137
+ else if (command === "backup")
138
+ result = await (name === "run" ? backupRun : name === "verify" ? backupVerify : () => { throw new Error("Use backup run|verify."); })(root, manifest, component);
139
+ else if (command === "media") {
140
+ result = name === "migrate" ? migrateMediaManifest(root, { apply: args.includes("--apply") }) : mediaCommand(root, manifest, name, component);
141
+ if (name !== "migrate" && !result.ok)
142
+ process.exitCode = 1;
143
+ }
144
+ else if (command === "status") {
145
+ result = await status(root, manifest, name && !name.startsWith("--") ? name : undefined);
146
+ if (args.includes("--check") && !result.ok)
147
+ process.exitCode = 1;
148
+ }
149
+ else if (command === "logs") {
150
+ const state = loadState(root, name), app = state.apps?.[component || "cms"];
151
+ if (!app?.uuid)
152
+ throw new Error("Component not provisioned.");
153
+ console.log(ssh(state.platform, "docker logs --tail 100 " + shellQuote(containerFor(state.platform, app.uuid))));
154
+ return;
155
+ }
156
+ else if (command === "preview") {
157
+ allowedComponents(manifest, "preview", ["web-ssr"]);
158
+ const target = manifest.environments.preview;
159
+ if (argValue(args, "--backend") && argValue(args, "--backend") !== target.backend)
160
+ throw new Error("Update the manifest backend before starting preview.");
161
+ if (!["start", "stop"].includes(name))
162
+ throw new Error("Use preview start|stop.");
163
+ const state = loadState(root, "preview"), app = state.apps?.["web-ssr"];
164
+ if (!app?.uuid)
165
+ throw new Error("Provision preview first.");
166
+ if (name === "start") {
167
+ const current = await deployedRelease(root, "preview", "web-ssr");
168
+ if (!current)
169
+ throw new Error("Build and deploy preview once before starting it.");
170
+ result = await deploy(root, manifest, "preview", "web-ssr", { release: current });
171
+ }
172
+ else {
173
+ const api = coolifyClient(state.platform.coolifyUrl, operatorEnvironment(root).COOLIFY_TOKEN);
174
+ await api("POST", "/applications/" + app.uuid + "/stop");
175
+ result = { preview: "stopped", dataPreserved: true };
176
+ }
177
+ }
178
+ else
179
+ throw new Error("Unknown command. Use --help.");
180
+ // Streaming commands own stdout (notably WP-CLI JSON consumed by callers).
181
+ if (result === undefined)
182
+ return;
183
+ if (command === "local" && ["storage", "clean"].includes(name) && !args.includes("--json")) {
184
+ printLocalStorage(result, { clean: name === "clean" });
185
+ return;
186
+ }
187
+ if (args.includes("--json"))
188
+ console.log(JSON.stringify(result, null, 2));
189
+ else {
190
+ console.log("FlowPress: " + command + (name ? " " + name : ""));
191
+ console.log(JSON.stringify(result, null, 2));
192
+ }
193
+ }
194
+ main().catch(error => {
195
+ console.error("FlowPress: " + error.message);
196
+ process.exitCode = 1;
197
+ });
198
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/ops/cli.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export function migrationProgram(operation: any, plan: any): string;
2
+ export function parseMigrationResponse(output: any): any;
3
+ export function migrationTransport(root: any, target: any): (operation: any, plan: any) => any;
4
+ export function verifyBackupSite(site: any, expectedSite: any): void;
5
+ export function localDatabaseSite(root: any): any;
6
+ export function verifyLocalSqlBackup(root: any, file: any, expectedSite: any): Promise<{
7
+ file: any;
8
+ tables: any;
9
+ site: any;
10
+ verified: boolean;
11
+ }>;
12
+ export function cmsMigrate(root: any, manifest: any, args: any, deps?: {}): Promise<any>;
13
+ export const migrationEvalArgs: string[];
14
+ //# sourceMappingURL=cms-migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-migrate.d.ts","sourceRoot":"","sources":["../../src/ops/cms-migrate.js"],"names":[],"mappings":"AAYA,oEAIC;AACD,yDAOC;AACD,+FAMC;AACD,qEAEC;AACD,kDAEC;AACD;;;;;GAiBC;AACD,yFA4CC;AA1FD,yCAAoD"}
@@ -0,0 +1,133 @@
1
+ import { readFileSync, mkdirSync, writeFileSync, existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ import { fileURLToPath } from "node:url";
5
+ import { resolveTarget } from "./cms-template/target.mjs";
6
+ import { allowedComponents, loadState } from "./config.js";
7
+ import { localCommand, localComposeArgs } from "./local.js";
8
+ import { backupRun, backupVerify } from "./monitor.js";
9
+ import { capture, run, ssh, containerFor, shellQuote, sleep } from "./process.js";
10
+ export const migrationEvalArgs = ["eval-file", "-"];
11
+ export function migrationProgram(operation, plan) {
12
+ const source = readFileSync(fileURLToPath(new URL("../../includes/pilot-aliases.php", import.meta.url)), "utf8").replace(/^<\?php\s*/, "").replace("declare(strict_types=1);", "");
13
+ const request = Buffer.from(JSON.stringify({ operation, plan })).toString("base64");
14
+ return `<?php\n${source}\ntry { $request = json_decode(base64_decode('${request}'), true, 512, JSON_THROW_ON_ERROR); $result = $request['operation'] === 'plan' ? flowpress_ops_alias_plan() : flowpress_ops_alias_apply($request['plan']); echo "\\n@@flowpress-migration@@\\n", wp_json_encode(['ok' => true, 'result' => $result]); } catch (Throwable $error) { echo "\\n@@flowpress-migration@@\\n", wp_json_encode(['ok' => false, 'error' => $error->getMessage()]); }`;
15
+ }
16
+ export function parseMigrationResponse(output) {
17
+ const marker = "@@flowpress-migration@@";
18
+ const at = output.lastIndexOf(marker);
19
+ if (at < 0)
20
+ throw new Error("CMS did not return the migration result.");
21
+ const result = JSON.parse(output.slice(at + marker.length));
22
+ if (!result.ok)
23
+ throw new Error(result.error);
24
+ return result.result;
25
+ }
26
+ export function migrationTransport(root, target) {
27
+ if (target.local)
28
+ return (operation, plan) => parseMigrationResponse(capture("docker", [...localComposeArgs(root), "exec", "-T", "cms", "/workspace/apps/cms/vendor/bin/wp", "--allow-root", "--path=/workspace/apps/cms/web/wp", ...migrationEvalArgs], { input: migrationProgram(operation, plan), maxBuffer: 256 * 1024 * 1024 }));
29
+ const state = loadState(root, target.backendName);
30
+ if (!state.apps?.cms?.uuid)
31
+ throw new Error("CMS container not provisioned for this target.");
32
+ const container = containerFor(state.platform, state.apps.cms.uuid);
33
+ return (operation, plan) => parseMigrationResponse(ssh(state.platform, "docker exec -i " + shellQuote(container) + " wp --allow-root --path=/srv/cms/web/wp " + migrationEvalArgs.map(shellQuote).join(" ") + "", { input: migrationProgram(operation, plan), maxBuffer: 256 * 1024 * 1024 }));
34
+ }
35
+ export function verifyBackupSite(site, expectedSite) {
36
+ if (new URL(site).origin !== new URL(expectedSite).origin)
37
+ throw new Error("Restored backup belongs to another database site.");
38
+ }
39
+ export function localDatabaseSite(root) {
40
+ return capture("docker", [...localComposeArgs(root), "exec", "-T", "cms", "/workspace/apps/cms/vendor/bin/wp", "--allow-root", "--path=/workspace/apps/cms/web/wp", "eval", 'global $wpdb; echo $wpdb->get_var($wpdb->prepare("SELECT option_value FROM {$wpdb->options} WHERE option_name = %s", "home"));']);
41
+ }
42
+ export async function verifyLocalSqlBackup(root, file, expectedSite) {
43
+ const id = "flowpress-migration-restore-" + randomUUID().slice(0, 8);
44
+ try {
45
+ run("docker", ["run", "--rm", "-d", "--network", "none", "--memory", "1536m", "--name", id, "-e", "MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1", "-e", "MARIADB_DATABASE=restore", "mariadb:11.4"], { stdio: "ignore" });
46
+ for (let attempt = 0; attempt < 60; attempt++) {
47
+ try {
48
+ capture("docker", ["exec", id, "healthcheck.sh", "--connect", "--innodb_initialized"]);
49
+ break;
50
+ }
51
+ catch {
52
+ if (attempt === 59)
53
+ throw new Error("Backup verification database did not start.");
54
+ await sleep(1000);
55
+ }
56
+ }
57
+ const data = readFileSync(file);
58
+ run("docker", ["exec", "-i", id, "mariadb", "-uroot", "restore"], { input: data, stdio: ["pipe", "pipe", "pipe"] });
59
+ const tables = capture("docker", ["exec", id, "mariadb", "-uroot", "-N", "restore", "-e", "SHOW TABLES"]).split("\n");
60
+ const options = tables.filter(name => /^[A-Za-z0-9_]+_options$/.test(name));
61
+ if (tables.length < 10 || options.length !== 1)
62
+ throw new Error("Backup lacks the expected WordPress tables.");
63
+ const site = capture("docker", ["exec", id, "mariadb", "-uroot", "-N", "restore", "-e", "SELECT option_value FROM `" + options[0] + "` WHERE option_name='home'"]);
64
+ verifyBackupSite(site, expectedSite);
65
+ return { file, tables: tables.length, site, verified: true };
66
+ }
67
+ finally {
68
+ try {
69
+ run("docker", ["rm", "-fv", id], { stdio: "ignore" });
70
+ }
71
+ catch { }
72
+ }
73
+ }
74
+ export async function cmsMigrate(root, manifest, args, deps = {}) {
75
+ if (args[0] !== "pilot-aliases")
76
+ throw new Error("Use cms migrate pilot-aliases --target <environment> --dry-run|--apply.");
77
+ const flags = args.slice(1);
78
+ if (flags.includes("--apply") === flags.includes("--dry-run"))
79
+ throw new Error("Choose exactly one of --dry-run or --apply.");
80
+ const at = flags.indexOf("--target");
81
+ if (at < 0 || !flags[at + 1] || flags[at + 1].startsWith("--"))
82
+ throw new Error("An explicit --target is required.");
83
+ const remaining = flags.filter((_, i) => i !== at && i !== at + 1).filter(flag => !["--apply", "--dry-run", "--json"].includes(flag));
84
+ if (remaining.length)
85
+ throw new Error("Unknown migration option: " + remaining[0]);
86
+ const target = (deps.resolveTarget || resolveTarget)({ root, manifest, flag: flags[at + 1] });
87
+ if (!target.local)
88
+ allowedComponents(manifest, target.backendName, ["cms"]);
89
+ const directory = join(root, ".local/cms-migrations");
90
+ const path = join(directory, "pilot-aliases-" + target.name + ".json");
91
+ const call = deps.transport || migrationTransport(root, target);
92
+ if (flags.includes("--dry-run")) {
93
+ const plan = await call("plan");
94
+ if (new URL(plan.site).origin !== target.origin)
95
+ throw new Error("CMS identity differs from the configured target.");
96
+ mkdirSync(directory, { recursive: true, mode: 0o700 });
97
+ writeFileSync(path, JSON.stringify({ ...plan, target: target.name }, null, 2) + "\n", { mode: 0o600 });
98
+ return { target: target.name, site: plan.site, hash: plan.hash, counts: plan.counts, changes: plan.changes.length, plan: path };
99
+ }
100
+ if (!existsSync(path))
101
+ throw new Error("Run --dry-run on this target before --apply.");
102
+ const plan = JSON.parse(readFileSync(path, "utf8"));
103
+ const current = await call("plan");
104
+ if (new URL(current.site).origin !== target.origin)
105
+ throw new Error("CMS identity differs from the configured target.");
106
+ if (plan.target !== target.name || plan.site !== current.site || plan.hash !== current.hash)
107
+ throw new Error("Migration plan is stale or belongs to another target; run --dry-run again.");
108
+ if (!current.changes.length)
109
+ return { target: target.name, updated: 0, counts: {} };
110
+ let backup;
111
+ if (deps.backup)
112
+ backup = await deps.backup(target, plan);
113
+ else if (target.local) {
114
+ const databaseSite = localDatabaseSite(root);
115
+ const exported = await localCommand(root, manifest, "backup", []);
116
+ backup = await verifyLocalSqlBackup(root, exported.file, databaseSite);
117
+ }
118
+ else {
119
+ const startedAt = Date.now() - 2000;
120
+ const exported = await backupRun(root, manifest, target.backendName);
121
+ backup = await backupVerify(root, manifest, target.backendName);
122
+ if (Date.parse(backup.database.modified || "") < startedAt || !backup.database.modified)
123
+ throw new Error("The verified offsite database backup predates this migration.");
124
+ backup = { ...backup, exported, verified: true };
125
+ }
126
+ if (!backup?.verified)
127
+ throw new Error("A verified backup is required before applying the migration.");
128
+ const applied = await call("apply", plan);
129
+ const receipt = join(directory, "pilot-aliases-" + target.name + "-" + Date.now() + ".receipt.json");
130
+ writeFileSync(receipt, JSON.stringify({ ...applied, backup, target: target.name, planHash: plan.hash }, null, 2) + "\n", { mode: 0o600 });
131
+ return { target: target.name, ...applied, receipt };
132
+ }
133
+ //# sourceMappingURL=cms-migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-migrate.js","sourceRoot":"","sources":["../../src/ops/cms-migrate.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export function parseArgs(argv: any): {
2
+ command: any;
3
+ file: any;
4
+ options: {
5
+ target: string;
6
+ dryRun: boolean;
7
+ yes: boolean;
8
+ force: boolean;
9
+ prune: boolean;
10
+ allowDirty: boolean;
11
+ };
12
+ };
13
+ /**
14
+ * deps: { root, themePath, resolveTarget, transport, git, store, confirm, log, now }
15
+ * Returns the process exit code.
16
+ */
17
+ export function runCmsTemplate(argv: any, deps: any): Promise<1 | 0>;
18
+ export const USAGE: "Usage: pnpm cms:template <pull|push|status|restore <snapshot.json>> [options]\n\n --target <env> backend to use (default: FRONTEND_BACKEND_TARGET)\n --dry-run print the plan only\n --yes confirm without prompting (required without a TTY)\n --force resolve conflicts: push \u2192 the repository wins, pull \u2192 the CMS wins\n --prune push: trash patterns / drop overrides missing from the repository\n pull: delete pattern files missing from the CMS\n --allow-dirty run with uncommitted changes under apps/cms/theme";
19
+ //# sourceMappingURL=command.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.mts","sourceRoot":"","sources":["../../../src/ops/cms-template/command.mjs"],"names":[],"mappings":"AAcA;;;;;;;;;;;EAoBC;AAED;;;GAGG;AACH,qEAoGC;AAxID,4lBAQsE"}
@@ -0,0 +1,145 @@
1
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { dirname, join, relative } from "node:path";
3
+ import { applyAncestry, pendingChanges, pendingMarkers, renderPlan } from "./plan.mjs";
4
+ export const USAGE = `Usage: pnpm cms:template <pull|push|status|restore <snapshot.json>> [options]
5
+
6
+ --target <env> backend to use (default: FRONTEND_BACKEND_TARGET)
7
+ --dry-run print the plan only
8
+ --yes confirm without prompting (required without a TTY)
9
+ --force resolve conflicts: push → the repository wins, pull → the CMS wins
10
+ --prune push: trash patterns / drop overrides missing from the repository
11
+ pull: delete pattern files missing from the CMS
12
+ --allow-dirty run with uncommitted changes under apps/cms/theme`;
13
+ export function parseArgs(argv) {
14
+ const options = { target: "", dryRun: false, yes: false, force: false, prune: false, allowDirty: false };
15
+ const positional = [];
16
+ for (let index = 0; index < argv.length; index++) {
17
+ const arg = argv[index];
18
+ if (arg === "--target")
19
+ options.target = String(argv[++index] ?? "");
20
+ else if (arg.startsWith("--target="))
21
+ options.target = arg.slice(9);
22
+ else if (arg === "--dry-run")
23
+ options.dryRun = true;
24
+ else if (arg === "--yes" || arg === "-y")
25
+ options.yes = true;
26
+ else if (arg === "--force")
27
+ options.force = true;
28
+ else if (arg === "--prune")
29
+ options.prune = true;
30
+ else if (arg === "--allow-dirty")
31
+ options.allowDirty = true;
32
+ else if (arg.startsWith("-"))
33
+ throw new Error(`Unknown option ${arg}.\n\n${USAGE}`);
34
+ else
35
+ positional.push(arg);
36
+ }
37
+ const [command = "", file = ""] = positional;
38
+ if (!["pull", "push", "status", "restore"].includes(command) || (command === "restore") !== Boolean(file)) {
39
+ throw new Error(USAGE);
40
+ }
41
+ return { command, file, options };
42
+ }
43
+ /**
44
+ * deps: { root, themePath, resolveTarget, transport, git, store, confirm, log, now }
45
+ * Returns the process exit code.
46
+ */
47
+ export async function runCmsTemplate(argv, deps) {
48
+ const { command, file, options } = parseArgs(argv);
49
+ const { log } = deps;
50
+ const target = deps.resolveTarget(options.target);
51
+ const transport = deps.transport(target);
52
+ const status = await transport.call("status");
53
+ if (status.protocol !== 1) {
54
+ throw new Error(`${target.origin} speaks sync protocol ${status.protocol}; this CLI speaks 1. Deploy the backend or update the repository.`);
55
+ }
56
+ if (new URL(status.site).origin !== target.origin)
57
+ throw new Error(`The CMS identifies itself as ${status.site}, not the configured target ${target.origin}.`);
58
+ log(`target ${target.name}: ${status.site} (${target.local ? "local backend" : "remote backend"}) · theme ${status.stylesheet}`);
59
+ if (command === "status") {
60
+ log(`protocol ${status.protocol}`);
61
+ return 0;
62
+ }
63
+ if ((command === "push" || command === "restore") && !options.dryRun)
64
+ deps.assertWritable?.(target);
65
+ const ask = (question) => target.local ? true : deps.confirm(question, { yes: options.yes });
66
+ if (command === "restore") {
67
+ const snapshot = JSON.parse(readFileSync(file, "utf8"));
68
+ if (snapshot.site !== status.site) {
69
+ throw new Error(`${file} belongs to ${snapshot.site}, not to ${status.site}.`);
70
+ }
71
+ log(`restore ${snapshot.entries.length} row(s) recorded on ${snapshot.createdAt} before commit ${snapshot.commit}`);
72
+ if (options.dryRun)
73
+ return 0;
74
+ if (!(await ask(`Restore ${snapshot.entries.length} row(s) on ${target.name} (${target.origin})?`))) {
75
+ log("aborted");
76
+ return 1;
77
+ }
78
+ const report = await transport.call("restore", { snapshot });
79
+ log(`restored ${report.restored.length}, removed ${report.removed.length}`);
80
+ return 0;
81
+ }
82
+ const dirty = deps.git.dirty(deps.themePath);
83
+ if (dirty.length && !options.allowDirty && (command === "pull" || !target.local)) {
84
+ throw new Error(`Uncommitted changes in ${deps.themePath}:\n${dirty.join("\n")}\n` +
85
+ (command === "pull"
86
+ ? "Commit or stash them before a pull (or pass --allow-dirty)."
87
+ : "A remote push must be reproducible from a commit: commit first (or pass --allow-dirty)."));
88
+ }
89
+ const entities = deps.store.read();
90
+ const plan = await transport.call("plan", {
91
+ direction: command, entities, force: options.force, prune: options.prune,
92
+ });
93
+ if (command === "push")
94
+ applyAncestry(plan, (commit) => deps.git.isAncestor(commit), options.force);
95
+ renderPlan(plan, target, log);
96
+ if (command === "push" && plan.blocked.length) {
97
+ log("push blocked, nothing was written:");
98
+ for (const reason of plan.blocked)
99
+ log(` - ${reason}`);
100
+ log("Run `pnpm cms:template pull` and merge with git, or pass --force to overwrite the CMS.");
101
+ return 1;
102
+ }
103
+ const changes = pendingChanges(plan);
104
+ const markers = command === "push" ? pendingMarkers(plan) : [];
105
+ const blocked = plan.items.filter((item) => item.action === "blocked");
106
+ if (!changes.length && !markers.length) {
107
+ log(blocked.length ? "nothing to write; conflicts listed above (use --force to take the CMS version)" : "already in sync");
108
+ return blocked.length ? 1 : 0;
109
+ }
110
+ if (options.dryRun) {
111
+ log("dry run: nothing written");
112
+ return blocked.length ? 1 : 0;
113
+ }
114
+ const question = command === "pull"
115
+ ? `Write ${changes.length} file change(s) from ${target.name} (${target.origin})?`
116
+ : `Apply ${changes.length} change(s) and ${markers.length} sync marker(s) to ${target.name} (${target.origin})?` +
117
+ (changes.length ? " Template and pattern saves schedule a public build." : "");
118
+ if (!(await ask(question))) {
119
+ log("aborted");
120
+ return 1;
121
+ }
122
+ if (command === "pull") {
123
+ for (const path of deps.store.write(plan.items))
124
+ log(` wrote ${path}`);
125
+ log("review with `git diff`, then commit");
126
+ if (blocked.length)
127
+ log(`${blocked.length} conflict(s) left untouched (use --force to take the CMS version)`);
128
+ return blocked.length ? 1 : 0;
129
+ }
130
+ const commit = deps.git.head() + (dirty.length ? "+dirty" : "");
131
+ const snapshotPath = join(deps.root, ".local", "cms-template", "snapshots", target.name, `${deps.now().toISOString().replace(/[:.]/g, "-")}.json`);
132
+ mkdirSync(dirname(snapshotPath), { recursive: true, mode: 0o700 });
133
+ writeFileSync(snapshotPath, `${JSON.stringify({
134
+ ...plan.snapshot, target: target.name, commit, createdAt: deps.now().toISOString(),
135
+ }, null, 2)}\n`, { mode: 0o600, flag: "wx" });
136
+ log(`snapshot ${relative(deps.root, snapshotPath)} (restore with: pnpm cms:template restore ${relative(deps.root, snapshotPath)} --target ${target.name})`);
137
+ const report = await transport.call("apply", {
138
+ entities, planHash: plan.planHash, force: options.force, prune: options.prune, commit,
139
+ });
140
+ log(`created ${report.created.length}, updated ${report.updated.length}, deleted ${report.deleted.length}, sync markers ${report.markers}`);
141
+ if (changes.length)
142
+ log("new Tailwind classes? regenerate the safelist: pnpm safelist:generate");
143
+ return 0;
144
+ }
145
+ //# sourceMappingURL=command.mjs.map