@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.
- package/CHANGELOG.md +162 -0
- package/README.md +5 -0
- package/composer.json +1 -1
- package/containers/cms/Dockerfile +35 -0
- package/containers/cms/Dockerfile.dockerignore +20 -0
- package/containers/cms/healthz.php +17 -0
- package/containers/cms/install-languages.sh +16 -0
- package/containers/cms/mpm.conf +10 -0
- package/containers/cms/php.ini +16 -0
- package/containers/cms/sanitize-integrations.php +14 -0
- package/containers/cms/sanitize.php +40 -0
- package/containers/cms/smtp.php +13 -0
- package/containers/cms/vhost.conf +61 -0
- package/containers/cms/wp-cli.yml +1 -0
- package/containers/local/cms/Dockerfile +18 -0
- package/containers/local/cms/entrypoint.sh +7 -0
- package/containers/local/cms/php.ini +8 -0
- package/containers/local/cms/vhost.conf +14 -0
- package/containers/local/runtimes.json +14 -0
- package/containers/local/web/Dockerfile +8 -0
- package/containers/local/web/entrypoint.sh +21 -0
- package/containers/php-runtime/Dockerfile +21 -0
- package/containers/web-ssr/Dockerfile +27 -0
- package/containers/web-ssr/Dockerfile.dockerignore +10 -0
- package/containers/web-static/Caddyfile +40 -0
- package/containers/web-static/Dockerfile +17 -0
- package/containers/web-static/Dockerfile.dockerignore +7 -0
- package/dist/development.d.ts +12 -0
- package/dist/development.d.ts.map +1 -0
- package/dist/development.js +57 -0
- package/dist/development.js.map +1 -0
- package/dist/node-fetch.d.ts +3 -0
- package/dist/node-fetch.d.ts.map +1 -0
- package/dist/node-fetch.js +20 -0
- package/dist/node-fetch.js.map +1 -0
- package/dist/ops/bootstrap.d.ts +24 -0
- package/dist/ops/bootstrap.d.ts.map +1 -0
- package/dist/ops/bootstrap.js +156 -0
- package/dist/ops/bootstrap.js.map +1 -0
- package/dist/ops/build.d.ts +45 -0
- package/dist/ops/build.d.ts.map +1 -0
- package/dist/ops/build.js +119 -0
- package/dist/ops/build.js.map +1 -0
- package/dist/ops/check.d.ts +14 -0
- package/dist/ops/check.d.ts.map +1 -0
- package/dist/ops/check.js +42 -0
- package/dist/ops/check.js.map +1 -0
- package/dist/ops/cli.d.ts +3 -0
- package/dist/ops/cli.d.ts.map +1 -0
- package/dist/ops/cli.js +198 -0
- package/dist/ops/cli.js.map +1 -0
- package/dist/ops/cms-migrate.d.ts +14 -0
- package/dist/ops/cms-migrate.d.ts.map +1 -0
- package/dist/ops/cms-migrate.js +133 -0
- package/dist/ops/cms-migrate.js.map +1 -0
- package/dist/ops/cms-template/command.d.mts +19 -0
- package/dist/ops/cms-template/command.d.mts.map +1 -0
- package/dist/ops/cms-template/command.mjs +145 -0
- package/dist/ops/cms-template/command.mjs.map +1 -0
- package/dist/ops/cms-template/confirm.d.mts +11 -0
- package/dist/ops/cms-template/confirm.d.mts.map +1 -0
- package/dist/ops/cms-template/confirm.mjs +18 -0
- package/dist/ops/cms-template/confirm.mjs.map +1 -0
- package/dist/ops/cms-template/entry.d.mts +2 -0
- package/dist/ops/cms-template/entry.d.mts.map +1 -0
- package/dist/ops/cms-template/entry.mjs +22 -0
- package/dist/ops/cms-template/entry.mjs.map +1 -0
- package/dist/ops/cms-template/git.d.mts +7 -0
- package/dist/ops/cms-template/git.d.mts.map +1 -0
- package/dist/ops/cms-template/git.mjs +22 -0
- package/dist/ops/cms-template/git.mjs.map +1 -0
- package/dist/ops/cms-template/plan.d.mts +7 -0
- package/dist/ops/cms-template/plan.d.mts.map +1 -0
- package/dist/ops/cms-template/plan.mjs +54 -0
- package/dist/ops/cms-template/plan.mjs.map +1 -0
- package/dist/ops/cms-template/store.d.mts +21 -0
- package/dist/ops/cms-template/store.d.mts.map +1 -0
- package/dist/ops/cms-template/store.mjs +184 -0
- package/dist/ops/cms-template/store.mjs.map +1 -0
- package/dist/ops/cms-template/target.d.mts +15 -0
- package/dist/ops/cms-template/target.d.mts.map +1 -0
- package/dist/ops/cms-template/target.mjs +24 -0
- package/dist/ops/cms-template/target.mjs.map +1 -0
- package/dist/ops/cms-template/transport.d.mts +26 -0
- package/dist/ops/cms-template/transport.d.mts.map +1 -0
- package/dist/ops/cms-template/transport.mjs +115 -0
- package/dist/ops/cms-template/transport.mjs.map +1 -0
- package/dist/ops/config.d.ts +54 -0
- package/dist/ops/config.d.ts.map +1 -0
- package/dist/ops/config.js +221 -0
- package/dist/ops/config.js.map +1 -0
- package/dist/ops/coolify.d.ts +2 -0
- package/dist/ops/coolify.d.ts.map +1 -0
- package/dist/ops/coolify.js +44 -0
- package/dist/ops/coolify.js.map +1 -0
- package/dist/ops/data.d.ts +31 -0
- package/dist/ops/data.d.ts.map +1 -0
- package/dist/ops/data.js +165 -0
- package/dist/ops/data.js.map +1 -0
- package/dist/ops/deploy.d.ts +38 -0
- package/dist/ops/deploy.d.ts.map +1 -0
- package/dist/ops/deploy.js +127 -0
- package/dist/ops/deploy.js.map +1 -0
- package/dist/ops/editorial.d.ts +23 -0
- package/dist/ops/editorial.d.ts.map +1 -0
- package/dist/ops/editorial.js +79 -0
- package/dist/ops/editorial.js.map +1 -0
- package/dist/ops/environment-files.d.ts +9 -0
- package/dist/ops/environment-files.d.ts.map +1 -0
- package/dist/ops/environment-files.js +127 -0
- package/dist/ops/environment-files.js.map +1 -0
- package/dist/ops/environment.d.ts +31 -0
- package/dist/ops/environment.d.ts.map +1 -0
- package/dist/ops/environment.js +165 -0
- package/dist/ops/environment.js.map +1 -0
- package/dist/ops/features.d.ts +12 -0
- package/dist/ops/features.d.ts.map +1 -0
- package/dist/ops/features.js +71 -0
- package/dist/ops/features.js.map +1 -0
- package/dist/ops/health.d.ts +26 -0
- package/dist/ops/health.d.ts.map +1 -0
- package/dist/ops/health.js +27 -0
- package/dist/ops/health.js.map +1 -0
- package/dist/ops/local.d.ts +198 -0
- package/dist/ops/local.d.ts.map +1 -0
- package/dist/ops/local.js +187 -0
- package/dist/ops/local.js.map +1 -0
- package/dist/ops/media-config.d.ts +61 -0
- package/dist/ops/media-config.d.ts.map +1 -0
- package/dist/ops/media-config.js +96 -0
- package/dist/ops/media-config.js.map +1 -0
- package/dist/ops/media.d.ts +47 -0
- package/dist/ops/media.d.ts.map +1 -0
- package/dist/ops/media.js +81 -0
- package/dist/ops/media.js.map +1 -0
- package/dist/ops/monitor.d.ts +25 -0
- package/dist/ops/monitor.d.ts.map +1 -0
- package/dist/ops/monitor.js +143 -0
- package/dist/ops/monitor.js.map +1 -0
- package/dist/ops/process.d.ts +9 -0
- package/dist/ops/process.d.ts.map +1 -0
- package/dist/ops/process.js +56 -0
- package/dist/ops/process.js.map +1 -0
- package/dist/ops/provision.d.ts +41 -0
- package/dist/ops/provision.d.ts.map +1 -0
- package/dist/ops/provision.js +268 -0
- package/dist/ops/provision.js.map +1 -0
- package/dist/ops/registry.d.ts +14 -0
- package/dist/ops/registry.d.ts.map +1 -0
- package/dist/ops/registry.js +112 -0
- package/dist/ops/registry.js.map +1 -0
- package/dist/ops/release.d.ts +26 -0
- package/dist/ops/release.d.ts.map +1 -0
- package/dist/ops/release.js +79 -0
- package/dist/ops/release.js.map +1 -0
- package/dist/ops/runtimes.d.ts +16 -0
- package/dist/ops/runtimes.d.ts.map +1 -0
- package/dist/ops/runtimes.js +70 -0
- package/dist/ops/runtimes.js.map +1 -0
- package/dist/ops/s3.d.ts +8 -0
- package/dist/ops/s3.d.ts.map +1 -0
- package/dist/ops/s3.js +38 -0
- package/dist/ops/s3.js.map +1 -0
- package/dist/ops/static-config.d.ts +14 -0
- package/dist/ops/static-config.d.ts.map +1 -0
- package/dist/ops/static-config.js +92 -0
- package/dist/ops/static-config.js.map +1 -0
- package/dist/ops/storage.d.ts +39 -0
- package/dist/ops/storage.d.ts.map +1 -0
- package/dist/ops/storage.js +108 -0
- package/dist/ops/storage.js.map +1 -0
- package/flowpress-deploy.php +2 -2
- package/includes/pilot-aliases.php +69 -0
- package/package.json +43 -6
- package/schema/deployment.schema.json +306 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { localComposeArgs } from "../local.js";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
const RESPONSE_MARKER = "@@cms-template@@";
|
|
7
|
+
const ROUTE = "wp-json/flowpress/v1/site-editor-sync";
|
|
8
|
+
/**
|
|
9
|
+
* Local backend: the command runs inside the Docker CMS through `wp eval`. The
|
|
10
|
+
* request goes through the bind-mounted .local/ folder instead of argv, which
|
|
11
|
+
* would hit ARG_MAX with large templates.
|
|
12
|
+
*/
|
|
13
|
+
export function dockerTransport({ root, run = spawnSync }) {
|
|
14
|
+
return {
|
|
15
|
+
kind: "docker",
|
|
16
|
+
async call(operation, args = {}) {
|
|
17
|
+
const directory = join(root, ".local", "cms-template");
|
|
18
|
+
const name = `request-${randomUUID()}.json`;
|
|
19
|
+
mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
20
|
+
writeFileSync(join(directory, name), JSON.stringify({ operation, args }), { mode: 0o600, flag: "wx" });
|
|
21
|
+
try {
|
|
22
|
+
const result = run("docker", [
|
|
23
|
+
...localComposeArgs(root),
|
|
24
|
+
"exec", "-T", "cms",
|
|
25
|
+
"/workspace/apps/cms/vendor/bin/wp",
|
|
26
|
+
"--allow-root",
|
|
27
|
+
"--path=/workspace/apps/cms/web/wp",
|
|
28
|
+
"eval", dockerProgram(`/workspace/.local/cms-template/${name}`),
|
|
29
|
+
], { cwd: root, encoding: "utf8", maxBuffer: 256 * 1024 * 1024 });
|
|
30
|
+
return parseDockerResponse(result);
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
rmSync(join(directory, name), { force: true });
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function dockerProgram(path) {
|
|
39
|
+
return String.raw `
|
|
40
|
+
$request = json_decode((string) file_get_contents(${JSON.stringify(path)}), true, 512, JSON_THROW_ON_ERROR);
|
|
41
|
+
try {
|
|
42
|
+
if (! function_exists('flowpress_site_editor_sync_dispatch')) {
|
|
43
|
+
throw new RuntimeException('The CMS does not load the official FlowPress Site Editor sync module.');
|
|
44
|
+
}
|
|
45
|
+
$admins = get_users(['role' => 'administrator', 'number' => 1, 'orderby' => 'ID', 'order' => 'ASC', 'fields' => 'ID']);
|
|
46
|
+
if (! $admins) throw new RuntimeException('The local CMS has no administrator.');
|
|
47
|
+
// Saves run as an administrator, like an editor session (trusted code, kses).
|
|
48
|
+
wp_set_current_user((int) $admins[0]);
|
|
49
|
+
$response = ['ok' => true, 'result' => flowpress_site_editor_sync_dispatch((string) $request['operation'], (array) $request['args'])];
|
|
50
|
+
} catch (Throwable $error) {
|
|
51
|
+
$response = ['ok' => false, 'error' => $error->getMessage()];
|
|
52
|
+
}
|
|
53
|
+
echo "\n${RESPONSE_MARKER}\n", wp_json_encode($response);
|
|
54
|
+
`;
|
|
55
|
+
}
|
|
56
|
+
export function parseDockerResponse(result) {
|
|
57
|
+
if (result.error || result.status !== 0)
|
|
58
|
+
throw new Error(`The local CMS command failed (exit ${result.status ?? "unknown"}). ${String(result.stderr ?? "").trim()}`);
|
|
59
|
+
const output = String(result.stdout ?? "");
|
|
60
|
+
const index = output.lastIndexOf(RESPONSE_MARKER);
|
|
61
|
+
if (index < 0) {
|
|
62
|
+
throw new Error(`The local CMS did not answer (exit ${result.status}). Is the Docker stack running (pnpm dev)?\n${String(result.stderr || output).trim()}`);
|
|
63
|
+
}
|
|
64
|
+
const response = JSON.parse(output.slice(index + RESPONSE_MARKER.length));
|
|
65
|
+
if (!response.ok)
|
|
66
|
+
throw new Error(response.error);
|
|
67
|
+
return response.result;
|
|
68
|
+
}
|
|
69
|
+
/** Remote backends: official Site Editor sync REST routes, Application Password (Basic) auth. */
|
|
70
|
+
export function restTransport({ backendUrl, auth, targetName, fetchImpl = fetch }) {
|
|
71
|
+
if (!/^[^:]+:.+$/.test(auth)) {
|
|
72
|
+
throw new Error(`CMS_SYNC_AUTH is missing in .env.${targetName}: set it to "<user>:<application password>" ` +
|
|
73
|
+
"for a user with the edit_theme_options capability (Users → Profile → Application Passwords).");
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
kind: "rest",
|
|
77
|
+
async call(operation, args = {}) {
|
|
78
|
+
const read = operation === "status";
|
|
79
|
+
const response = await fetchImpl(`${backendUrl}/${ROUTE}/${operation}`, {
|
|
80
|
+
method: read ? "GET" : "POST",
|
|
81
|
+
headers: {
|
|
82
|
+
accept: "application/json",
|
|
83
|
+
authorization: `Basic ${Buffer.from(auth).toString("base64")}`,
|
|
84
|
+
...(read ? {} : { "content-type": "application/json" }),
|
|
85
|
+
},
|
|
86
|
+
body: read ? undefined : JSON.stringify(args),
|
|
87
|
+
});
|
|
88
|
+
const text = await response.text();
|
|
89
|
+
let body = null;
|
|
90
|
+
try {
|
|
91
|
+
body = JSON.parse(text);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Reported below with the HTTP status.
|
|
95
|
+
}
|
|
96
|
+
if (response.status === 404 && body?.code === "rest_no_route") {
|
|
97
|
+
throw new Error(`${backendUrl} does not expose the Site Editor sync routes: deploy the backend first (pnpm backend:deploy).`);
|
|
98
|
+
}
|
|
99
|
+
if (["rest_forbidden", "rest_not_logged_in"].includes(body?.code)) {
|
|
100
|
+
// This stack answers a wrong password as anonymous too, not only a dropped header.
|
|
101
|
+
throw new Error(`${backendUrl} treated the request as anonymous (${body.code}): check CMS_SYNC_AUTH in .env.${targetName} ` +
|
|
102
|
+
"and that the user has edit_theme_options; if both are right, the host strips the Authorization header " +
|
|
103
|
+
"(see apps/cms/web/.htaccess).");
|
|
104
|
+
}
|
|
105
|
+
if (response.status === 401 || response.status === 403) {
|
|
106
|
+
throw new Error(`${backendUrl} refused the credentials (${body?.code ?? response.status}): check CMS_SYNC_AUTH in .env.${targetName}.`);
|
|
107
|
+
}
|
|
108
|
+
if (!response.ok || body === null) {
|
|
109
|
+
throw new Error(body?.message ?? `${backendUrl} answered HTTP ${response.status}.`);
|
|
110
|
+
}
|
|
111
|
+
return body;
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=transport.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.mjs","sourceRoot":"","sources":["../../../src/ops/cms-template/transport.mjs"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export function projectRoot(start?: string): string;
|
|
2
|
+
export function readJson(file: any, fallback?: undefined): any;
|
|
3
|
+
export function writeJson(file: any, value: any, mode?: number): void;
|
|
4
|
+
export function readEnv(file: any): import("dotenv").DotenvParseOutput;
|
|
5
|
+
export function origin(value: any, label: any): string;
|
|
6
|
+
export function assertManifest(value: any): any;
|
|
7
|
+
export function readManifest(root?: string): any;
|
|
8
|
+
export function targetConfig(manifest: any, name: any): any;
|
|
9
|
+
export function allowedComponents(manifest: any, name: any, requested?: any[]): any;
|
|
10
|
+
export function identity(root?: string): {
|
|
11
|
+
slug: string;
|
|
12
|
+
displayName: any;
|
|
13
|
+
repository: any;
|
|
14
|
+
};
|
|
15
|
+
export function statePath(root: any, name: any): string;
|
|
16
|
+
export function loadState(root: any, name: any): any;
|
|
17
|
+
export function saveState(root: any, name: any, state: any): void;
|
|
18
|
+
export function platformConfig(root: any, manifest: any, file: any): any;
|
|
19
|
+
export function publicPlatform(id: any, platform: any): {
|
|
20
|
+
id: any;
|
|
21
|
+
coolifyUrl: any;
|
|
22
|
+
serverUuid: any;
|
|
23
|
+
ssh: any;
|
|
24
|
+
network: any;
|
|
25
|
+
subnet: any;
|
|
26
|
+
registry: any;
|
|
27
|
+
registryProject: any;
|
|
28
|
+
backupStorageUuid: any;
|
|
29
|
+
poolUuid: any;
|
|
30
|
+
destinationUuid: any;
|
|
31
|
+
phpImage: any;
|
|
32
|
+
};
|
|
33
|
+
export function databaseIdentity(slug: any, name: any): {
|
|
34
|
+
DB_NAME: string;
|
|
35
|
+
DB_USER: string;
|
|
36
|
+
};
|
|
37
|
+
export function ensureSecrets(root: any, name: any, slug: any): {
|
|
38
|
+
DB_NAME: string;
|
|
39
|
+
DB_USER: string;
|
|
40
|
+
};
|
|
41
|
+
export function operatorEnvironment(root: any): {
|
|
42
|
+
[x: string]: string | undefined;
|
|
43
|
+
};
|
|
44
|
+
export function imageRepository(platform: any, slug: any, component: any): string;
|
|
45
|
+
export function releaseTag(component: any, name: any, sha: any, buildId: any): string;
|
|
46
|
+
export const profiles: Readonly<{
|
|
47
|
+
backend: string[];
|
|
48
|
+
static: string[];
|
|
49
|
+
"headless-static": string[];
|
|
50
|
+
"headless-ssr": string[];
|
|
51
|
+
}>;
|
|
52
|
+
export const environments: string[];
|
|
53
|
+
export const saltKeys: string[];
|
|
54
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/ops/config.js"],"names":[],"mappings":"AAcA,oDAQC;AACD,+DAGC;AACD,sEAKC;AACD,uEAEC;AACD,uDAOC;AACD,gDAmCC;AACD,iDAEC;AACD,4DAGC;AACD,oFAMC;AACD;;;;EAMC;AACD,wDAA+F;AAC/F,qDAAqF;AACrF,kEAWC;AACD,yEAwBC;AACD;;;;;;;;;;;;;EAGC;AACD;;;EAGC;AAED;;;EASC;AACD;;EAEC;AACD,kFAGC;AACD,sFAKC;AApKD;;;;;GAKG;AACH,oCAA0E;AAuI1E,gCAAuJ"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync, renameSync } from "node:fs";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
import { parse as parseYaml } from "yaml";
|
|
5
|
+
import { parse as parseEnv } from "dotenv";
|
|
6
|
+
import { mediaConfiguration, validateMediaValue } from "./media-config.js";
|
|
7
|
+
export const profiles = Object.freeze({
|
|
8
|
+
backend: ["cms"],
|
|
9
|
+
static: ["web-static"],
|
|
10
|
+
"headless-static": ["cms", "web-static"],
|
|
11
|
+
"headless-ssr": ["cms", "web-ssr"],
|
|
12
|
+
});
|
|
13
|
+
export const environments = ["local", "staging", "production", "preview"];
|
|
14
|
+
export function projectRoot(start = process.env.FLOWPRESS_PROJECT_ROOT || process.cwd()) {
|
|
15
|
+
let root = resolve(start);
|
|
16
|
+
while (!existsSync(join(root, "flowpress.deploy.yaml")) && !existsSync(join(root, "pnpm-workspace.yaml"))) {
|
|
17
|
+
const parent = dirname(root);
|
|
18
|
+
if (parent === root)
|
|
19
|
+
throw new Error("Run this command inside a FlowPress project.");
|
|
20
|
+
root = parent;
|
|
21
|
+
}
|
|
22
|
+
return root;
|
|
23
|
+
}
|
|
24
|
+
export function readJson(file, fallback = undefined) {
|
|
25
|
+
if (!existsSync(file))
|
|
26
|
+
return fallback;
|
|
27
|
+
return JSON.parse(readFileSync(file, "utf8"));
|
|
28
|
+
}
|
|
29
|
+
export function writeJson(file, value, mode = 0o644) {
|
|
30
|
+
mkdirSync(dirname(file), { recursive: true, mode: 0o700 });
|
|
31
|
+
const temporary = file + ".tmp-" + process.pid;
|
|
32
|
+
writeFileSync(temporary, JSON.stringify(value, null, 2) + "\n", { mode });
|
|
33
|
+
renameSync(temporary, file);
|
|
34
|
+
}
|
|
35
|
+
export function readEnv(file) {
|
|
36
|
+
return existsSync(file) ? parseEnv(readFileSync(file)) : {};
|
|
37
|
+
}
|
|
38
|
+
export function origin(value, label) {
|
|
39
|
+
let url;
|
|
40
|
+
try {
|
|
41
|
+
url = new URL(value);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
throw new Error(label + " must be an absolute HTTP(S) URL.");
|
|
45
|
+
}
|
|
46
|
+
if (!["https:", "http:"].includes(url.protocol) || url.username || url.password || url.search || url.hash || url.pathname !== "/") {
|
|
47
|
+
throw new Error(label + " must be an origin without credentials, path, query or fragment.");
|
|
48
|
+
}
|
|
49
|
+
return url.origin;
|
|
50
|
+
}
|
|
51
|
+
export function assertManifest(value) {
|
|
52
|
+
if (!value || ![1, 2].includes(value.schemaVersion) || !profiles[value.profile])
|
|
53
|
+
throw new Error("Expected deployment schemaVersion 1|2 and a supported profile.");
|
|
54
|
+
if (typeof value.platform !== "string" || !/^[a-z0-9][a-z0-9-]*$/.test(value.platform))
|
|
55
|
+
throw new Error("Invalid platform identifier.");
|
|
56
|
+
if (value.database !== "shared")
|
|
57
|
+
throw new Error("Use database: shared.");
|
|
58
|
+
if (value.schemaVersion === 2)
|
|
59
|
+
validateMediaValue(value.media);
|
|
60
|
+
else if (!["local", "s3"].includes(value.media))
|
|
61
|
+
throw new Error("Schema 1 media must be local|s3.");
|
|
62
|
+
if (!value.environments || typeof value.environments !== "object")
|
|
63
|
+
throw new Error("Missing environments.");
|
|
64
|
+
if (value.development?.ports)
|
|
65
|
+
for (const [key, port] of Object.entries(value.development.ports)) {
|
|
66
|
+
if (!["web", "cms", "https", "database"].includes(key) || !Number.isInteger(port) || port < 1 || port > 65535)
|
|
67
|
+
throw new Error("Invalid development port: " + key);
|
|
68
|
+
}
|
|
69
|
+
for (const [name, target] of Object.entries(value.environments)) {
|
|
70
|
+
if (value.schemaVersion === 1 && target.media !== undefined)
|
|
71
|
+
throw new Error("Environment media overrides require schemaVersion 2.");
|
|
72
|
+
mediaConfiguration(value, name);
|
|
73
|
+
if (!environments.includes(name))
|
|
74
|
+
throw new Error("Unsupported environment: " + name);
|
|
75
|
+
const components = name === "preview" ? ["web-ssr"] : profiles[target.profile || value.profile];
|
|
76
|
+
if (!components)
|
|
77
|
+
throw new Error("Unsupported profile for " + name);
|
|
78
|
+
if (!Array.isArray(target.publish) || target.publish.some(component => !components.includes(component)) || new Set(target.publish).size !== target.publish.length) {
|
|
79
|
+
throw new Error("Explicit publish list required for " + name + "; select components from " + components.join(", "));
|
|
80
|
+
}
|
|
81
|
+
for (const key of ["backendUrl", "frontendUrl"])
|
|
82
|
+
if (target[key])
|
|
83
|
+
origin(target[key], name + "." + key);
|
|
84
|
+
if (target.mediaUrl) {
|
|
85
|
+
let mediaUrl;
|
|
86
|
+
try {
|
|
87
|
+
mediaUrl = new URL(target.mediaUrl);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
throw new Error("Invalid mediaUrl for " + name);
|
|
91
|
+
}
|
|
92
|
+
if (!["http:", "https:"].includes(mediaUrl.protocol) || mediaUrl.username || mediaUrl.password || mediaUrl.search || mediaUrl.hash)
|
|
93
|
+
throw new Error("Invalid mediaUrl for " + name);
|
|
94
|
+
}
|
|
95
|
+
for (const key of ["aliases", "backendAliases"])
|
|
96
|
+
if (target[key] !== undefined) {
|
|
97
|
+
if (!Array.isArray(target[key]))
|
|
98
|
+
throw new Error(name + "." + key + " must be a list of origins.");
|
|
99
|
+
for (const value of target[key])
|
|
100
|
+
origin(value, name + "." + key);
|
|
101
|
+
}
|
|
102
|
+
if (target.publish.includes("cms") && !target.backendUrl)
|
|
103
|
+
throw new Error(name + " CMS requires backendUrl.");
|
|
104
|
+
if (target.publish.some(component => component !== "cms") && !target.frontendUrl)
|
|
105
|
+
throw new Error(name + " frontend requires frontendUrl.");
|
|
106
|
+
if (name === "preview" && (target.mode !== "on-demand" || !["staging", "production"].includes(target.backend)))
|
|
107
|
+
throw new Error("Preview requires mode: on-demand and backend: staging|production.");
|
|
108
|
+
if (target.backend && !value.environments[target.backend])
|
|
109
|
+
throw new Error("Unknown backend reference: " + target.backend);
|
|
110
|
+
}
|
|
111
|
+
return value;
|
|
112
|
+
}
|
|
113
|
+
export function readManifest(root = projectRoot()) {
|
|
114
|
+
return assertManifest(parseYaml(readFileSync(join(root, "flowpress.deploy.yaml"), "utf8"), { uniqueKeys: true, maxAliasCount: 0 }));
|
|
115
|
+
}
|
|
116
|
+
export function targetConfig(manifest, name) {
|
|
117
|
+
if (!environments.includes(name) || !manifest.environments[name])
|
|
118
|
+
throw new Error("Environment not configured: " + name);
|
|
119
|
+
return manifest.environments[name];
|
|
120
|
+
}
|
|
121
|
+
export function allowedComponents(manifest, name, requested = []) {
|
|
122
|
+
const target = targetConfig(manifest, name);
|
|
123
|
+
const selected = requested.length ? requested : target.publish;
|
|
124
|
+
if (!selected.length)
|
|
125
|
+
throw new Error("Publication is disabled for " + name + ".");
|
|
126
|
+
for (const component of selected)
|
|
127
|
+
if (!target.publish.includes(component))
|
|
128
|
+
throw new Error("Publication of " + component + " is disabled for " + name + ".");
|
|
129
|
+
return selected;
|
|
130
|
+
}
|
|
131
|
+
export function identity(root = projectRoot()) {
|
|
132
|
+
const config = readJson(join(root, "flowpress.config.json"));
|
|
133
|
+
const pkg = readJson(join(root, "package.json"), {});
|
|
134
|
+
const slug = config?.project?.slug || pkg.name;
|
|
135
|
+
if (typeof slug !== "string" || !/^[a-z0-9][a-z0-9.-]*$/.test(slug))
|
|
136
|
+
throw new Error("A safe project slug is required.");
|
|
137
|
+
return { slug, displayName: config?.project?.displayName || slug, repository: config?.repository?.slug };
|
|
138
|
+
}
|
|
139
|
+
export function statePath(root, name) { return join(root, "deploy", "state", name + ".json"); }
|
|
140
|
+
export function loadState(root, name) { return readJson(statePath(root, name), {}); }
|
|
141
|
+
export function saveState(root, name, state) {
|
|
142
|
+
const binding = structuredClone(state), runtime = { apps: {} };
|
|
143
|
+
for (const [component, app] of Object.entries(binding.apps || {})) {
|
|
144
|
+
for (const key of ["current", "previous", "deployedAt"])
|
|
145
|
+
if (app[key] !== undefined) {
|
|
146
|
+
runtime.apps[component] ||= {};
|
|
147
|
+
runtime.apps[component][key] = app[key];
|
|
148
|
+
delete app[key];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
writeJson(statePath(root, name), binding);
|
|
152
|
+
if (Object.keys(runtime.apps).length)
|
|
153
|
+
writeJson(join(root, ".local/flowpress", "runtime-" + name + ".json"), runtime, 0o600);
|
|
154
|
+
}
|
|
155
|
+
export function platformConfig(root, manifest, file) {
|
|
156
|
+
if (file || process.env.FLOWPRESS_PLATFORMS_FILE) {
|
|
157
|
+
const catalogFile = file || process.env.FLOWPRESS_PLATFORMS_FILE;
|
|
158
|
+
const catalog = parseYaml(readFileSync(catalogFile, "utf8"));
|
|
159
|
+
const platform = catalog.platforms?.[manifest.platform];
|
|
160
|
+
if (!platform)
|
|
161
|
+
throw new Error("Platform not found: " + manifest.platform);
|
|
162
|
+
if (platform.server) {
|
|
163
|
+
const server = parseYaml(readFileSync(join(dirname(catalogFile), "servers.yaml"), "utf8")).servers?.[platform.server];
|
|
164
|
+
if (!server?.ssh?.alias || !server.ssh.user || !server.coolify_server_uuid)
|
|
165
|
+
throw new Error("Incomplete server inventory binding: " + platform.server);
|
|
166
|
+
platform.serverUuid = server.coolify_server_uuid;
|
|
167
|
+
platform.ssh = server.ssh.user + "@" + server.ssh.alias;
|
|
168
|
+
}
|
|
169
|
+
if (platform.panel) {
|
|
170
|
+
const panel = parseYaml(readFileSync(join(dirname(catalogFile), "panels.yaml"), "utf8")).panels?.[platform.panel];
|
|
171
|
+
if (!panel?.panel_url_tailnet)
|
|
172
|
+
throw new Error("Missing private panel URL in inventory.");
|
|
173
|
+
platform.coolifyUrl = panel.panel_url_tailnet;
|
|
174
|
+
}
|
|
175
|
+
return { ...platform, registryProject: manifest.registryProject || identity(root).slug };
|
|
176
|
+
}
|
|
177
|
+
for (const name of Object.keys(manifest.environments)) {
|
|
178
|
+
const state = loadState(root, name);
|
|
179
|
+
if (state.platform?.id === manifest.platform)
|
|
180
|
+
return { ...state.platform, registryProject: manifest.registryProject || identity(root).slug };
|
|
181
|
+
}
|
|
182
|
+
throw new Error("Set FLOWPRESS_PLATFORMS_FILE for initial provisioning.");
|
|
183
|
+
}
|
|
184
|
+
export function publicPlatform(id, platform) {
|
|
185
|
+
const { coolifyUrl, serverUuid, ssh, network, subnet, registry, registryProject, backupStorageUuid, poolUuid, destinationUuid, phpImage } = platform;
|
|
186
|
+
return { id, coolifyUrl, serverUuid, ssh, network, subnet, registry, registryProject, backupStorageUuid, poolUuid, destinationUuid, phpImage };
|
|
187
|
+
}
|
|
188
|
+
export function databaseIdentity(slug, name) {
|
|
189
|
+
const hash = createHash("sha256").update(slug + ":" + name).digest("hex").slice(0, 16);
|
|
190
|
+
return { DB_NAME: "fp" + hash, DB_USER: "fp" + hash };
|
|
191
|
+
}
|
|
192
|
+
export const saltKeys = ["AUTH_KEY", "SECURE_AUTH_KEY", "LOGGED_IN_KEY", "NONCE_KEY", "AUTH_SALT", "SECURE_AUTH_SALT", "LOGGED_IN_SALT", "NONCE_SALT"];
|
|
193
|
+
export function ensureSecrets(root, name, slug) {
|
|
194
|
+
const file = join(root, ".secrets", name + ".env");
|
|
195
|
+
const current = readEnv(file);
|
|
196
|
+
const values = { ...databaseIdentity(slug, name), ...current };
|
|
197
|
+
for (const key of [...saltKeys, "DB_PASSWORD", "CMS_BUILD_CALLBACK_TOKEN"])
|
|
198
|
+
values[key] ||= randomBytes(32).toString("hex");
|
|
199
|
+
values.DB_PREFIX ||= "fp_";
|
|
200
|
+
mkdirSync(dirname(file), { recursive: true, mode: 0o700 });
|
|
201
|
+
writeFileSync(file, Object.entries(values).map(([key, value]) => key + "=" + JSON.stringify(value)).join("\n") + "\n", { mode: 0o600 });
|
|
202
|
+
return values;
|
|
203
|
+
}
|
|
204
|
+
export function operatorEnvironment(root) {
|
|
205
|
+
return { ...readEnv(join(root, ".secrets", "ops.env")), ...process.env };
|
|
206
|
+
}
|
|
207
|
+
export function imageRepository(platform, slug, component) {
|
|
208
|
+
if (!/^[a-z0-9][a-z0-9.-]*$/.test(slug) || !["cms", "web-static", "web-ssr"].includes(component))
|
|
209
|
+
throw new Error("Invalid image identity.");
|
|
210
|
+
return platform.registry + "/" + platform.registryProject + "/" + slug + "-" + component;
|
|
211
|
+
}
|
|
212
|
+
export function releaseTag(component, name, sha, buildId) {
|
|
213
|
+
if (!/^[a-f0-9]{40}$/.test(sha))
|
|
214
|
+
throw new Error("Expected a full commit SHA.");
|
|
215
|
+
if (component === "cms")
|
|
216
|
+
return "sha-" + sha;
|
|
217
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9.-]{0,63}$/.test(buildId || ""))
|
|
218
|
+
throw new Error("A safe frontend build ID is required.");
|
|
219
|
+
return name + "-" + sha + "-" + buildId;
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/ops/config.js"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coolify.d.ts","sourceRoot":"","sources":["../../src/ops/coolify.js"],"names":[],"mappings":"AACA,0DAGgC,WAAM,EAAE,SAAI,EAAE,SAAI,kBA8BjD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Minimal Coolify v4 REST client (reachable only through the tailnet).
|
|
2
|
+
export function coolifyClient(baseUrl, token) {
|
|
3
|
+
if (!token)
|
|
4
|
+
throw new Error("Missing Coolify API token (COOLIFY_TOKEN).");
|
|
5
|
+
const api = `${baseUrl.replace(/\/+$/, "")}/api/v1`;
|
|
6
|
+
return async function request(method, path, body) {
|
|
7
|
+
for (let attempt = 0;; attempt++) {
|
|
8
|
+
try {
|
|
9
|
+
const response = await fetch(`${api}${path}`, {
|
|
10
|
+
method,
|
|
11
|
+
signal: AbortSignal.timeout(30_000),
|
|
12
|
+
headers: {
|
|
13
|
+
accept: "application/json",
|
|
14
|
+
authorization: `Bearer ${token}`,
|
|
15
|
+
...(body ? { "content-type": "application/json" } : {}),
|
|
16
|
+
},
|
|
17
|
+
...(body ? { body: JSON.stringify(body) } : {}),
|
|
18
|
+
});
|
|
19
|
+
const text = await response.text();
|
|
20
|
+
let data;
|
|
21
|
+
try {
|
|
22
|
+
data = text ? JSON.parse(text) : {};
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
data = { message: text.slice(0, 300) };
|
|
26
|
+
}
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
const details = data?.message ? String(data.message).replace(/Bearer\s+\S+/g, "[redacted]").slice(0, 160) : "Request refused";
|
|
29
|
+
const error = new Error(`${method} ${path.split("?")[0]} -> HTTP ${response.status}: ${details}`);
|
|
30
|
+
error.status = response.status;
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
return data;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
const transient = error.status === undefined || error.status >= 500 || error.status === 429;
|
|
37
|
+
if (method !== "GET" || !transient || attempt >= 2)
|
|
38
|
+
throw error;
|
|
39
|
+
await new Promise((resolve) => setTimeout(resolve, 2000 * (attempt + 1)));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=coolify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coolify.js","sourceRoot":"","sources":["../../src/ops/coolify.js"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,MAAM,UAAU,aAAa,CAAC,OAAO,EAAE,KAAK;IAC1C,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC1E,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC;IACpD,OAAO,KAAK,UAAU,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI;QAC9C,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,EAAE,EAAE;oBAC5C,MAAM;oBACN,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;oBACnC,OAAO,EAAE;wBACP,MAAM,EAAE,kBAAkB;wBAC1B,aAAa,EAAE,UAAU,KAAK,EAAE;wBAChC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACxD;oBACD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAChD,CAAC,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnC,IAAI,IAAI,CAAC;gBACT,IAAI,CAAC;oBAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC;oBAAC,IAAI,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;gBAAC,CAAC;gBAC9F,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC;oBAC9H,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,GAAG,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,QAAQ,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC;oBAClG,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;oBAC/B,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC;gBAC5F,IAAI,MAAM,KAAK,KAAK,IAAI,CAAC,SAAS,IAAI,OAAO,IAAI,CAAC;oBAAE,MAAM,KAAK,CAAC;gBAChE,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function safeArchiveEntries(entries: any): void;
|
|
2
|
+
export function pullSource(root: any, manifest: any, sourceName: any): Promise<{
|
|
3
|
+
source: any;
|
|
4
|
+
createdAt: string;
|
|
5
|
+
dump: string;
|
|
6
|
+
archive: string;
|
|
7
|
+
sha256: string;
|
|
8
|
+
}>;
|
|
9
|
+
export function prepareData(root: any, manifest: any, name: any, { file, image, source }: {
|
|
10
|
+
file: any;
|
|
11
|
+
image: any;
|
|
12
|
+
source?: string | undefined;
|
|
13
|
+
}): Promise<{
|
|
14
|
+
file: string;
|
|
15
|
+
counts: any;
|
|
16
|
+
prefix: any;
|
|
17
|
+
}>;
|
|
18
|
+
export function pushData(root: any, manifest: any, name: any, file: any): Promise<{
|
|
19
|
+
environment: any;
|
|
20
|
+
imported: boolean;
|
|
21
|
+
database: any;
|
|
22
|
+
}>;
|
|
23
|
+
export function pushUploads(root: any, manifest: any, name: any, archive: any): Promise<{
|
|
24
|
+
environment: any;
|
|
25
|
+
uploadsCopied: boolean;
|
|
26
|
+
}>;
|
|
27
|
+
export function cleanIntegrations(root: any, manifest: any, name: any): Promise<{
|
|
28
|
+
environment: any;
|
|
29
|
+
output: any;
|
|
30
|
+
}>;
|
|
31
|
+
//# sourceMappingURL=data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../src/ops/data.js"],"names":[],"mappings":"AAWA,uDAGC;AACD;;;;;;GAgBC;AAUD;;;;;;;;GAuDC;AACD;;;;GAiBC;AACD;;;GAWC;AAED;;;GAUC"}
|