@geekmidas/cli 10.0.0-alpha.92 → 10.0.0-alpha.93
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/dist/{GoDaddyProvider-CJwg2r_9.cjs → GoDaddyProvider-BZb-V14e.cjs} +2 -2
- package/dist/{GoDaddyProvider-CJwg2r_9.cjs.map → GoDaddyProvider-BZb-V14e.cjs.map} +1 -1
- package/dist/{GoDaddyProvider-BqYGk9XT.mjs → GoDaddyProvider-Mi3vptSR.mjs} +2 -2
- package/dist/{GoDaddyProvider-BqYGk9XT.mjs.map → GoDaddyProvider-Mi3vptSR.mjs.map} +1 -1
- package/dist/{LegacyStateStore-CeEwayMB.cjs → LegacyStateStore-BlYXQQSE.cjs} +44 -10
- package/dist/LegacyStateStore-BlYXQQSE.cjs.map +1 -0
- package/dist/LegacyStateStore-CtwO7fwy.mjs +123 -0
- package/dist/LegacyStateStore-CtwO7fwy.mjs.map +1 -0
- package/dist/{LocalStateStore-Y8XHdoCR.mjs → LocalStateStore-D40_SDmJ.mjs} +2 -2
- package/dist/{LocalStateStore-Y8XHdoCR.mjs.map → LocalStateStore-D40_SDmJ.mjs.map} +1 -1
- package/dist/{LocalStateStore-BMfseje2.cjs → LocalStateStore-oX_zxj9V.cjs} +2 -2
- package/dist/{LocalStateStore-BMfseje2.cjs.map → LocalStateStore-oX_zxj9V.cjs.map} +1 -1
- package/dist/{S3StateStore-BfoY4MvD.mjs → S3StateStore-BzS0IeSt.mjs} +2 -2
- package/dist/{S3StateStore-BfoY4MvD.mjs.map → S3StateStore-BzS0IeSt.mjs.map} +1 -1
- package/dist/{S3StateStore-BmMt2HhW.cjs → S3StateStore-DeI7jtvi.cjs} +2 -2
- package/dist/{S3StateStore-BmMt2HhW.cjs.map → S3StateStore-DeI7jtvi.cjs.map} +1 -1
- package/dist/{SSMStateStore-D9K62wM4.cjs → SSMStateStore-CaCtrzFL.cjs} +2 -2
- package/dist/{SSMStateStore-D9K62wM4.cjs.map → SSMStateStore-CaCtrzFL.cjs.map} +1 -1
- package/dist/{SSMStateStore-Bdyw_0Jj.mjs → SSMStateStore-k_Ew7TWx.mjs} +2 -2
- package/dist/{SSMStateStore-Bdyw_0Jj.mjs.map → SSMStateStore-k_Ew7TWx.mjs.map} +1 -1
- package/dist/{add-2Opn2VVE.mjs → add-CP1podDH.mjs} +2 -3
- package/dist/{add-2Opn2VVE.mjs.map → add-CP1podDH.mjs.map} +1 -1
- package/dist/{add-oN0b18HN.cjs → add-VcyJnsPX.cjs} +3 -4
- package/dist/{add-oN0b18HN.cjs.map → add-VcyJnsPX.cjs.map} +1 -1
- package/dist/{bundler-C-AdesaG.mjs → bundler-BWrh-AJH.mjs} +3 -3
- package/dist/{bundler-C-AdesaG.mjs.map → bundler-BWrh-AJH.mjs.map} +1 -1
- package/dist/{bundler-CXQDrhzN.cjs → bundler-Dfsr6KXU.cjs} +3 -3
- package/dist/{bundler-CXQDrhzN.cjs.map → bundler-Dfsr6KXU.cjs.map} +1 -1
- package/dist/{cli-BjhaVObS.mjs → cli-B8otnZfX.mjs} +4 -4
- package/dist/{cli-BjhaVObS.mjs.map → cli-B8otnZfX.mjs.map} +1 -1
- package/dist/{cli-BRZFYvdb.cjs → cli-DL19w4OE.cjs} +2 -2
- package/dist/{cli-BRZFYvdb.cjs.map → cli-DL19w4OE.cjs.map} +1 -1
- package/dist/compose-BHVKLluX.cjs +1523 -0
- package/dist/compose-BHVKLluX.cjs.map +1 -0
- package/dist/compose-DrEB_4F-.mjs +1476 -0
- package/dist/compose-DrEB_4F-.mjs.map +1 -0
- package/dist/{config-BJo8Wggp.d.mts → config-CHX5GOo3.d.mts} +4 -4
- package/dist/{config-BJo8Wggp.d.mts.map → config-CHX5GOo3.d.mts.map} +1 -1
- package/dist/{config-C9zx7KsX.d.cts → config-DCCcrOSo.d.cts} +4 -4
- package/dist/{config-C9zx7KsX.d.cts.map → config-DCCcrOSo.d.cts.map} +1 -1
- package/dist/config.d.cts +3 -3
- package/dist/config.d.mts +3 -3
- package/dist/deploy/public.cjs +6 -5
- package/dist/deploy/public.d.cts +6 -6
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts +6 -6
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +6 -6
- package/dist/{deploy-6ToUHJmM.cjs → deploy-C3Mhnmus.cjs} +4 -3
- package/dist/deploy-C3Mhnmus.cjs.map +1 -0
- package/dist/{deploy-yuJHlkY0.mjs → deploy-DYIyIUYd.mjs} +4 -3
- package/dist/deploy-DYIyIUYd.mjs.map +1 -0
- package/dist/{discover-CRMhvHG9.d.cts → discover-DqwlBVyY.d.mts} +2 -2
- package/dist/{discover-CRMhvHG9.d.cts.map → discover-DqwlBVyY.d.mts.map} +1 -1
- package/dist/{discover-G76EQ4vY.d.mts → discover-vk2r5giK.d.cts} +2 -2
- package/dist/{discover-G76EQ4vY.d.mts.map → discover-vk2r5giK.d.cts.map} +1 -1
- package/dist/{dokploy-BvbJ_A4Q.mjs → dokploy-o4I6vb9W.mjs} +2 -2
- package/dist/{dokploy-BvbJ_A4Q.mjs.map → dokploy-o4I6vb9W.mjs.map} +1 -1
- package/dist/{dokploy-Bvvfj2qe.cjs → dokploy-rivb1RFt.cjs} +2 -2
- package/dist/{dokploy-Bvvfj2qe.cjs.map → dokploy-rivb1RFt.cjs.map} +1 -1
- package/dist/{encryption-C9Jm9dfn.mjs → encryption-B6ilrT7p.mjs} +2 -2
- package/dist/{encryption-C9Jm9dfn.mjs.map → encryption-B6ilrT7p.mjs.map} +1 -1
- package/dist/{encryption-CgW167LO.cjs → encryption-D7zmwzWz.cjs} +2 -2
- package/dist/{encryption-CgW167LO.cjs.map → encryption-D7zmwzWz.cjs.map} +1 -1
- package/dist/{engine-Dj7ZKO8H.cjs → engine-Cfx8fEZU.cjs} +6 -5
- package/dist/engine-Cfx8fEZU.cjs.map +1 -0
- package/dist/{engine-C8Ye9MUm.mjs → engine-DjEcovm-.mjs} +6 -5
- package/dist/engine-DjEcovm-.mjs.map +1 -0
- package/dist/{github-B1k42hIt.mjs → github-CzBbs43W.mjs} +2 -2
- package/dist/{github-B1k42hIt.mjs.map → github-CzBbs43W.mjs.map} +1 -1
- package/dist/{github-BD051KZZ.cjs → github-zneTMvnO.cjs} +2 -2
- package/dist/{github-BD051KZZ.cjs.map → github-zneTMvnO.cjs.map} +1 -1
- package/dist/{index-D1pHwqkK.d.mts → index-BiYU7cUl.d.mts} +2 -2
- package/dist/{index-B5uuwx-Y.d.cts.map → index-BiYU7cUl.d.mts.map} +1 -1
- package/dist/{index-B5uuwx-Y.d.cts → index-Dm6V9bwh.d.cts} +2 -2
- package/dist/{index-D1pHwqkK.d.mts.map → index-Dm6V9bwh.d.cts.map} +1 -1
- package/dist/index.cjs +143 -184
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +141 -181
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-IZsYyZ5F.mjs → migrate-BaC4w0sb.mjs} +2 -2
- package/dist/{migrate-IZsYyZ5F.mjs.map → migrate-BaC4w0sb.mjs.map} +1 -1
- package/dist/{migrate-D3VVsiHp.cjs → migrate-C8wTpakT.cjs} +2 -2
- package/dist/{migrate-D3VVsiHp.cjs.map → migrate-C8wTpakT.cjs.map} +1 -1
- package/dist/{migrate-BSbZ7-9n.mjs → migrate-CsBZKALY.mjs} +3 -3
- package/dist/{migrate-BSbZ7-9n.mjs.map → migrate-CsBZKALY.mjs.map} +1 -1
- package/dist/{migrate-f6JDjyCp.cjs → migrate-DFjbGnSr.cjs} +2 -2
- package/dist/{migrate-f6JDjyCp.cjs.map → migrate-DFjbGnSr.cjs.map} +1 -1
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/reconcile/public.d.cts +2 -2
- package/dist/reconcile/public.d.mts +2 -2
- package/dist/{reconcile-Dh1Jk7WE.mjs → reconcile--I7V4Klj.mjs} +2 -2
- package/dist/{reconcile-Dh1Jk7WE.mjs.map → reconcile--I7V4Klj.mjs.map} +1 -1
- package/dist/{resolve-Be4bF1w4.mjs → resolve-Ccjlpnd9.mjs} +3 -3
- package/dist/{resolve-Be4bF1w4.mjs.map → resolve-Ccjlpnd9.mjs.map} +1 -1
- package/dist/{resolve-DUp65SnJ.cjs → resolve-g8htuR80.cjs} +3 -3
- package/dist/{resolve-DUp65SnJ.cjs.map → resolve-g8htuR80.cjs.map} +1 -1
- package/dist/{rollback-DDHtd0GJ.cjs → rollback--ympG9ss.cjs} +5 -4
- package/dist/rollback--ympG9ss.cjs.map +1 -0
- package/dist/{rollback-D1d-fW0r.mjs → rollback-Drbg0OeR.mjs} +5 -4
- package/dist/rollback-Drbg0OeR.mjs.map +1 -0
- package/dist/{runtime-Es1V4e9M.d.mts → runtime-D_J3ExJn.d.cts} +2 -2
- package/dist/{runtime-DDrHlYe5.d.cts.map → runtime-D_J3ExJn.d.cts.map} +1 -1
- package/dist/{runtime-DDrHlYe5.d.cts → runtime-_wEVtshH.d.mts} +2 -2
- package/dist/{runtime-Es1V4e9M.d.mts.map → runtime-_wEVtshH.d.mts.map} +1 -1
- package/dist/{sandbox-C3WsTa5m.d.mts → sandbox-CPJq1Kia.d.mts} +2 -2
- package/dist/{sandbox-C3WsTa5m.d.mts.map → sandbox-CPJq1Kia.d.mts.map} +1 -1
- package/dist/{sandbox-MaxSeU92.d.cts → sandbox-JwuPAl7I.d.cts} +2 -2
- package/dist/{sandbox-MaxSeU92.d.cts.map → sandbox-JwuPAl7I.d.cts.map} +1 -1
- package/dist/secrets-DJteijZo.cjs +47 -0
- package/dist/secrets-DJteijZo.cjs.map +1 -0
- package/dist/secrets-DbPmAS4k.mjs +36 -0
- package/dist/secrets-DbPmAS4k.mjs.map +1 -0
- package/dist/{seeds-CvGQJnPO.mjs → seeds-BSL55F6q.mjs} +897 -59
- package/dist/seeds-BSL55F6q.mjs.map +1 -0
- package/dist/{seeds-BKoJYsE7.cjs → seeds-c-ByX9je.cjs} +1014 -80
- package/dist/seeds-c-ByX9je.cjs.map +1 -0
- package/dist/stack-1PeLJS2j.cjs +1346 -0
- package/dist/stack-1PeLJS2j.cjs.map +1 -0
- package/dist/stack-Co4uZkAo.mjs +1239 -0
- package/dist/stack-Co4uZkAo.mjs.map +1 -0
- package/dist/target/public.cjs +1 -1
- package/dist/target/public.d.cts +2 -2
- package/dist/target/public.d.mts +2 -2
- package/dist/target/public.mjs +1 -1
- package/dist/{terminal-Dtd6BZX9.mjs → terminal-C4XRdwnU.mjs} +2 -2
- package/dist/{terminal-Dtd6BZX9.mjs.map → terminal-C4XRdwnU.mjs.map} +1 -1
- package/dist/{types-Bk9st2cd.d.cts → types-B6lmD3en.d.mts} +77 -26
- package/dist/types-B6lmD3en.d.mts.map +1 -0
- package/dist/{types-B3Gqs175.d.mts → types-BibpiHKB.d.cts} +78 -25
- package/dist/types-BibpiHKB.d.cts.map +1 -0
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/package.json +15 -15
- package/dist/LegacyStateStore-CeEwayMB.cjs.map +0 -1
- package/dist/LegacyStateStore-DdJ1bCRV.mjs +0 -89
- package/dist/LegacyStateStore-DdJ1bCRV.mjs.map +0 -1
- package/dist/compose-CTdVeeVk.mjs +0 -3151
- package/dist/compose-CTdVeeVk.mjs.map +0 -1
- package/dist/compose-fnYmPk_c.cjs +0 -3276
- package/dist/compose-fnYmPk_c.cjs.map +0 -1
- package/dist/deploy-6ToUHJmM.cjs.map +0 -1
- package/dist/deploy-yuJHlkY0.mjs.map +0 -1
- package/dist/engine-C8Ye9MUm.mjs.map +0 -1
- package/dist/engine-Dj7ZKO8H.cjs.map +0 -1
- package/dist/rollback-D1d-fW0r.mjs.map +0 -1
- package/dist/rollback-DDHtd0GJ.cjs.map +0 -1
- package/dist/seeds-BKoJYsE7.cjs.map +0 -1
- package/dist/seeds-CvGQJnPO.mjs.map +0 -1
- package/dist/types-B3Gqs175.d.mts.map +0 -1
- package/dist/types-Bk9st2cd.d.cts.map +0 -1
|
@@ -7,7 +7,7 @@ const require_workspace = require("./workspace-CHOB2Xg3.cjs");
|
|
|
7
7
|
const require_config = require("./config.cjs");
|
|
8
8
|
const require_EndpointGenerator = require("./EndpointGenerator-De03t1hd.cjs");
|
|
9
9
|
const require_SubscriberGenerator = require("./SubscriberGenerator-Dvz7EzqK.cjs");
|
|
10
|
-
const require_resolve = require("./resolve-
|
|
10
|
+
const require_resolve = require("./resolve-g8htuR80.cjs");
|
|
11
11
|
let node_path = require("node:path");
|
|
12
12
|
let node_fs = require("node:fs");
|
|
13
13
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -6950,6 +6950,126 @@ function reportDevServices(ctx, uses) {
|
|
|
6950
6950
|
}
|
|
6951
6951
|
}
|
|
6952
6952
|
//#endregion
|
|
6953
|
+
//#region src/deploy/actor.ts
|
|
6954
|
+
/**
|
|
6955
|
+
* Who wrote a stage's deploy state: a GitHub Actions run, or a person at a
|
|
6956
|
+
* machine. Recorded on every state write (`updatedBy`), on every resource
|
|
6957
|
+
* record and on every release (`releasedBy`), so "who put this here" has an
|
|
6958
|
+
* answer that does not depend on anyone's memory.
|
|
6959
|
+
*/
|
|
6960
|
+
/** Whether `env` is a CI job — GitHub Actions or any runner that sets `CI`. */
|
|
6961
|
+
function isCi(env = process.env) {
|
|
6962
|
+
return env.GITHUB_ACTIONS === "true" || env.CI === "true";
|
|
6963
|
+
}
|
|
6964
|
+
/** Who this process is writing as. */
|
|
6965
|
+
function currentActor(env = process.env) {
|
|
6966
|
+
if (env.GITHUB_ACTIONS === "true") {
|
|
6967
|
+
const server = env.GITHUB_SERVER_URL ?? "https://github.com";
|
|
6968
|
+
return {
|
|
6969
|
+
kind: "github",
|
|
6970
|
+
actor: env.GITHUB_ACTOR ?? "unknown",
|
|
6971
|
+
run: `${server}/${env.GITHUB_REPOSITORY ?? "unknown"}/actions/runs/${env.GITHUB_RUN_ID ?? "unknown"}`,
|
|
6972
|
+
...env.GITHUB_WORKFLOW ? { workflow: env.GITHUB_WORKFLOW } : {}
|
|
6973
|
+
};
|
|
6974
|
+
}
|
|
6975
|
+
let user = "unknown";
|
|
6976
|
+
try {
|
|
6977
|
+
user = (0, node_os.userInfo)().username;
|
|
6978
|
+
} catch {}
|
|
6979
|
+
return {
|
|
6980
|
+
kind: "local",
|
|
6981
|
+
user,
|
|
6982
|
+
host: (0, node_os.hostname)()
|
|
6983
|
+
};
|
|
6984
|
+
}
|
|
6985
|
+
/** `octocat (deploy, https://github.com/…/runs/1)` or `ada@laptop`. */
|
|
6986
|
+
function describeActor(actor) {
|
|
6987
|
+
if (!actor) return "unknown";
|
|
6988
|
+
if (actor.kind === "local") return `${actor.user}@${actor.host}`;
|
|
6989
|
+
return `${actor.actor} (${actor.workflow ? `${actor.workflow}, ` : ""}${actor.run})`;
|
|
6990
|
+
}
|
|
6991
|
+
//#endregion
|
|
6992
|
+
//#region src/deploy/dnsResources.ts
|
|
6993
|
+
/** The resource type of a DNS record gkm wrote. */
|
|
6994
|
+
const DNS_RECORD_RESOURCE = "dns-record";
|
|
6995
|
+
/** A record's full name: `api.example.com`, or the domain for `@`. */
|
|
6996
|
+
function dnsRecordFqdn(domain, name) {
|
|
6997
|
+
return name === "@" || name === "" ? domain : `${name}.${domain}`;
|
|
6998
|
+
}
|
|
6999
|
+
/** `dns-record:<fqdn>:<type>` */
|
|
7000
|
+
function dnsResourceKey(fqdn, type) {
|
|
7001
|
+
return `${DNS_RECORD_RESOURCE}:${fqdn.toLowerCase()}:${type.toUpperCase()}`;
|
|
7002
|
+
}
|
|
7003
|
+
/** The resource record a written DNS record is kept as. */
|
|
7004
|
+
function dnsRecordResource(record) {
|
|
7005
|
+
const fqdn = dnsRecordFqdn(record.domain, record.name).toLowerCase();
|
|
7006
|
+
const type = record.type.toUpperCase();
|
|
7007
|
+
const data = {
|
|
7008
|
+
domain: record.domain,
|
|
7009
|
+
name: record.name,
|
|
7010
|
+
value: record.value,
|
|
7011
|
+
ttl: record.ttl,
|
|
7012
|
+
...record.provider ? { provider: record.provider } : {}
|
|
7013
|
+
};
|
|
7014
|
+
return {
|
|
7015
|
+
key: dnsResourceKey(fqdn, type),
|
|
7016
|
+
type: DNS_RECORD_RESOURCE,
|
|
7017
|
+
id: `${fqdn} ${type}`,
|
|
7018
|
+
status: "ready",
|
|
7019
|
+
data
|
|
7020
|
+
};
|
|
7021
|
+
}
|
|
7022
|
+
/** Records that gkm wrote `record` — or updates the value it holds. */
|
|
7023
|
+
async function recordDnsResource(journal, record) {
|
|
7024
|
+
const { key, type, id, data } = dnsRecordResource(record);
|
|
7025
|
+
await journal.ready({
|
|
7026
|
+
key,
|
|
7027
|
+
type,
|
|
7028
|
+
...data ? { data } : {}
|
|
7029
|
+
}, id);
|
|
7030
|
+
}
|
|
7031
|
+
/** Forgets a DNS record gkm deleted. */
|
|
7032
|
+
async function forgetDnsResource(journal, record) {
|
|
7033
|
+
await journal.forget(dnsResourceKey(dnsRecordFqdn(record.domain, record.name), record.type));
|
|
7034
|
+
}
|
|
7035
|
+
/**
|
|
7036
|
+
* The changes a DNS step made, kept: what it created, updated or wrote is
|
|
7037
|
+
* recorded, what it deleted is forgotten. A record it found already right is
|
|
7038
|
+
* recorded only if gkm wrote it before; one it left to a person is not.
|
|
7039
|
+
*/
|
|
7040
|
+
async function recordDnsChanges(journal, changes, providerOf) {
|
|
7041
|
+
for (const change of changes) {
|
|
7042
|
+
if (change.action === "delete") {
|
|
7043
|
+
await forgetDnsResource(journal, change);
|
|
7044
|
+
continue;
|
|
7045
|
+
}
|
|
7046
|
+
const written = change.action === "create" || change.action === "update" || change.action === "write";
|
|
7047
|
+
const known = change.action === "unchanged" && journal.record(dnsResourceKey(dnsRecordFqdn(change.domain, change.name), change.type)) !== void 0;
|
|
7048
|
+
if (!written && !known || change.value === void 0) continue;
|
|
7049
|
+
const provider = providerOf(change.domain);
|
|
7050
|
+
await recordDnsResource(journal, {
|
|
7051
|
+
domain: change.domain,
|
|
7052
|
+
name: change.name,
|
|
7053
|
+
type: change.type,
|
|
7054
|
+
value: change.value,
|
|
7055
|
+
ttl: change.ttl ?? 0,
|
|
7056
|
+
...provider ? { provider } : {}
|
|
7057
|
+
});
|
|
7058
|
+
}
|
|
7059
|
+
}
|
|
7060
|
+
/** Every DNS record gkm wrote for the stage, from its resource records. */
|
|
7061
|
+
function dnsResources(resources) {
|
|
7062
|
+
return Object.values(resources).filter((record) => record.type === DNS_RECORD_RESOURCE).map((record) => {
|
|
7063
|
+
const data = record.data ?? {};
|
|
7064
|
+
const [fqdn = "", type = ""] = (record.id ?? "").split(" ");
|
|
7065
|
+
return {
|
|
7066
|
+
...data,
|
|
7067
|
+
type,
|
|
7068
|
+
fqdn
|
|
7069
|
+
};
|
|
7070
|
+
}).sort((a, b) => a.fqdn.localeCompare(b.fqdn) || a.type.localeCompare(b.type));
|
|
7071
|
+
}
|
|
7072
|
+
//#endregion
|
|
6953
7073
|
//#region src/deploy/StateProvider.ts
|
|
6954
7074
|
/**
|
|
6955
7075
|
* Check if value is a StateProvider implementation.
|
|
@@ -6957,28 +7077,6 @@ function reportDevServices(ctx, uses) {
|
|
|
6957
7077
|
function isStateProvider(value) {
|
|
6958
7078
|
return typeof value === "object" && value !== null && typeof value.read === "function" && typeof value.write === "function";
|
|
6959
7079
|
}
|
|
6960
|
-
//#endregion
|
|
6961
|
-
//#region src/deploy/StateStore.ts
|
|
6962
|
-
/**
|
|
6963
|
-
* Deploy state store.
|
|
6964
|
-
*
|
|
6965
|
-
* `StateProvider` reads and writes a whole stage at once, with nothing to stop
|
|
6966
|
-
* two runs of the same stage from overwriting each other and nowhere to record
|
|
6967
|
-
* a resource the moment it exists. A `StateStore` adds the three things a
|
|
6968
|
-
* deploy needs to be safe against crashes and concurrent runs:
|
|
6969
|
-
*
|
|
6970
|
-
* - `lock(stage)`: one run per stage. A second gets `StateLocked`, naming the
|
|
6971
|
-
* holder, instead of racing the first.
|
|
6972
|
-
* - Versioned `read` and conditional `write`: a write names the version it was
|
|
6973
|
-
* based on, and raises `StateVersionConflict` when the stored state moved on
|
|
6974
|
-
* underneath it, so nothing is lost silently even without the lock.
|
|
6975
|
-
* - Per-resource records: `putResource` journals one resource at a time, so a
|
|
6976
|
-
* run that dies half way leaves behind the ids of everything it created.
|
|
6977
|
-
*
|
|
6978
|
-
* Built-in stores: `LocalStateStore`, `SSMStateStore`, `S3StateStore`. A
|
|
6979
|
-
* custom `StateProvider` is wrapped by `LegacyStateStore`, which keeps it
|
|
6980
|
-
* working but cannot lock.
|
|
6981
|
-
*/
|
|
6982
7080
|
var StateLocked = class extends require_errors.GkmError {
|
|
6983
7081
|
stage;
|
|
6984
7082
|
holder;
|
|
@@ -7026,7 +7124,7 @@ var StateSchemaTooNew = class extends require_errors.GkmError {
|
|
|
7026
7124
|
stage;
|
|
7027
7125
|
schemaVersion;
|
|
7028
7126
|
constructor(stage, schemaVersion) {
|
|
7029
|
-
super(`Deploy state for stage '${stage}' has schema version ${String(schemaVersion)}, newer than this @geekmidas/cli understands (
|
|
7127
|
+
super(`Deploy state for stage '${stage}' has schema version ${String(schemaVersion)}, newer than this @geekmidas/cli understands (3). Upgrade @geekmidas/cli to the version that wrote it.`);
|
|
7030
7128
|
this.stage = stage;
|
|
7031
7129
|
this.schemaVersion = schemaVersion;
|
|
7032
7130
|
this.name = "StateSchemaTooNew";
|
|
@@ -7061,6 +7159,22 @@ var UnknownStateProvider = class extends require_errors.GkmError {
|
|
|
7061
7159
|
this.name = "UnknownStateProvider";
|
|
7062
7160
|
}
|
|
7063
7161
|
};
|
|
7162
|
+
/**
|
|
7163
|
+
* A deploy, setup or rollback of a stage in CI, with the stage's state kept on
|
|
7164
|
+
* the runner — which is discarded when the job ends.
|
|
7165
|
+
*/
|
|
7166
|
+
var LocalStateInCi = class extends require_errors.GkmError {
|
|
7167
|
+
stage;
|
|
7168
|
+
operation;
|
|
7169
|
+
region;
|
|
7170
|
+
constructor(stage, operation, region) {
|
|
7171
|
+
super(`\`gkm ${operation}\` would keep stage '${stage}'s deploy state in .gkm/ on this CI runner, and the runner is discarded when the job ends: the next run would start without it — no releases to roll back to, no record of what was created. Keep the state in AWS — in gkm.config.ts:\n\n state: { provider: 'ssm', region: '${region}' },\n\nthen move the state you already have, from the machine that holds it:\n\n gkm state:push --stage ${stage}\n`);
|
|
7172
|
+
this.stage = stage;
|
|
7173
|
+
this.operation = operation;
|
|
7174
|
+
this.region = region;
|
|
7175
|
+
this.name = "LocalStateInCi";
|
|
7176
|
+
}
|
|
7177
|
+
};
|
|
7064
7178
|
/** A lock or write that could not get at the state backend in time. */
|
|
7065
7179
|
var StateStoreBusy = class extends require_errors.GkmError {
|
|
7066
7180
|
stage;
|
|
@@ -7089,6 +7203,10 @@ function decodeDocument(stage, body, location) {
|
|
|
7089
7203
|
schemaVersion: 2,
|
|
7090
7204
|
document: parsed
|
|
7091
7205
|
};
|
|
7206
|
+
if (schemaVersion === 3) return {
|
|
7207
|
+
schemaVersion: 3,
|
|
7208
|
+
document: parsed
|
|
7209
|
+
};
|
|
7092
7210
|
throw new StateSchemaTooNew(stage, schemaVersion);
|
|
7093
7211
|
}
|
|
7094
7212
|
function encodeDocument(document) {
|
|
@@ -7128,6 +7246,79 @@ function migrateV1(stage, state) {
|
|
|
7128
7246
|
updatedAt: now
|
|
7129
7247
|
};
|
|
7130
7248
|
}
|
|
7249
|
+
const isEmpty = (value) => !value || Object.keys(value).length === 0;
|
|
7250
|
+
/**
|
|
7251
|
+
* Whether a v2 state in the Dokploy shape was written by the compose target.
|
|
7252
|
+
*
|
|
7253
|
+
* Before v3 every target wrote the Dokploy shape, and compose filled none of
|
|
7254
|
+
* its Dokploy fields. So the rule is the shape's content, not the target the
|
|
7255
|
+
* workspace names now: a state whose every Dokploy-only field is empty — no
|
|
7256
|
+
* project or environment id, no application or service ids, no credentials,
|
|
7257
|
+
* generated secrets, backups or registry — holds nothing only Dokploy could
|
|
7258
|
+
* use, and reading it as compose loses nothing. One with any of them was
|
|
7259
|
+
* written by Dokploy and is kept exactly as it is.
|
|
7260
|
+
*
|
|
7261
|
+
* The configured target is not used: a document decodes the same wherever it
|
|
7262
|
+
* is read (`state:show`, `state:push`) without a workspace, a stage can be
|
|
7263
|
+
* moved between targets, and `--target` can override a run.
|
|
7264
|
+
*/
|
|
7265
|
+
function writtenByCompose(state) {
|
|
7266
|
+
return !state.projectId && !state.environmentId && isEmpty(state.applications) && !state.services?.postgresId && !state.services?.redisId && isEmpty(state.appCredentials) && isEmpty(state.generatedSecrets) && !state.backups && !state.registryId;
|
|
7267
|
+
}
|
|
7268
|
+
/**
|
|
7269
|
+
* A v2 state and its records as v3 keeps them. A compose-written state
|
|
7270
|
+
* becomes the compose shape: its `dnsRecords` become `dns-record` resources,
|
|
7271
|
+
* and `dnsVerified` and the empty Dokploy fields go — the DNS check is made
|
|
7272
|
+
* on every deploy. A Dokploy state is returned as it is.
|
|
7273
|
+
*/
|
|
7274
|
+
function upgradeV2State(state, resources) {
|
|
7275
|
+
if (!writtenByCompose(state)) return {
|
|
7276
|
+
state,
|
|
7277
|
+
resources
|
|
7278
|
+
};
|
|
7279
|
+
const compose = {
|
|
7280
|
+
provider: "compose",
|
|
7281
|
+
stage: state.stage,
|
|
7282
|
+
lastDeployedAt: state.lastDeployedAt,
|
|
7283
|
+
...state.identity ? { identity: state.identity } : {},
|
|
7284
|
+
...state.releases ? { releases: state.releases } : {}
|
|
7285
|
+
};
|
|
7286
|
+
const upgraded = { ...resources };
|
|
7287
|
+
for (const record of Object.values(state.dnsRecords ?? {})) {
|
|
7288
|
+
const resource = migratedDnsResource(record);
|
|
7289
|
+
upgraded[resource.key] = resource;
|
|
7290
|
+
}
|
|
7291
|
+
return {
|
|
7292
|
+
state: compose,
|
|
7293
|
+
resources: upgraded
|
|
7294
|
+
};
|
|
7295
|
+
}
|
|
7296
|
+
/** A v2 `dnsRecords` entry as the `dns-record` resource v3 keeps. */
|
|
7297
|
+
function migratedDnsResource(record) {
|
|
7298
|
+
return {
|
|
7299
|
+
...dnsRecordResource({
|
|
7300
|
+
domain: record.domain,
|
|
7301
|
+
name: record.name,
|
|
7302
|
+
type: record.type,
|
|
7303
|
+
value: record.value,
|
|
7304
|
+
ttl: record.ttl
|
|
7305
|
+
}),
|
|
7306
|
+
updatedAt: record.createdAt
|
|
7307
|
+
};
|
|
7308
|
+
}
|
|
7309
|
+
/** A v2 document as v3 — not written until the next write. */
|
|
7310
|
+
function migrateV2(document) {
|
|
7311
|
+
const { state, resources } = upgradeV2State(document.state, document.resources);
|
|
7312
|
+
return {
|
|
7313
|
+
schemaVersion: 3,
|
|
7314
|
+
stage: document.stage,
|
|
7315
|
+
serial: document.serial,
|
|
7316
|
+
state,
|
|
7317
|
+
resources,
|
|
7318
|
+
updatedAt: document.updatedAt,
|
|
7319
|
+
history: []
|
|
7320
|
+
};
|
|
7321
|
+
}
|
|
7131
7322
|
function newLockHolder(options) {
|
|
7132
7323
|
let owner = "unknown";
|
|
7133
7324
|
try {
|
|
@@ -7146,14 +7337,33 @@ function contentVersion(body) {
|
|
|
7146
7337
|
return (0, node_crypto.createHash)("sha256").update(body).digest("hex").slice(0, 16);
|
|
7147
7338
|
}
|
|
7148
7339
|
/**
|
|
7340
|
+
* `history` with this write at its head. A run makes many writes — one per
|
|
7341
|
+
* resource it journals — so a run is one entry: a write by the run that
|
|
7342
|
+
* wrote the newest entry (the same lock) replaces it, and any other is
|
|
7343
|
+
* added. Without a lock, each write is its own entry.
|
|
7344
|
+
*/
|
|
7345
|
+
function appendHistory(history, entry, sameRun) {
|
|
7346
|
+
return [entry, ...sameRun ? history.slice(1) : history].slice(0, 20);
|
|
7347
|
+
}
|
|
7348
|
+
/**
|
|
7149
7349
|
* A store over a backend that can read and conditionally write one blob per
|
|
7150
|
-
* stage, and create a lock object only if it does not exist. Migration
|
|
7151
|
-
* resource records are the same for every such backend, so they
|
|
7350
|
+
* stage, and create a lock object only if it does not exist. Migration,
|
|
7351
|
+
* resource records and history are the same for every such backend, so they
|
|
7352
|
+
* live here.
|
|
7152
7353
|
*/
|
|
7153
7354
|
var DocumentStateStore = class {
|
|
7355
|
+
/** The lock this store holds for each stage — what its writes are for. */
|
|
7356
|
+
held = /* @__PURE__ */ new Map();
|
|
7357
|
+
/** Per stage, the lock whose run wrote the newest history entry. */
|
|
7358
|
+
logged = /* @__PURE__ */ new Map();
|
|
7359
|
+
/** Who this store writes as. */
|
|
7360
|
+
actor() {
|
|
7361
|
+
return currentActor();
|
|
7362
|
+
}
|
|
7154
7363
|
async lock(stage, options) {
|
|
7155
7364
|
const holder = newLockHolder(options);
|
|
7156
7365
|
await this.createLock(stage, holder);
|
|
7366
|
+
this.held.set(stage, holder);
|
|
7157
7367
|
let released = false;
|
|
7158
7368
|
return {
|
|
7159
7369
|
stage,
|
|
@@ -7161,6 +7371,7 @@ var DocumentStateStore = class {
|
|
|
7161
7371
|
release: async () => {
|
|
7162
7372
|
if (released) return;
|
|
7163
7373
|
released = true;
|
|
7374
|
+
if (this.held.get(stage)?.id === holder.id) this.held.delete(stage);
|
|
7164
7375
|
await this.removeLock(stage, holder);
|
|
7165
7376
|
}
|
|
7166
7377
|
};
|
|
@@ -7176,19 +7387,21 @@ var DocumentStateStore = class {
|
|
|
7176
7387
|
return {
|
|
7177
7388
|
state: current.document.state,
|
|
7178
7389
|
resources: current.document.resources,
|
|
7390
|
+
history: current.document.history,
|
|
7179
7391
|
version: current.version
|
|
7180
7392
|
};
|
|
7181
7393
|
}
|
|
7182
7394
|
async write(stage, state, options) {
|
|
7183
7395
|
if (options.expectedVersion === null) {
|
|
7184
|
-
const document = {
|
|
7185
|
-
schemaVersion:
|
|
7396
|
+
const document = this.stamp(stage, {
|
|
7397
|
+
schemaVersion: 3,
|
|
7186
7398
|
stage,
|
|
7187
7399
|
serial: 1,
|
|
7188
7400
|
state,
|
|
7189
7401
|
resources: {},
|
|
7190
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7191
|
-
|
|
7402
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7403
|
+
history: []
|
|
7404
|
+
});
|
|
7192
7405
|
return this.writeRaw(stage, encodeDocument(document), null);
|
|
7193
7406
|
}
|
|
7194
7407
|
return this.mutate(stage, options.expectedVersion, (document) => ({
|
|
@@ -7203,7 +7416,8 @@ var DocumentStateStore = class {
|
|
|
7203
7416
|
...document.resources,
|
|
7204
7417
|
[record.key]: {
|
|
7205
7418
|
...record,
|
|
7206
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7419
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7420
|
+
updatedBy: this.actor()
|
|
7207
7421
|
}
|
|
7208
7422
|
}
|
|
7209
7423
|
}));
|
|
@@ -7217,6 +7431,25 @@ var DocumentStateStore = class {
|
|
|
7217
7431
|
};
|
|
7218
7432
|
});
|
|
7219
7433
|
}
|
|
7434
|
+
/** `document` as this write leaves it: who wrote it, in its history. */
|
|
7435
|
+
stamp(stage, document) {
|
|
7436
|
+
const by = this.actor();
|
|
7437
|
+
const holder = this.held.get(stage);
|
|
7438
|
+
const operation = holder?.operation ?? "write";
|
|
7439
|
+
const history = document.history ?? [];
|
|
7440
|
+
const sameRun = holder !== void 0 && this.logged.get(stage) === holder.id && history[0]?.operation === operation;
|
|
7441
|
+
if (holder) this.logged.set(stage, holder.id);
|
|
7442
|
+
return {
|
|
7443
|
+
...document,
|
|
7444
|
+
updatedBy: by,
|
|
7445
|
+
history: appendHistory(history, {
|
|
7446
|
+
serial: document.serial,
|
|
7447
|
+
at: document.updatedAt,
|
|
7448
|
+
by,
|
|
7449
|
+
operation
|
|
7450
|
+
}, sameRun)
|
|
7451
|
+
};
|
|
7452
|
+
}
|
|
7220
7453
|
async mutate(stage, expectedVersion, change) {
|
|
7221
7454
|
const current = await this.readDocument(stage);
|
|
7222
7455
|
if (!current) {
|
|
@@ -7225,25 +7458,31 @@ var DocumentStateStore = class {
|
|
|
7225
7458
|
}
|
|
7226
7459
|
if (expectedVersion !== void 0 && current.version !== expectedVersion) throw new StateVersionConflict(stage, expectedVersion, current.version);
|
|
7227
7460
|
const next = change(current.document);
|
|
7461
|
+
next.schemaVersion = 3;
|
|
7228
7462
|
next.serial = current.document.serial + 1;
|
|
7229
7463
|
next.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7230
|
-
return this.writeRaw(stage, encodeDocument(next), current.version);
|
|
7464
|
+
return this.writeRaw(stage, encodeDocument(this.stamp(stage, next)), current.version);
|
|
7231
7465
|
}
|
|
7232
7466
|
/**
|
|
7233
|
-
* Reads the stage's document
|
|
7234
|
-
*
|
|
7235
|
-
*
|
|
7467
|
+
* Reads the stage's document as v3. A v1 document is migrated in place on
|
|
7468
|
+
* the way — itself a conditional write: if another run migrated (or wrote)
|
|
7469
|
+
* first, its result is read instead. A v2 document is upgraded in memory
|
|
7470
|
+
* and written as v3 by the next write.
|
|
7236
7471
|
*/
|
|
7237
7472
|
async readDocument(stage, attempt = 0) {
|
|
7238
7473
|
const raw = await this.readRaw(stage);
|
|
7239
7474
|
if (!raw) return null;
|
|
7240
7475
|
const decoded = decodeDocument(stage, raw.body, this.location(stage));
|
|
7241
|
-
if (decoded.schemaVersion ===
|
|
7476
|
+
if (decoded.schemaVersion === 3) return {
|
|
7242
7477
|
document: decoded.document,
|
|
7243
7478
|
version: raw.version
|
|
7244
7479
|
};
|
|
7480
|
+
if (decoded.schemaVersion === 2) return {
|
|
7481
|
+
document: migrateV2(decoded.document),
|
|
7482
|
+
version: raw.version
|
|
7483
|
+
};
|
|
7245
7484
|
await this.writeV1Backup(stage, raw.body);
|
|
7246
|
-
const document = migrateV1(stage, decoded.state);
|
|
7485
|
+
const document = this.stamp(stage, migrateV2(migrateV1(stage, decoded.state)));
|
|
7247
7486
|
try {
|
|
7248
7487
|
return {
|
|
7249
7488
|
document,
|
|
@@ -7255,6 +7494,22 @@ var DocumentStateStore = class {
|
|
|
7255
7494
|
}
|
|
7256
7495
|
}
|
|
7257
7496
|
};
|
|
7497
|
+
/** Whether `config` keeps state on this machine — `local`, or none given. */
|
|
7498
|
+
function isLocalState(config) {
|
|
7499
|
+
return !config || config.provider === "local";
|
|
7500
|
+
}
|
|
7501
|
+
/**
|
|
7502
|
+
* Refuses, with `LocalStateInCi`, a run that would write a deployed stage's
|
|
7503
|
+
* state to a CI runner's disk — the local stage, which runs on the runner
|
|
7504
|
+
* itself, is exempt. Local use is untouched. The region the message
|
|
7505
|
+
* suggests is the secrets store's, when the workspace keeps them in AWS.
|
|
7506
|
+
*/
|
|
7507
|
+
function assertStateOutlivesRun(workspace, stage, operation, env = process.env) {
|
|
7508
|
+
if (stage === workspace.stages?.local) return;
|
|
7509
|
+
if (!isCi(env) || !isLocalState(workspace.state)) return;
|
|
7510
|
+
const store = workspace.secrets?.store;
|
|
7511
|
+
throw new LocalStateInCi(stage, operation, typeof store === "object" && store && typeof store.region === "string" ? store.region : "<region>");
|
|
7512
|
+
}
|
|
7258
7513
|
function isStateStore(value) {
|
|
7259
7514
|
return typeof value === "object" && value !== null && typeof value.lock === "function" && typeof value.read === "function" && typeof value.write === "function" && typeof value.putResource === "function";
|
|
7260
7515
|
}
|
|
@@ -7271,17 +7526,17 @@ function isStateStore(value) {
|
|
|
7271
7526
|
async function createStateStore(options) {
|
|
7272
7527
|
const { config, workspaceRoot, workspaceName } = options;
|
|
7273
7528
|
if (!config || config.provider === "local") {
|
|
7274
|
-
const { LocalStateStore } = await Promise.resolve().then(() => require("./LocalStateStore-
|
|
7529
|
+
const { LocalStateStore } = await Promise.resolve().then(() => require("./LocalStateStore-oX_zxj9V.cjs")).then((n) => n.LocalStateStore_exports);
|
|
7275
7530
|
return new LocalStateStore(workspaceRoot);
|
|
7276
7531
|
}
|
|
7277
7532
|
if (isStateStore(config.provider)) return config.provider;
|
|
7278
7533
|
if (isStateProvider(config.provider)) {
|
|
7279
|
-
const { LegacyStateStore } = await Promise.resolve().then(() => require("./LegacyStateStore-
|
|
7534
|
+
const { LegacyStateStore } = await Promise.resolve().then(() => require("./LegacyStateStore-BlYXQQSE.cjs"));
|
|
7280
7535
|
return new LegacyStateStore(config.provider, { warn: options.warn });
|
|
7281
7536
|
}
|
|
7282
7537
|
if (config.provider === "ssm") {
|
|
7283
7538
|
if (!workspaceName) throw new StateStoreNeedsWorkspaceName("ssm");
|
|
7284
|
-
const { SSMStateStore } = await Promise.resolve().then(() => require("./SSMStateStore-
|
|
7539
|
+
const { SSMStateStore } = await Promise.resolve().then(() => require("./SSMStateStore-CaCtrzFL.cjs"));
|
|
7285
7540
|
const ssm = config;
|
|
7286
7541
|
return SSMStateStore.create({
|
|
7287
7542
|
workspaceName,
|
|
@@ -7291,7 +7546,7 @@ async function createStateStore(options) {
|
|
|
7291
7546
|
}
|
|
7292
7547
|
if (config.provider === "s3") {
|
|
7293
7548
|
if (!workspaceName) throw new StateStoreNeedsWorkspaceName("s3");
|
|
7294
|
-
const { S3StateStore } = await Promise.resolve().then(() => require("./S3StateStore-
|
|
7549
|
+
const { S3StateStore } = await Promise.resolve().then(() => require("./S3StateStore-DeI7jtvi.cjs"));
|
|
7295
7550
|
const s3 = config;
|
|
7296
7551
|
return S3StateStore.create({
|
|
7297
7552
|
workspaceName,
|
|
@@ -7339,7 +7594,7 @@ async function createDnsProvider(options) {
|
|
|
7339
7594
|
});
|
|
7340
7595
|
}
|
|
7341
7596
|
if (provider === "godaddy") {
|
|
7342
|
-
const { GoDaddyProvider } = await Promise.resolve().then(() => require("./GoDaddyProvider-
|
|
7597
|
+
const { GoDaddyProvider } = await Promise.resolve().then(() => require("./GoDaddyProvider-BZb-V14e.cjs"));
|
|
7343
7598
|
return new GoDaddyProvider(options.godaddy ?? {});
|
|
7344
7599
|
}
|
|
7345
7600
|
if (provider === "cloudflare") throw new DnsProviderNotImplemented("cloudflare");
|
|
@@ -7383,10 +7638,16 @@ var DnsProviderUnknown = class extends require_errors.GkmError {
|
|
|
7383
7638
|
//#endregion
|
|
7384
7639
|
//#region src/deploy/state.ts
|
|
7385
7640
|
/**
|
|
7386
|
-
*
|
|
7641
|
+
* A stage's deploy state.
|
|
7642
|
+
*
|
|
7643
|
+
* Every target records the same core — when the stage was last deployed, by
|
|
7644
|
+
* which identity, and each app's releases — and a target that keeps ids of
|
|
7645
|
+
* its own adds them in a shape of its own, told apart by `provider`:
|
|
7387
7646
|
*
|
|
7388
|
-
*
|
|
7389
|
-
*
|
|
7647
|
+
* - `dokploy`: the project, applications, services and credentials Dokploy
|
|
7648
|
+
* gave the stage, so a later deploy updates them rather than making more.
|
|
7649
|
+
* - `compose`: nothing beyond the core. A compose stage is one stack on one
|
|
7650
|
+
* server; what it created elsewhere (DNS records) is a resource record.
|
|
7390
7651
|
*/
|
|
7391
7652
|
/**
|
|
7392
7653
|
* Create a new empty state for a stage
|
|
@@ -7402,6 +7663,31 @@ function createEmptyState(stage, projectId, environmentId) {
|
|
|
7402
7663
|
lastDeployedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7403
7664
|
};
|
|
7404
7665
|
}
|
|
7666
|
+
/** A new compose stage's state. */
|
|
7667
|
+
function createComposeState(stage) {
|
|
7668
|
+
return {
|
|
7669
|
+
provider: "compose",
|
|
7670
|
+
stage,
|
|
7671
|
+
lastDeployedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7672
|
+
};
|
|
7673
|
+
}
|
|
7674
|
+
/**
|
|
7675
|
+
* `state` as the Dokploy target keeps it. A stage whose state another target
|
|
7676
|
+
* wrote — one moved from compose to Dokploy — keeps its core (releases,
|
|
7677
|
+
* identity) and starts with no Dokploy ids, as a first deploy would.
|
|
7678
|
+
*/
|
|
7679
|
+
function asDokployState(state) {
|
|
7680
|
+
if (state.provider === "dokploy") return state;
|
|
7681
|
+
const { provider: _provider, ...core } = state;
|
|
7682
|
+
return {
|
|
7683
|
+
...core,
|
|
7684
|
+
provider: "dokploy",
|
|
7685
|
+
projectId: "",
|
|
7686
|
+
environmentId: "",
|
|
7687
|
+
applications: {},
|
|
7688
|
+
services: {}
|
|
7689
|
+
};
|
|
7690
|
+
}
|
|
7405
7691
|
/**
|
|
7406
7692
|
* Set application ID in state (mutates state)
|
|
7407
7693
|
*/
|
|
@@ -7421,12 +7707,13 @@ function restorable(history, index, current) {
|
|
|
7421
7707
|
* `current`, and what was current becomes `previous`. Releasing what already
|
|
7422
7708
|
* runs — a redeploy of the same digest — changes nothing.
|
|
7423
7709
|
*/
|
|
7424
|
-
function recordRelease(state, appName, image, releasedAt = /* @__PURE__ */ new Date()) {
|
|
7710
|
+
function recordRelease(state, appName, image, by, releasedAt = /* @__PURE__ */ new Date()) {
|
|
7425
7711
|
const releases = state.releases?.[appName];
|
|
7426
7712
|
if (releases && sameImage(releases.current, image)) return;
|
|
7427
7713
|
const entry = {
|
|
7428
7714
|
...image,
|
|
7429
|
-
releasedAt: releasedAt.toISOString()
|
|
7715
|
+
releasedAt: releasedAt.toISOString(),
|
|
7716
|
+
releasedBy: by
|
|
7430
7717
|
};
|
|
7431
7718
|
const history = [entry, ...releases?.history ?? []].slice(0, 10);
|
|
7432
7719
|
const previous = releases?.current;
|
|
@@ -7874,6 +8161,422 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
|
|
|
7874
8161
|
return results;
|
|
7875
8162
|
}
|
|
7876
8163
|
//#endregion
|
|
8164
|
+
//#region src/compose/dns.ts
|
|
8165
|
+
/**
|
|
8166
|
+
* A compose stage's DNS: the records its public hosts need, and the check that
|
|
8167
|
+
* they resolve to its server before a certificate is asked for.
|
|
8168
|
+
*
|
|
8169
|
+
* - **The server** (`serverAddress`): the stage's own secrets hold its public
|
|
8170
|
+
* addresses — `GKM_SERVER_IPV4`, and `GKM_SERVER_IPV6` where it has one.
|
|
8171
|
+
* Reserved for gkm: never handed to an app.
|
|
8172
|
+
* - **The plan** (`planStackDns`, pure): every public host the stack serves —
|
|
8173
|
+
* its apex, each app, each file server, the public log UI — pointed at the
|
|
8174
|
+
* server. An A record per host (and an AAAA with an IPv6 address), or, where
|
|
8175
|
+
* the domain's `dns` entry says `records: { mode: 'cname', target }`, one A
|
|
8176
|
+
* record for the target and a CNAME to it for every other host but the
|
|
8177
|
+
* apex, which DNS forbids a CNAME at.
|
|
8178
|
+
* - **Applying it** (`applyStackDns`): through the domain's provider in `dns`,
|
|
8179
|
+
* a record set at a time. A record with the right value is left alone; one
|
|
8180
|
+
* with another value is replaced and the change printed. A `manual` domain
|
|
8181
|
+
* is printed and nothing else. A dry run reads, prints and writes nothing.
|
|
8182
|
+
* - **The check** (`checkStackDns`): each host resolved with the system
|
|
8183
|
+
* resolver. One that is not the server stops the deploy with
|
|
8184
|
+
* {@link HostNotPointingAtServer}, before Caddy or Traefik ask Let's Encrypt
|
|
8185
|
+
* for a certificate it cannot get — and use up the rate limit trying.
|
|
8186
|
+
*/
|
|
8187
|
+
/** The line that says how to set the server's address. */
|
|
8188
|
+
function serverAddressHint(stage) {
|
|
8189
|
+
return `gkm secrets:set ${require_workspace.SERVER_IPV4_KEY} '<ip>' --stage ${stage}`;
|
|
8190
|
+
}
|
|
8191
|
+
/** A server address in the stage's secrets that is not an address. */
|
|
8192
|
+
var ServerAddressInvalid = class extends require_errors.GkmError {
|
|
8193
|
+
stage;
|
|
8194
|
+
key;
|
|
8195
|
+
value;
|
|
8196
|
+
constructor(stage, key, value) {
|
|
8197
|
+
const ipv4 = key === require_workspace.SERVER_IPV4_KEY;
|
|
8198
|
+
super(`${key} in the '${stage}' stage's secrets is ${JSON.stringify(value)}, which is not an ${ipv4 ? "IPv4 address (like 203.0.113.10)" : "IPv6 address (like 2001:db8::10)"}. Set the server's public address: gkm secrets:set ${key} '<ip>' --stage ${stage}.`);
|
|
8199
|
+
this.stage = stage;
|
|
8200
|
+
this.key = key;
|
|
8201
|
+
this.value = value;
|
|
8202
|
+
this.name = "ServerAddressInvalid";
|
|
8203
|
+
}
|
|
8204
|
+
};
|
|
8205
|
+
/**
|
|
8206
|
+
* A compose stage that serves real domains with no server address: its hosts
|
|
8207
|
+
* cannot be pointed or checked, and a certificate would be asked for blind.
|
|
8208
|
+
*/
|
|
8209
|
+
var ServerAddressMissing = class extends require_errors.GkmError {
|
|
8210
|
+
stage;
|
|
8211
|
+
domain;
|
|
8212
|
+
constructor(stage, domain) {
|
|
8213
|
+
super(`The '${stage}' stage serves ${domain} and its secrets hold no ${require_workspace.SERVER_IPV4_KEY} — the public address of the server its stack runs on, which its hosts' DNS records point at and every deploy checks before asking for certificates. Set it: ${serverAddressHint(stage)} (and ${require_workspace.SERVER_IPV6_KEY} for an IPv6 address).`);
|
|
8214
|
+
this.stage = stage;
|
|
8215
|
+
this.domain = domain;
|
|
8216
|
+
this.name = "ServerAddressMissing";
|
|
8217
|
+
}
|
|
8218
|
+
};
|
|
8219
|
+
/**
|
|
8220
|
+
* The server's address from the stage's secrets, checked — `undefined` when
|
|
8221
|
+
* `GKM_SERVER_IPV4` is not set.
|
|
8222
|
+
*
|
|
8223
|
+
* @throws {ServerAddressInvalid} for a value that is not an address
|
|
8224
|
+
*/
|
|
8225
|
+
function serverAddress(stage, custom) {
|
|
8226
|
+
const ipv4 = custom?.[require_workspace.SERVER_IPV4_KEY]?.trim();
|
|
8227
|
+
const ipv6 = custom?.[require_workspace.SERVER_IPV6_KEY]?.trim();
|
|
8228
|
+
if (ipv6 && !(0, node_net.isIPv6)(ipv6)) throw new ServerAddressInvalid(stage, require_workspace.SERVER_IPV6_KEY, ipv6);
|
|
8229
|
+
if (!ipv4) return void 0;
|
|
8230
|
+
if (!(0, node_net.isIPv4)(ipv4)) throw new ServerAddressInvalid(stage, require_workspace.SERVER_IPV4_KEY, ipv4);
|
|
8231
|
+
return {
|
|
8232
|
+
ipv4,
|
|
8233
|
+
...ipv6 ? { ipv6 } : {}
|
|
8234
|
+
};
|
|
8235
|
+
}
|
|
8236
|
+
/**
|
|
8237
|
+
* A name that resolves to this machine by definition — `localhost` and every
|
|
8238
|
+
* `*.localhost` — and is in nobody's DNS.
|
|
8239
|
+
*/
|
|
8240
|
+
function isLocalHost(host) {
|
|
8241
|
+
const name = host.toLowerCase().replace(/\.$/, "");
|
|
8242
|
+
return name === "localhost" || name.endsWith(".localhost");
|
|
8243
|
+
}
|
|
8244
|
+
/**
|
|
8245
|
+
* The server's address, required where the stage serves real domains — not
|
|
8246
|
+
* `*.localhost` ones, which point at this machine already.
|
|
8247
|
+
*
|
|
8248
|
+
* @throws {ServerAddressMissing} when the stage has a domain and no address
|
|
8249
|
+
* @throws {ServerAddressInvalid} for a value that is not an address
|
|
8250
|
+
*/
|
|
8251
|
+
function requiredServerAddress(stage, domain, custom) {
|
|
8252
|
+
const server = serverAddress(stage, custom);
|
|
8253
|
+
if (!server && domain && !isLocalHost(domain)) throw new ServerAddressMissing(stage, domain);
|
|
8254
|
+
return server;
|
|
8255
|
+
}
|
|
8256
|
+
const MANAGED = [
|
|
8257
|
+
"A",
|
|
8258
|
+
"AAAA",
|
|
8259
|
+
"CNAME"
|
|
8260
|
+
];
|
|
8261
|
+
/** Every public host the stack serves, once each, sorted. */
|
|
8262
|
+
function stackHosts(stack) {
|
|
8263
|
+
return [...new Set(stack.routes.map((route) => route.host))].sort();
|
|
8264
|
+
}
|
|
8265
|
+
/** The TTL a domain's records are written with. */
|
|
8266
|
+
function recordTtl(config) {
|
|
8267
|
+
const ttl = "ttl" in config ? config.ttl : void 0;
|
|
8268
|
+
if (ttl) return ttl;
|
|
8269
|
+
return config.provider === "godaddy" ? 600 : 300;
|
|
8270
|
+
}
|
|
8271
|
+
function providerName(config) {
|
|
8272
|
+
return typeof config.provider === "string" ? config.provider : "custom";
|
|
8273
|
+
}
|
|
8274
|
+
/** The records a stage's hosts need — pure. */
|
|
8275
|
+
function planStackDns(input) {
|
|
8276
|
+
const { stage, server } = input;
|
|
8277
|
+
const dns = input.dns ? normalizeDnsConfig(input.dns) : {};
|
|
8278
|
+
const records = /* @__PURE__ */ new Map();
|
|
8279
|
+
const uncovered = [];
|
|
8280
|
+
const add = (host, domain, type, value) => {
|
|
8281
|
+
const name = extractSubdomain(host, domain);
|
|
8282
|
+
records.set(`${domain} ${name} ${type}`, {
|
|
8283
|
+
host,
|
|
8284
|
+
domain,
|
|
8285
|
+
name,
|
|
8286
|
+
type,
|
|
8287
|
+
value,
|
|
8288
|
+
ttl: recordTtl(dns[domain])
|
|
8289
|
+
});
|
|
8290
|
+
};
|
|
8291
|
+
const pointAt = (host, domain) => {
|
|
8292
|
+
add(host, domain, "A", server.ipv4);
|
|
8293
|
+
if (server.ipv6) add(host, domain, "AAAA", server.ipv6);
|
|
8294
|
+
};
|
|
8295
|
+
for (const raw of input.hosts) {
|
|
8296
|
+
const host = raw.toLowerCase();
|
|
8297
|
+
const domain = findRootDomain(host, dns);
|
|
8298
|
+
if (!domain) {
|
|
8299
|
+
uncovered.push(host);
|
|
8300
|
+
continue;
|
|
8301
|
+
}
|
|
8302
|
+
const target = require_workspace.cnameTarget(dns[domain].records, stage);
|
|
8303
|
+
if (target) pointAt(target, domain);
|
|
8304
|
+
if (target && host !== domain && host !== target) add(host, domain, "CNAME", target);
|
|
8305
|
+
else pointAt(host, domain);
|
|
8306
|
+
}
|
|
8307
|
+
const domains = /* @__PURE__ */ new Map();
|
|
8308
|
+
for (const record of [...records.values()].sort((a, b) => a.domain.localeCompare(b.domain) || a.name.localeCompare(b.name) || a.type.localeCompare(b.type))) {
|
|
8309
|
+
const config = dns[record.domain];
|
|
8310
|
+
const plan = domains.get(record.domain) ?? {
|
|
8311
|
+
domain: record.domain,
|
|
8312
|
+
provider: providerName(config),
|
|
8313
|
+
config,
|
|
8314
|
+
records: []
|
|
8315
|
+
};
|
|
8316
|
+
plan.records.push(record);
|
|
8317
|
+
domains.set(record.domain, plan);
|
|
8318
|
+
}
|
|
8319
|
+
return {
|
|
8320
|
+
stage,
|
|
8321
|
+
server,
|
|
8322
|
+
domains: [...domains.values()],
|
|
8323
|
+
uncovered: uncovered.sort()
|
|
8324
|
+
};
|
|
8325
|
+
}
|
|
8326
|
+
/** `api.example.com A 203.0.113.10 (TTL 600)` */
|
|
8327
|
+
function describe(record) {
|
|
8328
|
+
return `${record.host.padEnd(32)} ${record.type.padEnd(5)} ${record.value} (TTL ${record.ttl})`;
|
|
8329
|
+
}
|
|
8330
|
+
function printManual(plan, log, why) {
|
|
8331
|
+
log(` ${plan.domain}: ${why} — create these records at its DNS host:`);
|
|
8332
|
+
for (const record of plan.records) log(` ${describe(record)}`);
|
|
8333
|
+
return plan.records.map((r) => ({
|
|
8334
|
+
domain: r.domain,
|
|
8335
|
+
name: r.name,
|
|
8336
|
+
type: r.type,
|
|
8337
|
+
action: "manual",
|
|
8338
|
+
value: r.value,
|
|
8339
|
+
ttl: r.ttl
|
|
8340
|
+
}));
|
|
8341
|
+
}
|
|
8342
|
+
/** The existing records of every planned name, for the types gkm manages. */
|
|
8343
|
+
async function existingRecords(provider, plan) {
|
|
8344
|
+
const names = [...new Set(plan.records.map((r) => r.name))];
|
|
8345
|
+
const wanted = names.flatMap((name) => MANAGED.map((type) => ({
|
|
8346
|
+
name,
|
|
8347
|
+
type
|
|
8348
|
+
})));
|
|
8349
|
+
if (provider.readRecords) return provider.readRecords(plan.domain, wanted);
|
|
8350
|
+
return (await provider.getRecords(plan.domain)).filter((r) => names.includes(r.name) && MANAGED.includes(r.type));
|
|
8351
|
+
}
|
|
8352
|
+
const same = (a, b) => a.trim().replace(/\.$/, "").toLowerCase() === b.trim().replace(/\.$/, "").toLowerCase();
|
|
8353
|
+
/**
|
|
8354
|
+
* What each domain's records need, compared with what is there: creates,
|
|
8355
|
+
* updates, and the deletes a change of mode needs — a name moving from an A
|
|
8356
|
+
* record to a CNAME, or back, cannot hold both. Nothing else is deleted.
|
|
8357
|
+
*/
|
|
8358
|
+
function diffDomainDns(plan, existing) {
|
|
8359
|
+
const changes = [];
|
|
8360
|
+
const find = (name, type) => existing.find((r) => r.name === name && r.type === type);
|
|
8361
|
+
const planned = /* @__PURE__ */ new Map();
|
|
8362
|
+
for (const record of plan.records) {
|
|
8363
|
+
const types = planned.get(record.name) ?? /* @__PURE__ */ new Set();
|
|
8364
|
+
types.add(record.type);
|
|
8365
|
+
planned.set(record.name, types);
|
|
8366
|
+
}
|
|
8367
|
+
for (const [name, types] of planned) {
|
|
8368
|
+
const conflicting = types.has("CNAME") ? ["A", "AAAA"] : ["CNAME"];
|
|
8369
|
+
for (const type of conflicting) {
|
|
8370
|
+
const found = find(name, type);
|
|
8371
|
+
if (!found || found.values.length === 0) continue;
|
|
8372
|
+
changes.push({
|
|
8373
|
+
domain: plan.domain,
|
|
8374
|
+
name,
|
|
8375
|
+
type,
|
|
8376
|
+
action: "delete",
|
|
8377
|
+
previous: found.values.join(", ")
|
|
8378
|
+
});
|
|
8379
|
+
}
|
|
8380
|
+
}
|
|
8381
|
+
for (const record of plan.records) {
|
|
8382
|
+
const found = find(record.name, record.type);
|
|
8383
|
+
const base = {
|
|
8384
|
+
domain: plan.domain,
|
|
8385
|
+
name: record.name,
|
|
8386
|
+
type: record.type,
|
|
8387
|
+
value: record.value,
|
|
8388
|
+
ttl: record.ttl
|
|
8389
|
+
};
|
|
8390
|
+
if (!found || found.values.length === 0) changes.push({
|
|
8391
|
+
...base,
|
|
8392
|
+
action: "create"
|
|
8393
|
+
});
|
|
8394
|
+
else if (found.values.length === 1 && same(found.values[0], record.value)) changes.push({
|
|
8395
|
+
...base,
|
|
8396
|
+
action: "unchanged"
|
|
8397
|
+
});
|
|
8398
|
+
else changes.push({
|
|
8399
|
+
...base,
|
|
8400
|
+
action: "update",
|
|
8401
|
+
previous: found.values.join(", ")
|
|
8402
|
+
});
|
|
8403
|
+
}
|
|
8404
|
+
return changes;
|
|
8405
|
+
}
|
|
8406
|
+
/** A host's full name from a domain and a relative name. */
|
|
8407
|
+
function fullName(domain, name) {
|
|
8408
|
+
return name === "@" ? domain : `${name}.${domain}`;
|
|
8409
|
+
}
|
|
8410
|
+
function printChange(change, dryRun, log) {
|
|
8411
|
+
const host = fullName(change.domain, change.name).padEnd(32);
|
|
8412
|
+
const type = change.type.padEnd(5);
|
|
8413
|
+
const would = dryRun ? "would " : "";
|
|
8414
|
+
switch (change.action) {
|
|
8415
|
+
case "unchanged":
|
|
8416
|
+
log(` ✓ ${host} ${type} ${change.value} (TTL ${change.ttl}) — up to date`);
|
|
8417
|
+
break;
|
|
8418
|
+
case "create":
|
|
8419
|
+
log(` + ${host} ${type} ${change.value} (TTL ${change.ttl}) — ${would}create`);
|
|
8420
|
+
break;
|
|
8421
|
+
case "update":
|
|
8422
|
+
log(` ~ ${host} ${type} ${change.previous} → ${change.value} (TTL ${change.ttl}) — ${would}update`);
|
|
8423
|
+
break;
|
|
8424
|
+
case "write":
|
|
8425
|
+
log(dryRun ? ` ? ${host} ${type} ${change.value} (TTL ${change.ttl}) — would write; current value unknown (key cannot read DNS)` : ` ! ${host} ${type} ${change.value} (TTL ${change.ttl}) — written (not diffed)`);
|
|
8426
|
+
break;
|
|
8427
|
+
case "delete": log(` - ${host} ${type} ${change.previous} — ${would}delete (a name cannot hold a CNAME and an A record)`);
|
|
8428
|
+
}
|
|
8429
|
+
}
|
|
8430
|
+
/**
|
|
8431
|
+
* Each domain's records, through its provider. Returns every change, the
|
|
8432
|
+
* unchanged included; a dry run makes none of them.
|
|
8433
|
+
*/
|
|
8434
|
+
async function applyStackDns(plan, options = {}) {
|
|
8435
|
+
const dryRun = options.dryRun === true;
|
|
8436
|
+
const log = options.log ?? ((line) => console.log(line));
|
|
8437
|
+
const providerFor = options.providerFor ?? ((config) => createDnsProvider({
|
|
8438
|
+
config,
|
|
8439
|
+
...options.credentials ? { godaddy: options.credentials } : {}
|
|
8440
|
+
}));
|
|
8441
|
+
const changes = [];
|
|
8442
|
+
for (const host of plan.uncovered) log(` ⚠ ${host} is under no domain in dns — point it at ${plan.server.ipv4} yourself`);
|
|
8443
|
+
for (const domain of plan.domains) {
|
|
8444
|
+
if (domain.provider === "manual") {
|
|
8445
|
+
changes.push(...printManual(domain, log, "manual"));
|
|
8446
|
+
continue;
|
|
8447
|
+
}
|
|
8448
|
+
const provider = await providerFor(domain.config);
|
|
8449
|
+
if (!provider) {
|
|
8450
|
+
changes.push(...printManual(domain, log, "manual"));
|
|
8451
|
+
continue;
|
|
8452
|
+
}
|
|
8453
|
+
log(` ${domain.domain} (${provider.name})${dryRun ? " — dry run" : ""}`);
|
|
8454
|
+
let existing;
|
|
8455
|
+
let diff;
|
|
8456
|
+
try {
|
|
8457
|
+
existing = await existingRecords(provider, domain);
|
|
8458
|
+
diff = diffDomainDns(domain, existing);
|
|
8459
|
+
} catch (error) {
|
|
8460
|
+
if (!(error instanceof DnsRecordsUnreadable)) throw error;
|
|
8461
|
+
log(` ℹ The ${provider.name} key cannot read ${domain.domain}'s DNS records, so changes cannot be diffed: every record is written (idempotent).`);
|
|
8462
|
+
existing = [];
|
|
8463
|
+
diff = domain.records.map((r) => ({
|
|
8464
|
+
domain: r.domain,
|
|
8465
|
+
name: r.name,
|
|
8466
|
+
type: r.type,
|
|
8467
|
+
action: "write",
|
|
8468
|
+
value: r.value,
|
|
8469
|
+
ttl: r.ttl
|
|
8470
|
+
}));
|
|
8471
|
+
}
|
|
8472
|
+
for (const change of diff) printChange(change, dryRun, log);
|
|
8473
|
+
if (!plan.server.ipv6) for (const name of new Set(domain.records.map((r) => r.name))) {
|
|
8474
|
+
const aaaa = existing.find((r) => r.name === name && r.type === "AAAA");
|
|
8475
|
+
const planned = domain.records.find((r) => r.name === name && r.type === "A");
|
|
8476
|
+
if (aaaa && planned && aaaa.values.length > 0) log(` ⚠ ${fullName(domain.domain, name)} also has AAAA ${aaaa.values.join(", ")}: set ${require_workspace.SERVER_IPV6_KEY} in the '${plan.stage}' stage's secrets to the server's IPv6 address, or remove that record, or IPv6 clients go elsewhere`);
|
|
8477
|
+
}
|
|
8478
|
+
changes.push(...diff);
|
|
8479
|
+
if (dryRun) continue;
|
|
8480
|
+
const deletes = diff.filter((c) => c.action === "delete");
|
|
8481
|
+
if (deletes.length > 0) await provider.deleteRecords(domain.domain, deletes.map((c) => ({
|
|
8482
|
+
name: c.name,
|
|
8483
|
+
type: c.type
|
|
8484
|
+
})));
|
|
8485
|
+
const writes = diff.filter((c) => c.action === "create" || c.action === "update" || c.action === "write");
|
|
8486
|
+
if (writes.length > 0) await provider.upsertRecords(domain.domain, writes.map((c) => ({
|
|
8487
|
+
name: c.name,
|
|
8488
|
+
type: c.type,
|
|
8489
|
+
value: c.value,
|
|
8490
|
+
ttl: c.ttl
|
|
8491
|
+
})));
|
|
8492
|
+
}
|
|
8493
|
+
return changes;
|
|
8494
|
+
}
|
|
8495
|
+
/** The system resolver: what the server's own clients would be told. */
|
|
8496
|
+
const systemLookup = async (host) => {
|
|
8497
|
+
return (await (0, node_dns_promises.lookup)(host, { all: true })).map((a) => a.address);
|
|
8498
|
+
};
|
|
8499
|
+
/** Hosts that do not resolve to the stage's server. */
|
|
8500
|
+
var HostNotPointingAtServer = class extends require_errors.GkmError {
|
|
8501
|
+
stage;
|
|
8502
|
+
hosts;
|
|
8503
|
+
expected;
|
|
8504
|
+
fix;
|
|
8505
|
+
constructor(stage, hosts, expected, fix) {
|
|
8506
|
+
const want = expected.ipv6 ? `${expected.ipv4} (and ${expected.ipv6})` : expected.ipv4;
|
|
8507
|
+
const lines = hosts.map((h) => ` - ${h.host} → ${h.resolved.length > 0 ? h.resolved.join(", ") : `nothing${h.error ? ` (${h.error})` : ""}`}, expected ${want}`);
|
|
8508
|
+
super(`${hosts.length === 1 ? "A host" : `${hosts.length} hosts`} of '${stage}' do${hosts.length === 1 ? "es" : ""} not resolve to its server, so a certificate for ${hosts.length === 1 ? "it" : "them"} cannot be issued:\n${lines.join("\n")}\n${fix}\nRecords can take a few minutes to propagate. With a CDN or proxy in front of the server, pass --skip-dns-check.`);
|
|
8509
|
+
this.stage = stage;
|
|
8510
|
+
this.hosts = hosts;
|
|
8511
|
+
this.expected = expected;
|
|
8512
|
+
this.fix = fix;
|
|
8513
|
+
this.name = "HostNotPointingAtServer";
|
|
8514
|
+
}
|
|
8515
|
+
};
|
|
8516
|
+
/**
|
|
8517
|
+
* Every host resolved: each must resolve to the server's IPv4 address and to
|
|
8518
|
+
* nothing but the server's addresses.
|
|
8519
|
+
*
|
|
8520
|
+
* @throws {HostNotPointingAtServer} naming every host that does not
|
|
8521
|
+
*/
|
|
8522
|
+
async function checkStackDns(input) {
|
|
8523
|
+
const lookup = input.lookup ?? systemLookup;
|
|
8524
|
+
const { server } = input;
|
|
8525
|
+
const ours = new Set([server.ipv4, server.ipv6].filter(Boolean).map((a) => a.toLowerCase()));
|
|
8526
|
+
const bad = [];
|
|
8527
|
+
const ok = [];
|
|
8528
|
+
for (const host of input.hosts) {
|
|
8529
|
+
let resolved;
|
|
8530
|
+
try {
|
|
8531
|
+
resolved = [...new Set(await lookup(host))];
|
|
8532
|
+
} catch (error) {
|
|
8533
|
+
const code = error && typeof error === "object" && "code" in error ? String(error.code) : error instanceof Error ? error.message : String(error);
|
|
8534
|
+
bad.push({
|
|
8535
|
+
host,
|
|
8536
|
+
resolved: [],
|
|
8537
|
+
error: code
|
|
8538
|
+
});
|
|
8539
|
+
continue;
|
|
8540
|
+
}
|
|
8541
|
+
if (resolved.some((a) => a.toLowerCase() === server.ipv4.toLowerCase()) && resolved.every((a) => ours.has(a.toLowerCase()))) ok.push(host);
|
|
8542
|
+
else bad.push({
|
|
8543
|
+
host,
|
|
8544
|
+
resolved
|
|
8545
|
+
});
|
|
8546
|
+
}
|
|
8547
|
+
if (bad.length > 0) throw new HostNotPointingAtServer(input.stage, bad, {
|
|
8548
|
+
ipv4: server.ipv4,
|
|
8549
|
+
...server.ipv6 ? { ipv6: server.ipv6 } : {}
|
|
8550
|
+
}, dnsFix(input, bad));
|
|
8551
|
+
return ok;
|
|
8552
|
+
}
|
|
8553
|
+
/** How to fix it: `gkm setup`, or the records to create by hand. */
|
|
8554
|
+
function dnsFix(input, bad) {
|
|
8555
|
+
const hosts = bad.map((h) => h.host);
|
|
8556
|
+
let plan;
|
|
8557
|
+
try {
|
|
8558
|
+
plan = planStackDns({
|
|
8559
|
+
stage: input.stage,
|
|
8560
|
+
hosts,
|
|
8561
|
+
server: input.server,
|
|
8562
|
+
dns: input.dns
|
|
8563
|
+
});
|
|
8564
|
+
} catch {
|
|
8565
|
+
plan = {
|
|
8566
|
+
stage: input.stage,
|
|
8567
|
+
server: input.server,
|
|
8568
|
+
domains: [],
|
|
8569
|
+
uncovered: hosts
|
|
8570
|
+
};
|
|
8571
|
+
}
|
|
8572
|
+
const automatic = plan.domains.filter((d) => d.provider !== "manual");
|
|
8573
|
+
const byHand = [...plan.domains.filter((d) => d.provider === "manual").flatMap((d) => d.records.map(describe)), ...plan.uncovered.flatMap((host) => [`${host.padEnd(32)} A ${input.server.ipv4}`, ...input.server.ipv6 ? [`${host.padEnd(32)} AAAA ${input.server.ipv6}`] : []])];
|
|
8574
|
+
const lines = [];
|
|
8575
|
+
if (automatic.length > 0) lines.push(`Fix: gkm setup --stage ${input.stage} writes the records for ${automatic.map((d) => d.domain).join(", ")} (gkm setup --stage ${input.stage} --dry-run shows them first).`);
|
|
8576
|
+
if (byHand.length > 0) lines.push(`${automatic.length > 0 ? "And create" : "Fix: create"} these records at the DNS host:`, ...byHand.map((line) => ` ${line}`));
|
|
8577
|
+
return lines.join("\n");
|
|
8578
|
+
}
|
|
8579
|
+
//#endregion
|
|
7877
8580
|
//#region src/docker/imageRef.ts
|
|
7878
8581
|
/**
|
|
7879
8582
|
* An image reference, checked before it reaches `docker`.
|
|
@@ -8266,14 +8969,9 @@ var DeployJournal = class DeployJournal {
|
|
|
8266
8969
|
this.version = version;
|
|
8267
8970
|
this.existed = existed;
|
|
8268
8971
|
}
|
|
8269
|
-
|
|
8270
|
-
* The stage's journal — its stored state, or `initial` written as the
|
|
8271
|
-
* stage's first state, so there is somewhere to record the very first
|
|
8272
|
-
* resource before it is created.
|
|
8273
|
-
*/
|
|
8274
|
-
static async open(store, stage, initial) {
|
|
8972
|
+
static async open(store, stage, initial, adopt = (stored) => stored) {
|
|
8275
8973
|
const stored = await store.read(stage);
|
|
8276
|
-
if (stored) return new DeployJournal(store, stage, stored.state, stored.resources, stored.version, true);
|
|
8974
|
+
if (stored) return new DeployJournal(store, stage, adopt(stored.state), stored.resources, stored.version, true);
|
|
8277
8975
|
const state = initial();
|
|
8278
8976
|
const version = await store.write(stage, state, { expectedVersion: null });
|
|
8279
8977
|
return new DeployJournal(store, stage, state, {}, version, false);
|
|
@@ -8292,10 +8990,13 @@ var DeployJournal = class DeployJournal {
|
|
|
8292
8990
|
status: "pending"
|
|
8293
8991
|
});
|
|
8294
8992
|
}
|
|
8295
|
-
/**
|
|
8993
|
+
/**
|
|
8994
|
+
* Records `entry` as existing with `id`; a no-op if it already is, with
|
|
8995
|
+
* the same data.
|
|
8996
|
+
*/
|
|
8296
8997
|
async ready(entry, id) {
|
|
8297
8998
|
const current = this.resources[entry.key];
|
|
8298
|
-
if (current?.status === "ready" && current.id === id) return;
|
|
8999
|
+
if (current?.status === "ready" && current.id === id && JSON.stringify(current.data) === JSON.stringify(entry.data)) return;
|
|
8299
9000
|
await this.put({
|
|
8300
9001
|
...entry,
|
|
8301
9002
|
status: "ready",
|
|
@@ -8340,6 +9041,17 @@ var DeployJournal = class DeployJournal {
|
|
|
8340
9041
|
...staleId ? { staleId } : {}
|
|
8341
9042
|
};
|
|
8342
9043
|
}
|
|
9044
|
+
/** Removes `key`'s record — a resource that no longer exists. */
|
|
9045
|
+
async forget(key) {
|
|
9046
|
+
if (!(key in this.resources)) return;
|
|
9047
|
+
this.version = await this.store.deleteResource(this.stage, key, { expectedVersion: this.version });
|
|
9048
|
+
const { [key]: _removed, ...resources } = this.resources;
|
|
9049
|
+
this.resources = resources;
|
|
9050
|
+
}
|
|
9051
|
+
/** Every record, as the journal last wrote or read it. */
|
|
9052
|
+
records() {
|
|
9053
|
+
return this.resources;
|
|
9054
|
+
}
|
|
8343
9055
|
/** Writes the stage's state, keeping its resource records. */
|
|
8344
9056
|
async save() {
|
|
8345
9057
|
this.state.lastDeployedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -8357,6 +9069,138 @@ var DeployJournal = class DeployJournal {
|
|
|
8357
9069
|
}
|
|
8358
9070
|
};
|
|
8359
9071
|
//#endregion
|
|
9072
|
+
//#region src/providers/dns.ts
|
|
9073
|
+
/** Whether the workspace deploys through the compose target. */
|
|
9074
|
+
function deploysWithCompose(workspace) {
|
|
9075
|
+
return workspace.deploy?.default === "compose" || Object.values(workspace.apps).some((app) => app.resolvedDeployTarget === "compose");
|
|
9076
|
+
}
|
|
9077
|
+
/**
|
|
9078
|
+
* A compose stage that serves a domain has its server's address in its
|
|
9079
|
+
* secrets — checked before `gkm setup --stage` does anything else.
|
|
9080
|
+
*
|
|
9081
|
+
* @throws {ServerAddressMissing} for a compose stage with a domain and none
|
|
9082
|
+
* @throws {ServerAddressInvalid} for a value that is not an address
|
|
9083
|
+
*/
|
|
9084
|
+
function assertStageServer(workspace, stage, secrets) {
|
|
9085
|
+
if (stage === workspace.stages.local) return void 0;
|
|
9086
|
+
if (!deploysWithCompose(workspace)) return serverAddress(stage, secrets?.custom);
|
|
9087
|
+
return requiredServerAddress(stage, workspace.domains?.[stage], secrets?.custom);
|
|
9088
|
+
}
|
|
9089
|
+
/**
|
|
9090
|
+
* The hosts a compose stage serves: its stack composed as a deploy would —
|
|
9091
|
+
* with the secrets it would generate made up in memory, never written — and
|
|
9092
|
+
* every route's host read off it.
|
|
9093
|
+
*/
|
|
9094
|
+
async function composeStageHosts(options) {
|
|
9095
|
+
const { workspace, stage } = options;
|
|
9096
|
+
const runnables = options.runnables ?? {};
|
|
9097
|
+
const background = options.background ?? {};
|
|
9098
|
+
const manifest = options.manifest ?? await require_discover.discover({
|
|
9099
|
+
patterns: constructGlobs(workspace),
|
|
9100
|
+
cwd: workspace.root,
|
|
9101
|
+
runnables,
|
|
9102
|
+
background
|
|
9103
|
+
});
|
|
9104
|
+
const stored = await (await secretsStoreFor(workspace, stage, {
|
|
9105
|
+
...options.profile ? { profile: options.profile } : {},
|
|
9106
|
+
...options.home ? { home: options.home } : {}
|
|
9107
|
+
})).read(stage);
|
|
9108
|
+
const { deployedStackSecrets } = await Promise.resolve().then(() => require("./secrets-DJteijZo.cjs")).then((n) => n.secrets_exports);
|
|
9109
|
+
const { composeStack } = await Promise.resolve().then(() => require("./stack-1PeLJS2j.cjs")).then((n) => n.stack_exports);
|
|
9110
|
+
const { secrets } = deployedStackSecrets(workspace, stage, stored, manifest);
|
|
9111
|
+
return stackHosts(composeStack({
|
|
9112
|
+
workspace,
|
|
9113
|
+
manifest,
|
|
9114
|
+
runnables,
|
|
9115
|
+
background,
|
|
9116
|
+
stage,
|
|
9117
|
+
identity: deployIdentity(workspace, stage),
|
|
9118
|
+
images: {
|
|
9119
|
+
mode: "pull",
|
|
9120
|
+
tag: "dns",
|
|
9121
|
+
...workspace.deploy?.registry ? { registry: workspace.deploy.registry } : {}
|
|
9122
|
+
},
|
|
9123
|
+
secrets,
|
|
9124
|
+
buildOnly: true,
|
|
9125
|
+
allowDevServices: true
|
|
9126
|
+
}));
|
|
9127
|
+
}
|
|
9128
|
+
/**
|
|
9129
|
+
* `GKM_SERVER_IPV4` from the stage's secrets and `dns`: each public host's
|
|
9130
|
+
* records, created or corrected. A dry run reads and prints, and writes
|
|
9131
|
+
* nothing.
|
|
9132
|
+
*/
|
|
9133
|
+
async function provisionStageDns(options) {
|
|
9134
|
+
const { workspace, stage } = options;
|
|
9135
|
+
const log = options.log ?? ((line) => console.log(line));
|
|
9136
|
+
if (stage === workspace.stages.local || !workspace.dns || !deploysWithCompose(workspace)) return {
|
|
9137
|
+
mode: "none",
|
|
9138
|
+
hosts: [],
|
|
9139
|
+
changes: []
|
|
9140
|
+
};
|
|
9141
|
+
const server = serverAddress(stage, (await (await secretsStoreFor(workspace, stage, {
|
|
9142
|
+
...options.profile ? { profile: options.profile } : {},
|
|
9143
|
+
...options.home ? { home: options.home } : {}
|
|
9144
|
+
})).read(stage))?.custom);
|
|
9145
|
+
if (!server) {
|
|
9146
|
+
log(`\n🌐 DNS for '${stage}': no GKM_SERVER_IPV4 in its secrets, so no records — ${serverAddressHint(stage)}`);
|
|
9147
|
+
return {
|
|
9148
|
+
mode: "none",
|
|
9149
|
+
hosts: [],
|
|
9150
|
+
changes: []
|
|
9151
|
+
};
|
|
9152
|
+
}
|
|
9153
|
+
const hosts = [...options.hosts ?? await composeStageHosts({
|
|
9154
|
+
workspace,
|
|
9155
|
+
stage,
|
|
9156
|
+
...options.profile ? { profile: options.profile } : {},
|
|
9157
|
+
...options.home ? { home: options.home } : {},
|
|
9158
|
+
...options.manifest ? { manifest: options.manifest } : {},
|
|
9159
|
+
...options.runnables ? { runnables: options.runnables } : {},
|
|
9160
|
+
...options.background ? { background: options.background } : {}
|
|
9161
|
+
})];
|
|
9162
|
+
log(`\n🌐 DNS for '${stage}' → ${server.ipv4}${server.ipv6 ? ` / ${server.ipv6}` : ""}${options.dryRun ? " (dry run — nothing is written)" : ""}`);
|
|
9163
|
+
const plan = planStackDns({
|
|
9164
|
+
stage,
|
|
9165
|
+
hosts,
|
|
9166
|
+
server,
|
|
9167
|
+
dns: workspace.dns
|
|
9168
|
+
});
|
|
9169
|
+
try {
|
|
9170
|
+
const changes = await applyStackDns(plan, {
|
|
9171
|
+
...options.dryRun ? { dryRun: true } : {},
|
|
9172
|
+
log,
|
|
9173
|
+
credentials: {
|
|
9174
|
+
env: options.env ?? process.env,
|
|
9175
|
+
...options.home ? { home: options.home } : {},
|
|
9176
|
+
log
|
|
9177
|
+
},
|
|
9178
|
+
...options.providerFor ? { providerFor: options.providerFor } : {}
|
|
9179
|
+
});
|
|
9180
|
+
if (options.journal && !options.dryRun) {
|
|
9181
|
+
const providers = new Map(plan.domains.map((domain) => [domain.domain, domain.provider]));
|
|
9182
|
+
await recordDnsChanges(options.journal, changes, (domain) => providers.get(domain));
|
|
9183
|
+
}
|
|
9184
|
+
return {
|
|
9185
|
+
mode: "records",
|
|
9186
|
+
hosts,
|
|
9187
|
+
changes
|
|
9188
|
+
};
|
|
9189
|
+
} catch (error) {
|
|
9190
|
+
if (error instanceof require_credentials.MissingCredential) {
|
|
9191
|
+
log(` ⚠ ${error.message}`);
|
|
9192
|
+
log(" Until then, create these records yourself:");
|
|
9193
|
+
for (const domain of plan.domains) for (const r of domain.records) log(` ${r.host.padEnd(32)} ${r.type.padEnd(5)} ${r.value} (TTL ${r.ttl})`);
|
|
9194
|
+
return {
|
|
9195
|
+
mode: "records",
|
|
9196
|
+
hosts,
|
|
9197
|
+
changes: []
|
|
9198
|
+
};
|
|
9199
|
+
}
|
|
9200
|
+
throw error;
|
|
9201
|
+
}
|
|
9202
|
+
}
|
|
9203
|
+
//#endregion
|
|
8360
9204
|
//#region src/providers/aws.ts
|
|
8361
9205
|
/**
|
|
8362
9206
|
* The AWS account a provider provisions in — the stage's, found the way the
|
|
@@ -9328,7 +10172,7 @@ async function provisionStage(options) {
|
|
|
9328
10172
|
});
|
|
9329
10173
|
const lock = dryRun ? void 0 : await stateStore.lock(stage, { operation: "provision" });
|
|
9330
10174
|
try {
|
|
9331
|
-
const state = dryRun ? await readOnlyState(stateStore, stage) : journalState(await DeployJournal.open(stateStore, stage, () => createEmptyState(stage, "", "")));
|
|
10175
|
+
const state = dryRun ? await readOnlyState(stateStore, stage) : journalState(await DeployJournal.open(stateStore, stage, () => deploysWithCompose(workspace) ? createComposeState(stage) : createEmptyState(stage, "", "")));
|
|
9332
10176
|
const writeSecrets = async (values) => {
|
|
9333
10177
|
if (dryRun) return;
|
|
9334
10178
|
const stored = await secretsStore.read(stage) ?? initStageSecrets(stage);
|
|
@@ -9639,6 +10483,12 @@ Object.defineProperty(exports, "FileSecretsStore", {
|
|
|
9639
10483
|
return FileSecretsStore;
|
|
9640
10484
|
}
|
|
9641
10485
|
});
|
|
10486
|
+
Object.defineProperty(exports, "HostNotPointingAtServer", {
|
|
10487
|
+
enumerable: true,
|
|
10488
|
+
get: function() {
|
|
10489
|
+
return HostNotPointingAtServer;
|
|
10490
|
+
}
|
|
10491
|
+
});
|
|
9642
10492
|
Object.defineProperty(exports, "LEGACY_LOCAL_LOGIN", {
|
|
9643
10493
|
enumerable: true,
|
|
9644
10494
|
get: function() {
|
|
@@ -9669,6 +10519,12 @@ Object.defineProperty(exports, "LOGS_SERVICE", {
|
|
|
9669
10519
|
return LOGS_SERVICE;
|
|
9670
10520
|
}
|
|
9671
10521
|
});
|
|
10522
|
+
Object.defineProperty(exports, "LocalStateInCi", {
|
|
10523
|
+
enumerable: true,
|
|
10524
|
+
get: function() {
|
|
10525
|
+
return LocalStateInCi;
|
|
10526
|
+
}
|
|
10527
|
+
});
|
|
9672
10528
|
Object.defineProperty(exports, "NoDomainForStage", {
|
|
9673
10529
|
enumerable: true,
|
|
9674
10530
|
get: function() {
|
|
@@ -9777,6 +10633,12 @@ Object.defineProperty(exports, "appTelemetry", {
|
|
|
9777
10633
|
return appTelemetry;
|
|
9778
10634
|
}
|
|
9779
10635
|
});
|
|
10636
|
+
Object.defineProperty(exports, "appendHistory", {
|
|
10637
|
+
enumerable: true,
|
|
10638
|
+
get: function() {
|
|
10639
|
+
return appendHistory;
|
|
10640
|
+
}
|
|
10641
|
+
});
|
|
9780
10642
|
Object.defineProperty(exports, "applicationName", {
|
|
9781
10643
|
enumerable: true,
|
|
9782
10644
|
get: function() {
|
|
@@ -9801,6 +10663,12 @@ Object.defineProperty(exports, "applyPostgres", {
|
|
|
9801
10663
|
return applyPostgres;
|
|
9802
10664
|
}
|
|
9803
10665
|
});
|
|
10666
|
+
Object.defineProperty(exports, "asDokployState", {
|
|
10667
|
+
enumerable: true,
|
|
10668
|
+
get: function() {
|
|
10669
|
+
return asDokployState;
|
|
10670
|
+
}
|
|
10671
|
+
});
|
|
9804
10672
|
Object.defineProperty(exports, "assertDevServicesFlag", {
|
|
9805
10673
|
enumerable: true,
|
|
9806
10674
|
get: function() {
|
|
@@ -9825,6 +10693,18 @@ Object.defineProperty(exports, "assertStageProvidersEnabled", {
|
|
|
9825
10693
|
return assertStageProvidersEnabled;
|
|
9826
10694
|
}
|
|
9827
10695
|
});
|
|
10696
|
+
Object.defineProperty(exports, "assertStageServer", {
|
|
10697
|
+
enumerable: true,
|
|
10698
|
+
get: function() {
|
|
10699
|
+
return assertStageServer;
|
|
10700
|
+
}
|
|
10701
|
+
});
|
|
10702
|
+
Object.defineProperty(exports, "assertStateOutlivesRun", {
|
|
10703
|
+
enumerable: true,
|
|
10704
|
+
get: function() {
|
|
10705
|
+
return assertStateOutlivesRun;
|
|
10706
|
+
}
|
|
10707
|
+
});
|
|
9828
10708
|
Object.defineProperty(exports, "backendsOf", {
|
|
9829
10709
|
enumerable: true,
|
|
9830
10710
|
get: function() {
|
|
@@ -9849,6 +10729,12 @@ Object.defineProperty(exports, "cacheBackendFor", {
|
|
|
9849
10729
|
return cacheBackendFor;
|
|
9850
10730
|
}
|
|
9851
10731
|
});
|
|
10732
|
+
Object.defineProperty(exports, "checkStackDns", {
|
|
10733
|
+
enumerable: true,
|
|
10734
|
+
get: function() {
|
|
10735
|
+
return checkStackDns;
|
|
10736
|
+
}
|
|
10737
|
+
});
|
|
9852
10738
|
Object.defineProperty(exports, "composeBuildPaths", {
|
|
9853
10739
|
enumerable: true,
|
|
9854
10740
|
get: function() {
|
|
@@ -9873,16 +10759,16 @@ Object.defineProperty(exports, "contentVersion", {
|
|
|
9873
10759
|
return contentVersion;
|
|
9874
10760
|
}
|
|
9875
10761
|
});
|
|
9876
|
-
Object.defineProperty(exports, "
|
|
10762
|
+
Object.defineProperty(exports, "createComposeState", {
|
|
9877
10763
|
enumerable: true,
|
|
9878
10764
|
get: function() {
|
|
9879
|
-
return
|
|
10765
|
+
return createComposeState;
|
|
9880
10766
|
}
|
|
9881
10767
|
});
|
|
9882
|
-
Object.defineProperty(exports, "
|
|
10768
|
+
Object.defineProperty(exports, "createCredentialsPreload", {
|
|
9883
10769
|
enumerable: true,
|
|
9884
10770
|
get: function() {
|
|
9885
|
-
return
|
|
10771
|
+
return createCredentialsPreload;
|
|
9886
10772
|
}
|
|
9887
10773
|
});
|
|
9888
10774
|
Object.defineProperty(exports, "createEmptyState", {
|
|
@@ -9903,18 +10789,36 @@ Object.defineProperty(exports, "createStateStore", {
|
|
|
9903
10789
|
return createStateStore;
|
|
9904
10790
|
}
|
|
9905
10791
|
});
|
|
10792
|
+
Object.defineProperty(exports, "currentActor", {
|
|
10793
|
+
enumerable: true,
|
|
10794
|
+
get: function() {
|
|
10795
|
+
return currentActor;
|
|
10796
|
+
}
|
|
10797
|
+
});
|
|
9906
10798
|
Object.defineProperty(exports, "deployIdentity", {
|
|
9907
10799
|
enumerable: true,
|
|
9908
10800
|
get: function() {
|
|
9909
10801
|
return deployIdentity;
|
|
9910
10802
|
}
|
|
9911
10803
|
});
|
|
10804
|
+
Object.defineProperty(exports, "deploysWithCompose", {
|
|
10805
|
+
enumerable: true,
|
|
10806
|
+
get: function() {
|
|
10807
|
+
return deploysWithCompose;
|
|
10808
|
+
}
|
|
10809
|
+
});
|
|
9912
10810
|
Object.defineProperty(exports, "derivedContainers", {
|
|
9913
10811
|
enumerable: true,
|
|
9914
10812
|
get: function() {
|
|
9915
10813
|
return derivedContainers;
|
|
9916
10814
|
}
|
|
9917
10815
|
});
|
|
10816
|
+
Object.defineProperty(exports, "describeActor", {
|
|
10817
|
+
enumerable: true,
|
|
10818
|
+
get: function() {
|
|
10819
|
+
return describeActor;
|
|
10820
|
+
}
|
|
10821
|
+
});
|
|
9918
10822
|
Object.defineProperty(exports, "describeServices", {
|
|
9919
10823
|
enumerable: true,
|
|
9920
10824
|
get: function() {
|
|
@@ -9933,6 +10837,12 @@ Object.defineProperty(exports, "devServicesUsed", {
|
|
|
9933
10837
|
return devServicesUsed;
|
|
9934
10838
|
}
|
|
9935
10839
|
});
|
|
10840
|
+
Object.defineProperty(exports, "dnsResources", {
|
|
10841
|
+
enumerable: true,
|
|
10842
|
+
get: function() {
|
|
10843
|
+
return dnsResources;
|
|
10844
|
+
}
|
|
10845
|
+
});
|
|
9936
10846
|
Object.defineProperty(exports, "dockerCommand", {
|
|
9937
10847
|
enumerable: true,
|
|
9938
10848
|
get: function() {
|
|
@@ -9975,12 +10885,6 @@ Object.defineProperty(exports, "externalServices", {
|
|
|
9975
10885
|
return externalServices;
|
|
9976
10886
|
}
|
|
9977
10887
|
});
|
|
9978
|
-
Object.defineProperty(exports, "extractSubdomain", {
|
|
9979
|
-
enumerable: true,
|
|
9980
|
-
get: function() {
|
|
9981
|
-
return extractSubdomain;
|
|
9982
|
-
}
|
|
9983
|
-
});
|
|
9984
10888
|
Object.defineProperty(exports, "fakeKey", {
|
|
9985
10889
|
enumerable: true,
|
|
9986
10890
|
get: function() {
|
|
@@ -9999,12 +10903,6 @@ Object.defineProperty(exports, "findBuildRoot", {
|
|
|
9999
10903
|
return findBuildRoot;
|
|
10000
10904
|
}
|
|
10001
10905
|
});
|
|
10002
|
-
Object.defineProperty(exports, "findRootDomain", {
|
|
10003
|
-
enumerable: true,
|
|
10004
|
-
get: function() {
|
|
10005
|
-
return findRootDomain;
|
|
10006
|
-
}
|
|
10007
|
-
});
|
|
10008
10906
|
Object.defineProperty(exports, "forgetState", {
|
|
10009
10907
|
enumerable: true,
|
|
10010
10908
|
get: function() {
|
|
@@ -10071,6 +10969,12 @@ Object.defineProperty(exports, "isImageBuild", {
|
|
|
10071
10969
|
return isImageBuild;
|
|
10072
10970
|
}
|
|
10073
10971
|
});
|
|
10972
|
+
Object.defineProperty(exports, "isLocalHost", {
|
|
10973
|
+
enumerable: true,
|
|
10974
|
+
get: function() {
|
|
10975
|
+
return isLocalHost;
|
|
10976
|
+
}
|
|
10977
|
+
});
|
|
10074
10978
|
Object.defineProperty(exports, "isMainFrontendApp", {
|
|
10075
10979
|
enumerable: true,
|
|
10076
10980
|
get: function() {
|
|
@@ -10179,12 +11083,6 @@ Object.defineProperty(exports, "newLockHolder", {
|
|
|
10179
11083
|
return newLockHolder;
|
|
10180
11084
|
}
|
|
10181
11085
|
});
|
|
10182
|
-
Object.defineProperty(exports, "normalizeDnsConfig", {
|
|
10183
|
-
enumerable: true,
|
|
10184
|
-
get: function() {
|
|
10185
|
-
return normalizeDnsConfig;
|
|
10186
|
-
}
|
|
10187
|
-
});
|
|
10188
11086
|
Object.defineProperty(exports, "orchestrateDns", {
|
|
10189
11087
|
enumerable: true,
|
|
10190
11088
|
get: function() {
|
|
@@ -10281,6 +11179,12 @@ Object.defineProperty(exports, "provisionStage", {
|
|
|
10281
11179
|
return provisionStage;
|
|
10282
11180
|
}
|
|
10283
11181
|
});
|
|
11182
|
+
Object.defineProperty(exports, "provisionStageDns", {
|
|
11183
|
+
enumerable: true,
|
|
11184
|
+
get: function() {
|
|
11185
|
+
return provisionStageDns;
|
|
11186
|
+
}
|
|
11187
|
+
});
|
|
10284
11188
|
Object.defineProperty(exports, "quoteIdentifier", {
|
|
10285
11189
|
enumerable: true,
|
|
10286
11190
|
get: function() {
|
|
@@ -10341,6 +11245,12 @@ Object.defineProperty(exports, "reportPlannedSeeds", {
|
|
|
10341
11245
|
return reportPlannedSeeds;
|
|
10342
11246
|
}
|
|
10343
11247
|
});
|
|
11248
|
+
Object.defineProperty(exports, "requiredServerAddress", {
|
|
11249
|
+
enumerable: true,
|
|
11250
|
+
get: function() {
|
|
11251
|
+
return requiredServerAddress;
|
|
11252
|
+
}
|
|
11253
|
+
});
|
|
10344
11254
|
Object.defineProperty(exports, "requiredStageKeys", {
|
|
10345
11255
|
enumerable: true,
|
|
10346
11256
|
get: function() {
|
|
@@ -10377,6 +11287,12 @@ Object.defineProperty(exports, "secretsStoreFor", {
|
|
|
10377
11287
|
return secretsStoreFor;
|
|
10378
11288
|
}
|
|
10379
11289
|
});
|
|
11290
|
+
Object.defineProperty(exports, "serverAddressHint", {
|
|
11291
|
+
enumerable: true,
|
|
11292
|
+
get: function() {
|
|
11293
|
+
return serverAddressHint;
|
|
11294
|
+
}
|
|
11295
|
+
});
|
|
10380
11296
|
Object.defineProperty(exports, "setApplicationId", {
|
|
10381
11297
|
enumerable: true,
|
|
10382
11298
|
get: function() {
|
|
@@ -10401,6 +11317,12 @@ Object.defineProperty(exports, "setPostgresBackupId", {
|
|
|
10401
11317
|
return setPostgresBackupId;
|
|
10402
11318
|
}
|
|
10403
11319
|
});
|
|
11320
|
+
Object.defineProperty(exports, "stackHosts", {
|
|
11321
|
+
enumerable: true,
|
|
11322
|
+
get: function() {
|
|
11323
|
+
return stackHosts;
|
|
11324
|
+
}
|
|
11325
|
+
});
|
|
10404
11326
|
Object.defineProperty(exports, "stackLogs", {
|
|
10405
11327
|
enumerable: true,
|
|
10406
11328
|
get: function() {
|
|
@@ -10455,6 +11377,12 @@ Object.defineProperty(exports, "surfaceClientTraced", {
|
|
|
10455
11377
|
return surfaceClientTraced;
|
|
10456
11378
|
}
|
|
10457
11379
|
});
|
|
11380
|
+
Object.defineProperty(exports, "systemLookup", {
|
|
11381
|
+
enumerable: true,
|
|
11382
|
+
get: function() {
|
|
11383
|
+
return systemLookup;
|
|
11384
|
+
}
|
|
11385
|
+
});
|
|
10458
11386
|
Object.defineProperty(exports, "telemetryOf", {
|
|
10459
11387
|
enumerable: true,
|
|
10460
11388
|
get: function() {
|
|
@@ -10467,6 +11395,12 @@ Object.defineProperty(exports, "toEmbeddableSecrets", {
|
|
|
10467
11395
|
return toEmbeddableSecrets;
|
|
10468
11396
|
}
|
|
10469
11397
|
});
|
|
11398
|
+
Object.defineProperty(exports, "upgradeV2State", {
|
|
11399
|
+
enumerable: true,
|
|
11400
|
+
get: function() {
|
|
11401
|
+
return upgradeV2State;
|
|
11402
|
+
}
|
|
11403
|
+
});
|
|
10470
11404
|
Object.defineProperty(exports, "usesTelemetry", {
|
|
10471
11405
|
enumerable: true,
|
|
10472
11406
|
get: function() {
|
|
@@ -10558,4 +11492,4 @@ Object.defineProperty(exports, "workspace_exports", {
|
|
|
10558
11492
|
}
|
|
10559
11493
|
});
|
|
10560
11494
|
|
|
10561
|
-
//# sourceMappingURL=seeds-
|
|
11495
|
+
//# sourceMappingURL=seeds-c-ByX9je.cjs.map
|