@geekmidas/cli 10.0.0-alpha.63 → 10.0.0-alpha.64
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/{HostingerProvider-mJ7YruxH.cjs → HostingerProvider-Bx2lHHvu.cjs} +3 -3
- package/dist/{HostingerProvider-mJ7YruxH.cjs.map → HostingerProvider-Bx2lHHvu.cjs.map} +1 -1
- package/dist/{HostingerProvider-DBBwpDjn.mjs → HostingerProvider-Cd4aS5Kj.mjs} +2 -2
- package/dist/{HostingerProvider-DBBwpDjn.mjs.map → HostingerProvider-Cd4aS5Kj.mjs.map} +1 -1
- package/dist/{LegacyStateStore-CP7SZwTP.cjs → LegacyStateStore-C2abV49N.cjs} +2 -2
- package/dist/{LegacyStateStore-CP7SZwTP.cjs.map → LegacyStateStore-C2abV49N.cjs.map} +1 -1
- package/dist/{LegacyStateStore-Q3GmKOdw.mjs → LegacyStateStore-DIgkGaUP.mjs} +2 -2
- package/dist/{LegacyStateStore-Q3GmKOdw.mjs.map → LegacyStateStore-DIgkGaUP.mjs.map} +1 -1
- package/dist/{LocalStateStore-BGIXcrvX.mjs → LocalStateStore-Cy1ZBW7U.mjs} +2 -2
- package/dist/{LocalStateStore-BGIXcrvX.mjs.map → LocalStateStore-Cy1ZBW7U.mjs.map} +1 -1
- package/dist/{LocalStateStore-sS8mvLeq.cjs → LocalStateStore-DiJqKyPy.cjs} +2 -2
- package/dist/{LocalStateStore-sS8mvLeq.cjs.map → LocalStateStore-DiJqKyPy.cjs.map} +1 -1
- package/dist/{OpenApiTsGenerator-CjHWFRDd.cjs → OpenApiTsGenerator-BWuDRHe9.cjs} +2 -2
- package/dist/{OpenApiTsGenerator-CjHWFRDd.cjs.map → OpenApiTsGenerator-BWuDRHe9.cjs.map} +1 -1
- package/dist/{OpenApiTsGenerator-CnAwhGxi.mjs → OpenApiTsGenerator-C6v-IeHt.mjs} +2 -2
- package/dist/{OpenApiTsGenerator-CnAwhGxi.mjs.map → OpenApiTsGenerator-C6v-IeHt.mjs.map} +1 -1
- package/dist/{S3StateStore-D7l_lWJ3.mjs → S3StateStore-D3x6ivBL.mjs} +2 -2
- package/dist/{S3StateStore-D7l_lWJ3.mjs.map → S3StateStore-D3x6ivBL.mjs.map} +1 -1
- package/dist/{S3StateStore-6jqITH2F.cjs → S3StateStore-Ds0V1Lgm.cjs} +2 -2
- package/dist/{S3StateStore-6jqITH2F.cjs.map → S3StateStore-Ds0V1Lgm.cjs.map} +1 -1
- package/dist/{SSMStateStore-B__F7IJa.cjs → SSMStateStore-CLipvx47.cjs} +2 -2
- package/dist/{SSMStateStore-B__F7IJa.cjs.map → SSMStateStore-CLipvx47.cjs.map} +1 -1
- package/dist/{SSMStateStore-CAQDVpoc.mjs → SSMStateStore-DfF174xQ.mjs} +2 -2
- package/dist/{SSMStateStore-CAQDVpoc.mjs.map → SSMStateStore-DfF174xQ.mjs.map} +1 -1
- package/dist/{bundler-DLfOn0ls.cjs → bundler-C8uJf324.cjs} +3 -3
- package/dist/{bundler-DLfOn0ls.cjs.map → bundler-C8uJf324.cjs.map} +1 -1
- package/dist/{bundler-DyWI41Iy.mjs → bundler-DYgm9xsd.mjs} +3 -3
- package/dist/{bundler-DyWI41Iy.mjs.map → bundler-DYgm9xsd.mjs.map} +1 -1
- package/dist/{cli-PkVF28LM.mjs → cli-Bogz-zEj.mjs} +5 -4
- package/dist/{cli-PkVF28LM.mjs.map → cli-Bogz-zEj.mjs.map} +1 -1
- package/dist/{cli-D-ZM-X2s.cjs → cli-D3jofJ6j.cjs} +7 -6
- package/dist/{cli-D-ZM-X2s.cjs.map → cli-D3jofJ6j.cjs.map} +1 -1
- package/dist/{config-CemHVcIr.d.cts → config-Be-4_I6H.d.cts} +3 -3
- package/dist/{config-C2BUosLm.d.mts.map → config-Be-4_I6H.d.cts.map} +1 -1
- package/dist/{config-C2BUosLm.d.mts → config-DqNRiQOp.d.mts} +3 -3
- package/dist/{config-CemHVcIr.d.cts.map → config-DqNRiQOp.d.mts.map} +1 -1
- package/dist/config.cjs +416 -17
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +3 -3
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +401 -2
- package/dist/config.mjs.map +1 -0
- package/dist/credentials-B70vmLcm.cjs +125 -0
- package/dist/credentials-B70vmLcm.cjs.map +1 -0
- package/dist/credentials-s0wMeZBU.mjs +108 -0
- package/dist/credentials-s0wMeZBU.mjs.map +1 -0
- package/dist/{define-CHBIEc5j.mjs → define-CYs0PEfZ.mjs} +2 -3
- package/dist/define-CYs0PEfZ.mjs.map +1 -0
- package/dist/{define-Cv_QvDrg.cjs → define-zUsP72ym.cjs} +2 -3
- package/dist/define-zUsP72ym.cjs.map +1 -0
- package/dist/deploy/public.cjs +32 -26
- package/dist/deploy/public.cjs.map +1 -1
- package/dist/deploy/public.d.cts +40 -4
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts +40 -4
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +15 -12
- package/dist/deploy/public.mjs.map +1 -1
- package/dist/{deploy-ABBI0lf1.cjs → deploy-55rJkdKz.cjs} +17 -14
- package/dist/{deploy-ABBI0lf1.cjs.map → deploy-55rJkdKz.cjs.map} +1 -1
- package/dist/{deploy-CGW-QY9D.mjs → deploy-Dc2LBJaK.mjs} +8 -7
- package/dist/{deploy-CGW-QY9D.mjs.map → deploy-Dc2LBJaK.mjs.map} +1 -1
- package/dist/{deploy-CG8bfFij.mjs → deploy-ZRXIPp1c.mjs} +11 -8
- package/dist/{deploy-CG8bfFij.mjs.map → deploy-ZRXIPp1c.mjs.map} +1 -1
- package/dist/{deploy-BiMrP9i7.cjs → deploy-yUcR2OlW.cjs} +12 -11
- package/dist/{deploy-BiMrP9i7.cjs.map → deploy-yUcR2OlW.cjs.map} +1 -1
- package/dist/derive-B4vDpzgP.mjs +150 -0
- package/dist/derive-B4vDpzgP.mjs.map +1 -0
- package/dist/derive-DAbo49sm.cjs +161 -0
- package/dist/derive-DAbo49sm.cjs.map +1 -0
- package/dist/{discover-C_6COHEv.cjs → discover-DHdECueV.cjs} +6 -157
- package/dist/discover-DHdECueV.cjs.map +1 -0
- package/dist/{discover-BaT6bpnA.mjs → discover-LMrqsWSU.mjs} +8 -117
- package/dist/discover-LMrqsWSU.mjs.map +1 -0
- package/dist/{dokploy-CwdmlyQL.mjs → dokploy-CepdXuMl.mjs} +3 -3
- package/dist/{dokploy-CwdmlyQL.mjs.map → dokploy-CepdXuMl.mjs.map} +1 -1
- package/dist/{dokploy-QJxMhxdf.cjs → dokploy-D1d37rvM.cjs} +3 -3
- package/dist/{dokploy-QJxMhxdf.cjs.map → dokploy-D1d37rvM.cjs.map} +1 -1
- package/dist/{encryption-DXw3jj0c.cjs → encryption-C9X98u2F.cjs} +5 -5
- package/dist/{encryption-DXw3jj0c.cjs.map → encryption-C9X98u2F.cjs.map} +1 -1
- package/dist/{encryption-CbQG_ayW.mjs → encryption-CKHjMpCr.mjs} +5 -5
- package/dist/{encryption-CbQG_ayW.mjs.map → encryption-CKHjMpCr.mjs.map} +1 -1
- package/dist/{github-ciwbIwVa.mjs → github-D-byNI7T.mjs} +4 -4
- package/dist/{github-ciwbIwVa.mjs.map → github-D-byNI7T.mjs.map} +1 -1
- package/dist/{github-BH_mETav.cjs → github-Dd3tMa1u.cjs} +4 -4
- package/dist/{github-BH_mETav.cjs.map → github-Dd3tMa1u.cjs.map} +1 -1
- package/dist/{index-DrKzpHl-.d.mts → index-CJ2qsSpp.d.mts} +2 -2
- package/dist/{index-BtXDZQuF.d.cts.map → index-CJ2qsSpp.d.mts.map} +1 -1
- package/dist/{index-BtXDZQuF.d.cts → index-CfE9Y885.d.cts} +2 -2
- package/dist/{index-DrKzpHl-.d.mts.map → index-CfE9Y885.d.cts.map} +1 -1
- package/dist/index.cjs +100 -235
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +71 -206
- package/dist/index.mjs.map +1 -1
- package/dist/local-C7wnrcYK.cjs +586 -0
- package/dist/local-C7wnrcYK.cjs.map +1 -0
- package/dist/local-Cd8ZYQG3.mjs +473 -0
- package/dist/local-Cd8ZYQG3.mjs.map +1 -0
- package/dist/{migrate-ImBKTBcW.mjs → migrate-B4gngTLe.mjs} +6 -6
- package/dist/{migrate-ImBKTBcW.mjs.map → migrate-B4gngTLe.mjs.map} +1 -1
- package/dist/{migrate-6oa9y_f2.cjs → migrate-tx9-P9uz.cjs} +6 -6
- package/dist/{migrate-6oa9y_f2.cjs.map → migrate-tx9-P9uz.cjs.map} +1 -1
- package/dist/openapi.cjs +2 -2
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +2 -2
- package/dist/{ready-Bpdnn2ON.mjs → ready-bQfu9GES.mjs} +3 -3
- package/dist/{ready-Bpdnn2ON.mjs.map → ready-bQfu9GES.mjs.map} +1 -1
- package/dist/{ready-BiG0rt4h.cjs → ready-brEhh68f.cjs} +3 -3
- package/dist/{ready-BiG0rt4h.cjs.map → ready-brEhh68f.cjs.map} +1 -1
- package/dist/reconcile/public.cjs +1 -1
- package/dist/reconcile/public.d.cts +1 -1
- package/dist/reconcile/public.d.mts +1 -1
- package/dist/reconcile/public.mjs +1 -1
- package/dist/{resolve-xytBTtG4.cjs → resolve-BXsNQjMR.cjs} +9 -6
- package/dist/resolve-BXsNQjMR.cjs.map +1 -0
- package/dist/{resolve-B1T0hUaR.mjs → resolve-DZ2IJ0qY.mjs} +9 -6
- package/dist/resolve-DZ2IJ0qY.mjs.map +1 -0
- package/dist/{runtime-CMwtq0AL.cjs → runtime-BGNDrHzh.cjs} +2 -2
- package/dist/{runtime-CMwtq0AL.cjs.map → runtime-BGNDrHzh.cjs.map} +1 -1
- package/dist/{runtime-Dn_n-29S.d.cts → runtime-CJEYK4Gz.d.mts} +2 -2
- package/dist/{runtime-CXPlkZzs.d.mts.map → runtime-CJEYK4Gz.d.mts.map} +1 -1
- package/dist/{runtime-CXPlkZzs.d.mts → runtime-Cjq1jlVX.d.cts} +2 -2
- package/dist/{runtime-Dn_n-29S.d.cts.map → runtime-Cjq1jlVX.d.cts.map} +1 -1
- package/dist/{runtime-DbakJS8u.mjs → runtime-Cmn-FeYO.mjs} +2 -2
- package/dist/{runtime-DbakJS8u.mjs.map → runtime-Cmn-FeYO.mjs.map} +1 -1
- package/dist/sandbox/discover-worker.cjs +1 -1
- package/dist/sandbox/discover-worker.mjs +1 -1
- package/dist/sandbox-CL--ZDui.cjs +164 -0
- package/dist/sandbox-CL--ZDui.cjs.map +1 -0
- package/dist/sandbox-Dm247NGx.mjs +117 -0
- package/dist/sandbox-Dm247NGx.mjs.map +1 -0
- package/dist/{sniffer-aO_-s5vq.mjs → sniffer-49KPbDgq.mjs} +25 -470
- package/dist/sniffer-49KPbDgq.mjs.map +1 -0
- package/dist/{sniffer-D_SYc_pO.cjs → sniffer-ByhbEW5A.cjs} +38 -567
- package/dist/sniffer-ByhbEW5A.cjs.map +1 -0
- package/dist/sst-BdALKEas.cjs +453 -0
- package/dist/sst-BdALKEas.cjs.map +1 -0
- package/dist/sst-Cper040I.mjs +430 -0
- package/dist/sst-Cper040I.mjs.map +1 -0
- package/dist/{store-BS8A7NcA.mjs → store-BaaonhkJ.mjs} +2 -2
- package/dist/{store-BS8A7NcA.mjs.map → store-BaaonhkJ.mjs.map} +1 -1
- package/dist/{store-KvNQwYaB.cjs → store-D_2ByRtW.cjs} +4 -4
- package/dist/{store-KvNQwYaB.cjs.map → store-D_2ByRtW.cjs.map} +1 -1
- package/dist/target/public.cjs +3 -3
- package/dist/target/public.d.cts +3 -3
- package/dist/target/public.d.mts +3 -3
- package/dist/target/public.mjs +3 -3
- package/dist/{terminal-D0f1u0LG.cjs → terminal-Bdv--jhY.cjs} +16 -111
- package/dist/terminal-Bdv--jhY.cjs.map +1 -0
- package/dist/{terminal-gMxAo9Dj.mjs → terminal-D7Ntz6WE.mjs} +13 -90
- package/dist/terminal-D7Ntz6WE.mjs.map +1 -0
- package/dist/{types-DIA7Li-J.d.cts → types-B_bEQvb9.d.mts} +42 -7
- package/dist/types-B_bEQvb9.d.mts.map +1 -0
- package/dist/{types-CfLKGfC_.d.mts → types-DkrDOMxw.d.cts} +43 -6
- package/dist/types-DkrDOMxw.d.cts.map +1 -0
- package/dist/utils-D2Nk1Nv2.cjs +205 -0
- package/dist/utils-D2Nk1Nv2.cjs.map +1 -0
- package/dist/utils-D_fxUqvU.mjs +156 -0
- package/dist/utils-D_fxUqvU.mjs.map +1 -0
- package/dist/vitest.cjs +1 -1
- package/dist/vitest.mjs +1 -1
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-Kl4NG9IH.cjs → workspace-BwgWJK7h.cjs} +5 -5
- package/dist/workspace-BwgWJK7h.cjs.map +1 -0
- package/dist/{workspace-Dh7rr7l4.mjs → workspace-Bwit4q9O.mjs} +5 -5
- package/dist/workspace-Bwit4q9O.mjs.map +1 -0
- package/package.json +13 -13
- package/dist/config-BEJYKd4s.cjs +0 -648
- package/dist/config-BEJYKd4s.cjs.map +0 -1
- package/dist/config-LKKCVCnC.mjs +0 -547
- package/dist/config-LKKCVCnC.mjs.map +0 -1
- package/dist/define-CHBIEc5j.mjs.map +0 -1
- package/dist/define-Cv_QvDrg.cjs.map +0 -1
- package/dist/discover-BaT6bpnA.mjs.map +0 -1
- package/dist/discover-C_6COHEv.cjs.map +0 -1
- package/dist/home-DOzBaWaL.cjs +0 -33
- package/dist/home-DOzBaWaL.cjs.map +0 -1
- package/dist/home-GI7pJl1M.mjs +0 -22
- package/dist/home-GI7pJl1M.mjs.map +0 -1
- package/dist/resolve-B1T0hUaR.mjs.map +0 -1
- package/dist/resolve-xytBTtG4.cjs.map +0 -1
- package/dist/sniffer-D_SYc_pO.cjs.map +0 -1
- package/dist/sniffer-aO_-s5vq.mjs.map +0 -1
- package/dist/terminal-D0f1u0LG.cjs.map +0 -1
- package/dist/terminal-gMxAo9Dj.mjs.map +0 -1
- package/dist/types-CfLKGfC_.d.mts.map +0 -1
- package/dist/types-DIA7Li-J.d.cts.map +0 -1
- package/dist/workspace-Dh7rr7l4.mjs.map +0 -1
- package/dist/workspace-Kl4NG9IH.cjs.map +0 -1
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
|
|
2
|
+
import { i as CommandFailed, t as LocalSandbox } from "./local-Cd8ZYQG3.mjs";
|
|
3
|
+
import { i as activeSandbox } from "./sandbox-Dm247NGx.mjs";
|
|
4
|
+
import { t as appKey } from "./derive-B4vDpzgP.mjs";
|
|
5
|
+
import { t as defineTarget } from "./define-CYs0PEfZ.mjs";
|
|
6
|
+
import { n as detectPackageManager } from "./utils-D_fxUqvU.mjs";
|
|
7
|
+
import { t as MissingCredential } from "./credentials-s0wMeZBU.mjs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { existsSync } from "node:fs";
|
|
10
|
+
import { readFile, rm } from "node:fs/promises";
|
|
11
|
+
import { kebabCase } from "@geekmidas/manifest";
|
|
12
|
+
//#region src/target/sst/health.ts
|
|
13
|
+
/** Surfaces that never answered healthy. */
|
|
14
|
+
var SurfacesUnhealthy = class extends Error {
|
|
15
|
+
stage;
|
|
16
|
+
surfaces;
|
|
17
|
+
constructor(stage, surfaces) {
|
|
18
|
+
const lines = surfaces.map(({ app, url, status, error }) => ` - ${app}: ${url} → ${status ?? error ?? "no answer"}`);
|
|
19
|
+
super(`The "${stage}" stage was deployed, but ${surfaces.length === 1 ? "a surface does" : "surfaces do"} not answer healthy:\n${lines.join("\n")}\nCheck its logs in CloudWatch, fix it, and deploy again.`);
|
|
20
|
+
this.stage = stage;
|
|
21
|
+
this.surfaces = surfaces;
|
|
22
|
+
this.name = "SurfacesUnhealthy";
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
/** `path` under `base`, keeping any path `base` already has. */
|
|
26
|
+
function healthUrl(base, path) {
|
|
27
|
+
const root = base.endsWith("/") ? base : `${base}/`;
|
|
28
|
+
return new URL(path.replace(/^\//, ""), root).toString();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Ask `url` until it answers 2xx or the attempts run out, emitting
|
|
32
|
+
* `health.checked` for each. Resolves with the last answer.
|
|
33
|
+
*/
|
|
34
|
+
async function checkHealth(app, url, options) {
|
|
35
|
+
let last = { healthy: false };
|
|
36
|
+
for (let attempt = 1; attempt <= options.attempts; attempt++) {
|
|
37
|
+
options.signal.throwIfAborted();
|
|
38
|
+
try {
|
|
39
|
+
const response = await fetch(url, {
|
|
40
|
+
redirect: "follow",
|
|
41
|
+
signal: AbortSignal.any([options.signal, AbortSignal.timeout(options.timeoutMs)])
|
|
42
|
+
});
|
|
43
|
+
await response.arrayBuffer().catch(() => void 0);
|
|
44
|
+
last = {
|
|
45
|
+
healthy: response.ok,
|
|
46
|
+
status: response.status
|
|
47
|
+
};
|
|
48
|
+
} catch (error) {
|
|
49
|
+
options.signal.throwIfAborted();
|
|
50
|
+
last = {
|
|
51
|
+
healthy: false,
|
|
52
|
+
error: error instanceof Error ? error.message : String(error)
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
options.emit({
|
|
56
|
+
type: "health.checked",
|
|
57
|
+
app,
|
|
58
|
+
url,
|
|
59
|
+
healthy: last.healthy,
|
|
60
|
+
...last.status !== void 0 ? { status: last.status } : {},
|
|
61
|
+
attempt
|
|
62
|
+
});
|
|
63
|
+
if (last.healthy) return last;
|
|
64
|
+
if (attempt < options.attempts) await wait(options.delayMs, options.signal);
|
|
65
|
+
}
|
|
66
|
+
return last;
|
|
67
|
+
}
|
|
68
|
+
function wait(ms, signal) {
|
|
69
|
+
if (ms <= 0) return Promise.resolve();
|
|
70
|
+
return new Promise((resolve, reject) => {
|
|
71
|
+
const timer = setTimeout(() => {
|
|
72
|
+
signal.removeEventListener("abort", stop);
|
|
73
|
+
resolve();
|
|
74
|
+
}, ms);
|
|
75
|
+
const stop = () => {
|
|
76
|
+
clearTimeout(timer);
|
|
77
|
+
reject(signal.reason);
|
|
78
|
+
};
|
|
79
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/target/sst/outputs.ts
|
|
84
|
+
/**
|
|
85
|
+
* The surface URLs an `sst deploy` reports.
|
|
86
|
+
*
|
|
87
|
+
* SST writes whatever `run()` in `sst.config.ts` returns to
|
|
88
|
+
* `.sst/outputs.json` after every successful deploy — `{"Api": "https://…"}`.
|
|
89
|
+
* What `run()` returns is the project's to write, so this reads it leniently:
|
|
90
|
+
* nested objects are walked, anything that is not an http(s) URL is ignored,
|
|
91
|
+
* and an output names a surface by its id in any casing, with or without a
|
|
92
|
+
* `Url` suffix (`Api`, `api`, `ApiUrl`, `API_URL`, `Api.url`).
|
|
93
|
+
*/
|
|
94
|
+
/** Where SST leaves the last successful deploy's outputs, under the project. */
|
|
95
|
+
const SST_OUTPUTS_FILE = join(".sst", "outputs.json");
|
|
96
|
+
/** `.sst/outputs.json` is there, and is not JSON. */
|
|
97
|
+
var SstOutputsUnreadable = class extends Error {
|
|
98
|
+
path;
|
|
99
|
+
reason;
|
|
100
|
+
constructor(path, reason) {
|
|
101
|
+
super(`Could not read SST's outputs at ${path}: ${reason}. It is rewritten by every successful \`sst deploy\`; delete it and deploy again.`);
|
|
102
|
+
this.path = path;
|
|
103
|
+
this.reason = reason;
|
|
104
|
+
this.name = "SstOutputsUnreadable";
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Remove what an earlier deploy wrote, so the outputs read after this one
|
|
109
|
+
* are this one's — not another stage's, deployed from the same checkout.
|
|
110
|
+
*/
|
|
111
|
+
async function clearOutputs(cwd) {
|
|
112
|
+
await rm(join(cwd, SST_OUTPUTS_FILE), { force: true });
|
|
113
|
+
}
|
|
114
|
+
/** The deploy's outputs, or `{}` when it wrote none. */
|
|
115
|
+
async function readOutputs(cwd) {
|
|
116
|
+
const path = join(cwd, SST_OUTPUTS_FILE);
|
|
117
|
+
if (!existsSync(path)) return {};
|
|
118
|
+
try {
|
|
119
|
+
return JSON.parse(await readFile(path, "utf8"));
|
|
120
|
+
} catch (error) {
|
|
121
|
+
throw new SstOutputsUnreadable(path, error instanceof Error ? error.message : String(error));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** Every http(s) URL in `outputs`, by its key path: `['Api', 'url']`. */
|
|
125
|
+
function urlsIn(value, path = [], found = []) {
|
|
126
|
+
if (typeof value === "string") {
|
|
127
|
+
if (isHttpUrl(value)) found.push({
|
|
128
|
+
path,
|
|
129
|
+
url: value
|
|
130
|
+
});
|
|
131
|
+
} else if (value && typeof value === "object" && !Array.isArray(value)) for (const [key, child] of Object.entries(value)) urlsIn(child, [...path, key], found);
|
|
132
|
+
return found;
|
|
133
|
+
}
|
|
134
|
+
function isHttpUrl(value) {
|
|
135
|
+
try {
|
|
136
|
+
const { protocol } = new URL(value);
|
|
137
|
+
return protocol === "http:" || protocol === "https:";
|
|
138
|
+
} catch {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The app an output's key path names, kebab-cased as app keys are: its last
|
|
144
|
+
* segment, without a `url` suffix — or its parent's, when the last segment
|
|
145
|
+
* is only `url`. Exact names are tried first, so an app called `api-url`
|
|
146
|
+
* still finds `ApiUrl`.
|
|
147
|
+
*/
|
|
148
|
+
function namesOf(path) {
|
|
149
|
+
const names = [];
|
|
150
|
+
for (const segment of [...path].reverse()) {
|
|
151
|
+
const name = kebabCase(segment);
|
|
152
|
+
names.push(name);
|
|
153
|
+
const bare = name.replace(/-?url$/, "");
|
|
154
|
+
if (bare) {
|
|
155
|
+
names.push(bare);
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return names;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Each app's URL from the outputs, for the apps given. An app no output
|
|
163
|
+
* names is left out.
|
|
164
|
+
*/
|
|
165
|
+
function surfaceUrls(outputs, apps) {
|
|
166
|
+
const found = urlsIn(outputs);
|
|
167
|
+
const urls = {};
|
|
168
|
+
for (const app of apps) {
|
|
169
|
+
const exact = found.find(({ path }) => namesOf(path)[0] === app);
|
|
170
|
+
const loose = found.find(({ path }) => namesOf(path).includes(app));
|
|
171
|
+
const match = exact ?? loose;
|
|
172
|
+
if (match) urls[app] = match.url;
|
|
173
|
+
}
|
|
174
|
+
return urls;
|
|
175
|
+
}
|
|
176
|
+
//#endregion
|
|
177
|
+
//#region src/target/sst/index.ts
|
|
178
|
+
/**
|
|
179
|
+
* The built-in `sst` target: `gkm build` writes the manifest, `sst deploy`
|
|
180
|
+
* provisions it, and the surfaces SST reports are health-checked.
|
|
181
|
+
*
|
|
182
|
+
* `@geekmidas/cloud` is unchanged by it: `sst.config.ts` still reads
|
|
183
|
+
* `.gkm/manifest/aws.ts` and `fromManifest` still makes every resource. What
|
|
184
|
+
* the target adds is the run around the two commands — the lock, the events,
|
|
185
|
+
* verification, and credentials kept where they belong.
|
|
186
|
+
*
|
|
187
|
+
* Both commands run in the sandbox: the build executes the project's code,
|
|
188
|
+
* and so does `sst deploy`, which evaluates `sst.config.ts`. Only the second
|
|
189
|
+
* needs AWS, so the AWS credential goes into that one command's environment
|
|
190
|
+
* and nowhere else — not the build's, not the process the deploy runs in.
|
|
191
|
+
* What `sst deploy` needs beyond them, the sandbox already passes: `PATH`
|
|
192
|
+
* for node and the package manager, and `HOME`, under which SST keeps its
|
|
193
|
+
* toolchain (`~/.config/sst`: bun, pulumi and its plugins) and the AWS SDK
|
|
194
|
+
* finds `~/.aws` for a profile. Its state — the Pulumi backend and the
|
|
195
|
+
* passphrase — is in the stage's own account, reached with that credential.
|
|
196
|
+
*/
|
|
197
|
+
var sst_exports = /* @__PURE__ */ __exportAll({
|
|
198
|
+
SstConfigNotFound: () => SstConfigNotFound,
|
|
199
|
+
awsEnv: () => awsEnv,
|
|
200
|
+
createSstTarget: () => createSstTarget,
|
|
201
|
+
projectCommand: () => projectCommand,
|
|
202
|
+
sstTarget: () => sstTarget
|
|
203
|
+
});
|
|
204
|
+
/** A cold build of every handler and site. */
|
|
205
|
+
const BUILD_TIMEOUT_MS = 18e5;
|
|
206
|
+
/**
|
|
207
|
+
* A first deploy creates CloudFront distributions and, with a database, a
|
|
208
|
+
* VPC and an RDS instance — each of which alone can take a quarter of an hour.
|
|
209
|
+
*/
|
|
210
|
+
const DEPLOY_TIMEOUT_MS = 54e5;
|
|
211
|
+
/** The workspace has no `sst.config.ts` for `sst deploy` to run. */
|
|
212
|
+
var SstConfigNotFound = class extends Error {
|
|
213
|
+
cwd;
|
|
214
|
+
constructor(cwd) {
|
|
215
|
+
super(`No sst.config.ts in ${cwd}. The sst target runs \`sst deploy\` at the workspace root: scaffold one with \`gkm init --deploy sst\` and copy its sst.config.ts, or deploy through another target with --target.`);
|
|
216
|
+
this.cwd = cwd;
|
|
217
|
+
this.name = "SstConfigNotFound";
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* The project's own copy of `bin`, through its package manager — never one
|
|
222
|
+
* `npx` would download, which would be code nobody installed.
|
|
223
|
+
*/
|
|
224
|
+
function projectCommand(pm, bin, args) {
|
|
225
|
+
switch (pm) {
|
|
226
|
+
case "pnpm": return ["pnpm", [
|
|
227
|
+
"exec",
|
|
228
|
+
bin,
|
|
229
|
+
...args
|
|
230
|
+
]];
|
|
231
|
+
case "yarn": return ["yarn", [bin, ...args]];
|
|
232
|
+
case "bun": return ["bunx", [bin, ...args]];
|
|
233
|
+
case "npm": return ["npx", [
|
|
234
|
+
"--no-install",
|
|
235
|
+
bin,
|
|
236
|
+
...args
|
|
237
|
+
]];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* The variables `credential` is to the AWS SDK and to SST.
|
|
242
|
+
*
|
|
243
|
+
* A profile is passed alone: given keys too, every SDK would take the keys.
|
|
244
|
+
*/
|
|
245
|
+
function awsEnv(credential) {
|
|
246
|
+
const region = credential.region ? {
|
|
247
|
+
AWS_REGION: credential.region,
|
|
248
|
+
AWS_DEFAULT_REGION: credential.region
|
|
249
|
+
} : {};
|
|
250
|
+
if ("profile" in credential) return {
|
|
251
|
+
AWS_PROFILE: credential.profile,
|
|
252
|
+
...region
|
|
253
|
+
};
|
|
254
|
+
return {
|
|
255
|
+
AWS_ACCESS_KEY_ID: credential.accessKeyId,
|
|
256
|
+
AWS_SECRET_ACCESS_KEY: credential.secretAccessKey,
|
|
257
|
+
...credential.sessionToken ? { AWS_SESSION_TOKEN: credential.sessionToken } : {},
|
|
258
|
+
...region
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* `env` without any `AWS_*`, so a host sandbox that passes some cannot put
|
|
263
|
+
* a second account beside the one the credential names.
|
|
264
|
+
*/
|
|
265
|
+
function withoutAws(env) {
|
|
266
|
+
return Object.fromEntries(Object.entries(env).filter(([name]) => !name.startsWith("AWS_")));
|
|
267
|
+
}
|
|
268
|
+
/** Each app's kind in the manifest, by app key: `rest-api` or `site`. */
|
|
269
|
+
function kindsOf(manifest) {
|
|
270
|
+
return new Map(Object.entries(manifest).map(([id, declaration]) => [appKey(id), declaration.kind]));
|
|
271
|
+
}
|
|
272
|
+
async function exec(ctx, run, [command, args], options) {
|
|
273
|
+
const result = await run.sandbox.exec(command, args, {
|
|
274
|
+
cwd: ctx.cwd,
|
|
275
|
+
env: options.env,
|
|
276
|
+
timeoutMs: options.timeoutMs,
|
|
277
|
+
output: ctx.childOutput,
|
|
278
|
+
signal: ctx.signal
|
|
279
|
+
});
|
|
280
|
+
if (result.exitCode !== 0) throw new CommandFailed(command, args, result.exitCode, result.signal);
|
|
281
|
+
}
|
|
282
|
+
/** The `sst` target, with its health checks tuned — for tests and hosts. */
|
|
283
|
+
function createSstTarget(options = {}) {
|
|
284
|
+
const health = {
|
|
285
|
+
attempts: options.health?.attempts ?? 6,
|
|
286
|
+
delayMs: options.health?.delayMs ?? 5e3,
|
|
287
|
+
timeoutMs: options.health?.timeoutMs ?? 1e4
|
|
288
|
+
};
|
|
289
|
+
return defineTarget({
|
|
290
|
+
name: "sst",
|
|
291
|
+
runtime: "aws",
|
|
292
|
+
capabilities: {
|
|
293
|
+
rollback: false,
|
|
294
|
+
migrations: "target",
|
|
295
|
+
images: false
|
|
296
|
+
},
|
|
297
|
+
credentials: ["aws"],
|
|
298
|
+
async validate(ctx) {
|
|
299
|
+
if (!existsSync(join(ctx.cwd, "sst.config.ts"))) throw new SstConfigNotFound(ctx.cwd);
|
|
300
|
+
const aws = await ctx.credentials.get({
|
|
301
|
+
kind: "aws",
|
|
302
|
+
stage: ctx.stage
|
|
303
|
+
}, { signal: ctx.signal });
|
|
304
|
+
if (!aws) throw new MissingCredential("aws", ctx.stage);
|
|
305
|
+
if (!("profile" in aws)) {
|
|
306
|
+
ctx.secrets.mask(aws.secretAccessKey);
|
|
307
|
+
if (aws.sessionToken) ctx.secrets.mask(aws.sessionToken);
|
|
308
|
+
}
|
|
309
|
+
for (const app of ctx.apps) if (ctx.workspace.apps[app]?.type === "mobile") ctx.skip(app, "mobile apps deploy through their own toolchain");
|
|
310
|
+
const skipped = new Set(ctx.skipped.map(({ app }) => app));
|
|
311
|
+
const apps = ctx.apps.filter((app) => !skipped.has(app));
|
|
312
|
+
ctx.logger.info(`\n🚀 Deploying "${ctx.workspace.name}" to the "${ctx.stage}" stage with SST`);
|
|
313
|
+
ctx.logger.info(` AWS: ${"profile" in aws ? `profile "${aws.profile}"` : "access keys"}`);
|
|
314
|
+
const deployable = Object.values(ctx.workspace.apps).filter((app) => app.type !== "mobile").length;
|
|
315
|
+
if (apps.length < deployable) ctx.logger.warn(` sst deploy deploys every construct of the stage, not only ${apps.join(", ")}.`);
|
|
316
|
+
return {
|
|
317
|
+
sandbox: activeSandbox() ?? new LocalSandbox({ root: ctx.cwd }),
|
|
318
|
+
pm: detectPackageManager(ctx.cwd),
|
|
319
|
+
aws,
|
|
320
|
+
apps,
|
|
321
|
+
urls: {}
|
|
322
|
+
};
|
|
323
|
+
},
|
|
324
|
+
async plan(ctx, run) {
|
|
325
|
+
const kinds = kindsOf(ctx.manifest);
|
|
326
|
+
for (const app of run.apps) ctx.emit({
|
|
327
|
+
type: "resource.planned",
|
|
328
|
+
key: `application:${app}`,
|
|
329
|
+
resourceType: kinds.get(app) ?? "application",
|
|
330
|
+
action: "ensure"
|
|
331
|
+
});
|
|
332
|
+
const [build, buildArgs] = buildCommand(ctx, run);
|
|
333
|
+
const [deploy, deployArgs] = deployCommand(ctx, run);
|
|
334
|
+
ctx.logger.info(` Would run: ${[build, ...buildArgs].join(" ")}`);
|
|
335
|
+
ctx.logger.info(` Would run: ${[deploy, ...deployArgs].join(" ")}`);
|
|
336
|
+
},
|
|
337
|
+
async build(ctx, run) {
|
|
338
|
+
ctx.logger.info("\n📦 Building the manifest SST deploys");
|
|
339
|
+
await exec(ctx, run, buildCommand(ctx, run), {
|
|
340
|
+
env: { ...run.sandbox.env },
|
|
341
|
+
timeoutMs: BUILD_TIMEOUT_MS
|
|
342
|
+
});
|
|
343
|
+
},
|
|
344
|
+
async release(ctx, run) {
|
|
345
|
+
ctx.logger.info(`\n☁️ sst deploy --stage ${ctx.stage}`);
|
|
346
|
+
await clearOutputs(ctx.cwd);
|
|
347
|
+
await exec(ctx, run, deployCommand(ctx, run), {
|
|
348
|
+
env: {
|
|
349
|
+
...withoutAws(run.sandbox.env),
|
|
350
|
+
...awsEnv(run.aws)
|
|
351
|
+
},
|
|
352
|
+
timeoutMs: DEPLOY_TIMEOUT_MS
|
|
353
|
+
});
|
|
354
|
+
run.urls = surfaceUrls(await readOutputs(ctx.cwd), run.apps);
|
|
355
|
+
for (const app of run.apps) ctx.emit({
|
|
356
|
+
type: "app.deployed",
|
|
357
|
+
app,
|
|
358
|
+
applicationId: ctx.name(app),
|
|
359
|
+
imageRef: "",
|
|
360
|
+
url: run.urls[app] ?? ""
|
|
361
|
+
});
|
|
362
|
+
},
|
|
363
|
+
async verify(ctx, run) {
|
|
364
|
+
const unhealthy = [];
|
|
365
|
+
for (const app of run.apps) {
|
|
366
|
+
const base = run.urls[app];
|
|
367
|
+
if (!base) {
|
|
368
|
+
ctx.logger.warn(` ⚠ No URL for ${app} in SST's outputs, so it was not checked. Return it from run() in sst.config.ts — { ${app}: <its url> } — to have it checked.`);
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
const url = healthUrl(base, ctx.workspace.apps[app]?.type === "backend" ? "/health" : "/");
|
|
372
|
+
const answer = await checkHealth(app, url, {
|
|
373
|
+
...health,
|
|
374
|
+
signal: ctx.signal,
|
|
375
|
+
emit: ctx.emit
|
|
376
|
+
});
|
|
377
|
+
if (answer.healthy) ctx.logger.info(` ✓ ${app}: ${url}`);
|
|
378
|
+
else unhealthy.push({
|
|
379
|
+
app,
|
|
380
|
+
url,
|
|
381
|
+
...answer.status !== void 0 ? { status: answer.status } : {},
|
|
382
|
+
...answer.error ? { error: answer.error } : {}
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
if (unhealthy.length > 0) throw new SurfacesUnhealthy(ctx.stage, unhealthy);
|
|
386
|
+
},
|
|
387
|
+
result(ctx, run) {
|
|
388
|
+
return {
|
|
389
|
+
apps: run.apps.map((appName) => ({
|
|
390
|
+
appName,
|
|
391
|
+
type: ctx.workspace.apps[appName]?.type ?? "backend",
|
|
392
|
+
success: true,
|
|
393
|
+
...run.urls[appName] ? { url: run.urls[appName] } : {}
|
|
394
|
+
})),
|
|
395
|
+
projectId: "",
|
|
396
|
+
environmentId: "",
|
|
397
|
+
successCount: ctx.dryRun ? 0 : run.apps.length,
|
|
398
|
+
failedCount: 0,
|
|
399
|
+
stage: ctx.stage,
|
|
400
|
+
identity: ctx.identity.key,
|
|
401
|
+
tag: ctx.tag,
|
|
402
|
+
dryRun: ctx.dryRun,
|
|
403
|
+
skipped: [...ctx.skipped],
|
|
404
|
+
urls: { ...run.urls },
|
|
405
|
+
changes: []
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
function buildCommand(ctx, run) {
|
|
411
|
+
return projectCommand(run.pm, "gkm", [
|
|
412
|
+
"build",
|
|
413
|
+
"--provider",
|
|
414
|
+
"aws",
|
|
415
|
+
"--stage",
|
|
416
|
+
ctx.stage
|
|
417
|
+
]);
|
|
418
|
+
}
|
|
419
|
+
function deployCommand(ctx, run) {
|
|
420
|
+
return projectCommand(run.pm, "sst", [
|
|
421
|
+
"deploy",
|
|
422
|
+
"--stage",
|
|
423
|
+
ctx.stage
|
|
424
|
+
]);
|
|
425
|
+
}
|
|
426
|
+
const sstTarget = createSstTarget();
|
|
427
|
+
//#endregion
|
|
428
|
+
export { SurfacesUnhealthy as i, sst_exports as n, SstOutputsUnreadable as r, SstConfigNotFound as t };
|
|
429
|
+
|
|
430
|
+
//# sourceMappingURL=sst-Cper040I.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sst-Cper040I.mjs","names":[],"sources":["../src/target/sst/health.ts","../src/target/sst/outputs.ts","../src/target/sst/index.ts"],"sourcesContent":["/**\n * Whether a released surface answers.\n *\n * The paths are the ones the local stack's healthchecks use\n * (`reconcile/apps.ts`): an API's `/health`, a site's `/`. A surface is\n * asked a few times, because a fresh deploy can take a moment to answer — a\n * Lambda's first start, a distribution still settling — and healthy means a\n * 2xx, after redirects.\n */\n\nimport type { TargetEvent } from '../types';\n\nexport interface HealthCheckOptions {\n\t/** How many times a surface is asked before it counts as down. */\n\tattempts: number;\n\t/** The wait between two attempts. */\n\tdelayMs: number;\n\t/** How long one request may take. */\n\ttimeoutMs: number;\n\tsignal: AbortSignal;\n\temit: (event: TargetEvent) => void;\n}\n\n/** Surfaces that never answered healthy. */\nexport class SurfacesUnhealthy extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** Each surface that failed, with the last thing it answered. */\n\t\treadonly surfaces: readonly {\n\t\t\tapp: string;\n\t\t\turl: string;\n\t\t\tstatus?: number;\n\t\t\terror?: string;\n\t\t}[],\n\t) {\n\t\tconst lines = surfaces.map(\n\t\t\t({ app, url, status, error }) =>\n\t\t\t\t` - ${app}: ${url} → ${status ?? error ?? 'no answer'}`,\n\t\t);\n\t\tsuper(\n\t\t\t`The \"${stage}\" stage was deployed, but ${surfaces.length === 1 ? 'a surface does' : 'surfaces do'} not answer healthy:\\n${lines.join('\\n')}\\nCheck its logs in CloudWatch, fix it, and deploy again.`,\n\t\t);\n\t\tthis.name = 'SurfacesUnhealthy';\n\t}\n}\n\n/** `path` under `base`, keeping any path `base` already has. */\nexport function healthUrl(base: string, path: string): string {\n\tconst root = base.endsWith('/') ? base : `${base}/`;\n\treturn new URL(path.replace(/^\\//, ''), root).toString();\n}\n\n/**\n * Ask `url` until it answers 2xx or the attempts run out, emitting\n * `health.checked` for each. Resolves with the last answer.\n */\nexport async function checkHealth(\n\tapp: string,\n\turl: string,\n\toptions: HealthCheckOptions,\n): Promise<{ healthy: boolean; status?: number; error?: string }> {\n\tlet last: { healthy: boolean; status?: number; error?: string } = {\n\t\thealthy: false,\n\t};\n\tfor (let attempt = 1; attempt <= options.attempts; attempt++) {\n\t\toptions.signal.throwIfAborted();\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tredirect: 'follow',\n\t\t\t\tsignal: AbortSignal.any([\n\t\t\t\t\toptions.signal,\n\t\t\t\t\tAbortSignal.timeout(options.timeoutMs),\n\t\t\t\t]),\n\t\t\t});\n\t\t\t// Drained, so the connection is not held open by an unread body.\n\t\t\tawait response.arrayBuffer().catch(() => undefined);\n\t\t\tlast = { healthy: response.ok, status: response.status };\n\t\t} catch (error) {\n\t\t\t// The run being stopped is not the surface being down.\n\t\t\toptions.signal.throwIfAborted();\n\t\t\tlast = {\n\t\t\t\thealthy: false,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t}\n\t\toptions.emit({\n\t\t\ttype: 'health.checked',\n\t\t\tapp,\n\t\t\turl,\n\t\t\thealthy: last.healthy,\n\t\t\t...(last.status !== undefined ? { status: last.status } : {}),\n\t\t\tattempt,\n\t\t});\n\t\tif (last.healthy) return last;\n\t\tif (attempt < options.attempts) await wait(options.delayMs, options.signal);\n\t}\n\treturn last;\n}\n\nfunction wait(ms: number, signal: AbortSignal): Promise<void> {\n\tif (ms <= 0) return Promise.resolve();\n\treturn new Promise((resolve, reject) => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tsignal.removeEventListener('abort', stop);\n\t\t\tresolve();\n\t\t}, ms);\n\t\tconst stop = () => {\n\t\t\tclearTimeout(timer);\n\t\t\treject(signal.reason);\n\t\t};\n\t\tsignal.addEventListener('abort', stop, { once: true });\n\t});\n}\n","/**\n * The surface URLs an `sst deploy` reports.\n *\n * SST writes whatever `run()` in `sst.config.ts` returns to\n * `.sst/outputs.json` after every successful deploy — `{\"Api\": \"https://…\"}`.\n * What `run()` returns is the project's to write, so this reads it leniently:\n * nested objects are walked, anything that is not an http(s) URL is ignored,\n * and an output names a surface by its id in any casing, with or without a\n * `Url` suffix (`Api`, `api`, `ApiUrl`, `API_URL`, `Api.url`).\n */\n\nimport { existsSync } from 'node:fs';\nimport { readFile, rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { kebabCase } from '@geekmidas/manifest';\n\n/** Where SST leaves the last successful deploy's outputs, under the project. */\nexport const SST_OUTPUTS_FILE = join('.sst', 'outputs.json');\n\n/** `.sst/outputs.json` is there, and is not JSON. */\nexport class SstOutputsUnreadable extends Error {\n\tconstructor(\n\t\treadonly path: string,\n\t\treadonly reason: string,\n\t) {\n\t\tsuper(\n\t\t\t`Could not read SST's outputs at ${path}: ${reason}. It is rewritten by every successful \\`sst deploy\\`; delete it and deploy again.`,\n\t\t);\n\t\tthis.name = 'SstOutputsUnreadable';\n\t}\n}\n\n/**\n * Remove what an earlier deploy wrote, so the outputs read after this one\n * are this one's — not another stage's, deployed from the same checkout.\n */\nexport async function clearOutputs(cwd: string): Promise<void> {\n\tawait rm(join(cwd, SST_OUTPUTS_FILE), { force: true });\n}\n\n/** The deploy's outputs, or `{}` when it wrote none. */\nexport async function readOutputs(cwd: string): Promise<unknown> {\n\tconst path = join(cwd, SST_OUTPUTS_FILE);\n\tif (!existsSync(path)) return {};\n\ttry {\n\t\treturn JSON.parse(await readFile(path, 'utf8'));\n\t} catch (error) {\n\t\tthrow new SstOutputsUnreadable(\n\t\t\tpath,\n\t\t\terror instanceof Error ? error.message : String(error),\n\t\t);\n\t}\n}\n\n/** Every http(s) URL in `outputs`, by its key path: `['Api', 'url']`. */\nfunction urlsIn(\n\tvalue: unknown,\n\tpath: string[] = [],\n\tfound: { path: string[]; url: string }[] = [],\n): { path: string[]; url: string }[] {\n\tif (typeof value === 'string') {\n\t\tif (isHttpUrl(value)) found.push({ path, url: value });\n\t} else if (value && typeof value === 'object' && !Array.isArray(value)) {\n\t\tfor (const [key, child] of Object.entries(value)) {\n\t\t\turlsIn(child, [...path, key], found);\n\t\t}\n\t}\n\treturn found;\n}\n\nfunction isHttpUrl(value: string): boolean {\n\ttry {\n\t\tconst { protocol } = new URL(value);\n\t\treturn protocol === 'http:' || protocol === 'https:';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * The app an output's key path names, kebab-cased as app keys are: its last\n * segment, without a `url` suffix — or its parent's, when the last segment\n * is only `url`. Exact names are tried first, so an app called `api-url`\n * still finds `ApiUrl`.\n */\nfunction namesOf(path: string[]): string[] {\n\tconst names: string[] = [];\n\tfor (const segment of [...path].reverse()) {\n\t\tconst name = kebabCase(segment);\n\t\tnames.push(name);\n\t\tconst bare = name.replace(/-?url$/, '');\n\t\tif (bare) {\n\t\t\tnames.push(bare);\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn names;\n}\n\n/**\n * Each app's URL from the outputs, for the apps given. An app no output\n * names is left out.\n */\nexport function surfaceUrls(\n\toutputs: unknown,\n\tapps: readonly string[],\n): Record<string, string> {\n\tconst found = urlsIn(outputs);\n\tconst urls: Record<string, string> = {};\n\tfor (const app of apps) {\n\t\t// An exact name beats a stripped one, wherever each is in the file.\n\t\tconst exact = found.find(({ path }) => namesOf(path)[0] === app);\n\t\tconst loose = found.find(({ path }) => namesOf(path).includes(app));\n\t\tconst match = exact ?? loose;\n\t\tif (match) urls[app] = match.url;\n\t}\n\treturn urls;\n}\n","/**\n * The built-in `sst` target: `gkm build` writes the manifest, `sst deploy`\n * provisions it, and the surfaces SST reports are health-checked.\n *\n * `@geekmidas/cloud` is unchanged by it: `sst.config.ts` still reads\n * `.gkm/manifest/aws.ts` and `fromManifest` still makes every resource. What\n * the target adds is the run around the two commands — the lock, the events,\n * verification, and credentials kept where they belong.\n *\n * Both commands run in the sandbox: the build executes the project's code,\n * and so does `sst deploy`, which evaluates `sst.config.ts`. Only the second\n * needs AWS, so the AWS credential goes into that one command's environment\n * and nowhere else — not the build's, not the process the deploy runs in.\n * What `sst deploy` needs beyond them, the sandbox already passes: `PATH`\n * for node and the package manager, and `HOME`, under which SST keeps its\n * toolchain (`~/.config/sst`: bun, pulumi and its plugins) and the AWS SDK\n * finds `~/.aws` for a profile. Its state — the Pulumi backend and the\n * passphrase — is in the stage's own account, reached with that credential.\n */\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport {\n\ttype AwsCredential,\n\tMissingCredential,\n} from '../../deploy/credentials';\nimport type { DeployResult } from '../../deploy/types';\nimport { detectPackageManager, type PackageManager } from '../../init/utils';\nimport { CommandFailed } from '../../run';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { activeSandbox, type Sandbox } from '../../sandbox/sandbox';\nimport { appKey } from '../../workspace/derive';\nimport { defineTarget } from '../define';\nimport type { DeployPhaseContext, DeployTarget } from '../types';\nimport { checkHealth, healthUrl, SurfacesUnhealthy } from './health';\nimport { clearOutputs, readOutputs, surfaceUrls } from './outputs';\n\nexport { SurfacesUnhealthy } from './health';\nexport { SST_OUTPUTS_FILE, SstOutputsUnreadable } from './outputs';\n\n/** A cold build of every handler and site. */\nconst BUILD_TIMEOUT_MS = 30 * 60_000;\n/**\n * A first deploy creates CloudFront distributions and, with a database, a\n * VPC and an RDS instance — each of which alone can take a quarter of an hour.\n */\nconst DEPLOY_TIMEOUT_MS = 90 * 60_000;\n\n/** The workspace has no `sst.config.ts` for `sst deploy` to run. */\nexport class SstConfigNotFound extends Error {\n\tconstructor(readonly cwd: string) {\n\t\tsuper(\n\t\t\t`No sst.config.ts in ${cwd}. The sst target runs \\`sst deploy\\` at the workspace root: scaffold one with \\`gkm init --deploy sst\\` and copy its sst.config.ts, or deploy through another target with --target.`,\n\t\t);\n\t\tthis.name = 'SstConfigNotFound';\n\t}\n}\n\n/** What the phases hand on. */\nexport interface SstRun {\n\tsandbox: Sandbox;\n\tpm: PackageManager;\n\taws: AwsCredential;\n\t/** The apps SST deploys this run: `ctx.apps` without the skipped. */\n\tapps: string[];\n\t/** Each app's URL, from the deploy's outputs. */\n\turls: Record<string, string>;\n}\n\nexport interface SstTargetOptions {\n\t/** How often, and how patiently, `verify` asks each surface. */\n\thealth?: { attempts?: number; delayMs?: number; timeoutMs?: number };\n}\n\n/**\n * The project's own copy of `bin`, through its package manager — never one\n * `npx` would download, which would be code nobody installed.\n */\nexport function projectCommand(\n\tpm: PackageManager,\n\tbin: string,\n\targs: readonly string[],\n): [command: string, args: string[]] {\n\tswitch (pm) {\n\t\tcase 'pnpm':\n\t\t\treturn ['pnpm', ['exec', bin, ...args]];\n\t\tcase 'yarn':\n\t\t\treturn ['yarn', [bin, ...args]];\n\t\tcase 'bun':\n\t\t\treturn ['bunx', [bin, ...args]];\n\t\tcase 'npm':\n\t\t\treturn ['npx', ['--no-install', bin, ...args]];\n\t}\n}\n\n/**\n * The variables `credential` is to the AWS SDK and to SST.\n *\n * A profile is passed alone: given keys too, every SDK would take the keys.\n */\nexport function awsEnv(credential: AwsCredential): Record<string, string> {\n\tconst region: Record<string, string> = credential.region\n\t\t? { AWS_REGION: credential.region, AWS_DEFAULT_REGION: credential.region }\n\t\t: {};\n\tif ('profile' in credential) {\n\t\treturn { AWS_PROFILE: credential.profile, ...region };\n\t}\n\treturn {\n\t\tAWS_ACCESS_KEY_ID: credential.accessKeyId,\n\t\tAWS_SECRET_ACCESS_KEY: credential.secretAccessKey,\n\t\t...(credential.sessionToken\n\t\t\t? { AWS_SESSION_TOKEN: credential.sessionToken }\n\t\t\t: {}),\n\t\t...region,\n\t};\n}\n\n/**\n * `env` without any `AWS_*`, so a host sandbox that passes some cannot put\n * a second account beside the one the credential names.\n */\nfunction withoutAws(\n\tenv: Readonly<Record<string, string>>,\n): Record<string, string> {\n\treturn Object.fromEntries(\n\t\tObject.entries(env).filter(([name]) => !name.startsWith('AWS_')),\n\t);\n}\n\n/** Each app's kind in the manifest, by app key: `rest-api` or `site`. */\nfunction kindsOf(manifest: ConstructManifest): Map<string, string> {\n\treturn new Map(\n\t\tObject.entries(manifest).map(([id, declaration]) => [\n\t\t\tappKey(id),\n\t\t\tdeclaration.kind,\n\t\t]),\n\t);\n}\n\nasync function exec(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n\t[command, args]: [string, string[]],\n\toptions: { env: Record<string, string>; timeoutMs: number },\n): Promise<void> {\n\tconst result = await run.sandbox.exec(command, args, {\n\t\tcwd: ctx.cwd,\n\t\tenv: options.env,\n\t\ttimeoutMs: options.timeoutMs,\n\t\toutput: ctx.childOutput,\n\t\tsignal: ctx.signal,\n\t});\n\tif (result.exitCode !== 0) {\n\t\tthrow new CommandFailed(\n\t\t\tcommand,\n\t\t\targs,\n\t\t\tresult.exitCode,\n\t\t\tresult.signal as NodeJS.Signals | null,\n\t\t);\n\t}\n}\n\n/** The `sst` target, with its health checks tuned — for tests and hosts. */\nexport function createSstTarget(\n\toptions: SstTargetOptions = {},\n): DeployTarget<undefined, SstRun> {\n\tconst health = {\n\t\tattempts: options.health?.attempts ?? 6,\n\t\tdelayMs: options.health?.delayMs ?? 5_000,\n\t\ttimeoutMs: options.health?.timeoutMs ?? 10_000,\n\t};\n\n\treturn defineTarget<undefined, SstRun>({\n\t\tname: 'sst',\n\t\truntime: 'aws',\n\t\t// SST keeps no previous release to return to; migrations run in the\n\t\t// stack, as `fromManifest` provisions the database; and nothing here\n\t\t// builds an image.\n\t\tcapabilities: { rollback: false, migrations: 'target', images: false },\n\t\tcredentials: ['aws'],\n\n\t\tasync validate(ctx) {\n\t\t\tif (!existsSync(join(ctx.cwd, 'sst.config.ts'))) {\n\t\t\t\tthrow new SstConfigNotFound(ctx.cwd);\n\t\t\t}\n\n\t\t\tconst aws = await ctx.credentials.get(\n\t\t\t\t{ kind: 'aws', stage: ctx.stage },\n\t\t\t\t{ signal: ctx.signal },\n\t\t\t);\n\t\t\tif (!aws) throw new MissingCredential('aws', ctx.stage);\n\t\t\tif (!('profile' in aws)) {\n\t\t\t\tctx.secrets.mask(aws.secretAccessKey);\n\t\t\t\tif (aws.sessionToken) ctx.secrets.mask(aws.sessionToken);\n\t\t\t}\n\n\t\t\t// A mobile app ships through its own store's toolchain.\n\t\t\tfor (const app of ctx.apps) {\n\t\t\t\tif (ctx.workspace.apps[app]?.type === 'mobile') {\n\t\t\t\t\tctx.skip(app, 'mobile apps deploy through their own toolchain');\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst skipped = new Set(ctx.skipped.map(({ app }) => app));\n\t\t\tconst apps = ctx.apps.filter((app) => !skipped.has(app));\n\n\t\t\tctx.logger.info(\n\t\t\t\t`\\n🚀 Deploying \"${ctx.workspace.name}\" to the \"${ctx.stage}\" stage with SST`,\n\t\t\t);\n\t\t\tctx.logger.info(\n\t\t\t\t` AWS: ${'profile' in aws ? `profile \"${aws.profile}\"` : 'access keys'}`,\n\t\t\t);\n\t\t\t// `sst deploy` takes the whole stack: there is no deploying one app.\n\t\t\tconst deployable = Object.values(ctx.workspace.apps).filter(\n\t\t\t\t(app) => app.type !== 'mobile',\n\t\t\t).length;\n\t\t\tif (apps.length < deployable) {\n\t\t\t\tctx.logger.warn(\n\t\t\t\t\t` sst deploy deploys every construct of the stage, not only ${apps.join(', ')}.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsandbox: activeSandbox() ?? new LocalSandbox({ root: ctx.cwd }),\n\t\t\t\tpm: detectPackageManager(ctx.cwd),\n\t\t\t\taws,\n\t\t\t\tapps,\n\t\t\t\turls: {},\n\t\t\t};\n\t\t},\n\n\t\tasync plan(ctx, run) {\n\t\t\tconst kinds = kindsOf(ctx.manifest);\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tctx.emit({\n\t\t\t\t\ttype: 'resource.planned',\n\t\t\t\t\tkey: `application:${app}`,\n\t\t\t\t\tresourceType: kinds.get(app) ?? 'application',\n\t\t\t\t\taction: 'ensure',\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst [build, buildArgs] = buildCommand(ctx, run);\n\t\t\tconst [deploy, deployArgs] = deployCommand(ctx, run);\n\t\t\tctx.logger.info(` Would run: ${[build, ...buildArgs].join(' ')}`);\n\t\t\tctx.logger.info(` Would run: ${[deploy, ...deployArgs].join(' ')}`);\n\t\t},\n\n\t\tasync build(ctx, run) {\n\t\t\tctx.logger.info('\\n📦 Building the manifest SST deploys');\n\t\t\t// No credential: the build runs the project's code and needs none.\n\t\t\tawait exec(ctx, run, buildCommand(ctx, run), {\n\t\t\t\tenv: { ...run.sandbox.env },\n\t\t\t\ttimeoutMs: BUILD_TIMEOUT_MS,\n\t\t\t});\n\t\t},\n\n\t\tasync release(ctx, run) {\n\t\t\tctx.logger.info(`\\n☁️ sst deploy --stage ${ctx.stage}`);\n\t\t\tawait clearOutputs(ctx.cwd);\n\t\t\tawait exec(ctx, run, deployCommand(ctx, run), {\n\t\t\t\tenv: { ...withoutAws(run.sandbox.env), ...awsEnv(run.aws) },\n\t\t\t\ttimeoutMs: DEPLOY_TIMEOUT_MS,\n\t\t\t});\n\n\t\t\trun.urls = surfaceUrls(await readOutputs(ctx.cwd), run.apps);\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tctx.emit({\n\t\t\t\t\ttype: 'app.deployed',\n\t\t\t\t\tapp,\n\t\t\t\t\tapplicationId: ctx.name(app),\n\t\t\t\t\t// SST builds no image a registry holds.\n\t\t\t\t\timageRef: '',\n\t\t\t\t\turl: run.urls[app] ?? '',\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\tasync verify(ctx, run) {\n\t\t\tconst unhealthy: SurfacesUnhealthy['surfaces'][number][] = [];\n\n\t\t\tfor (const app of run.apps) {\n\t\t\t\tconst base = run.urls[app];\n\t\t\t\tif (!base) {\n\t\t\t\t\tctx.logger.warn(\n\t\t\t\t\t\t` ⚠ No URL for ${app} in SST's outputs, so it was not checked. Return it from run() in sst.config.ts — { ${app}: <its url> } — to have it checked.`,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// A surface — a `rest-api` — is the backend app it derives.\n\t\t\t\tconst backend = ctx.workspace.apps[app]?.type === 'backend';\n\t\t\t\tconst url = healthUrl(base, backend ? '/health' : '/');\n\t\t\t\tconst answer = await checkHealth(app, url, {\n\t\t\t\t\t...health,\n\t\t\t\t\tsignal: ctx.signal,\n\t\t\t\t\temit: ctx.emit,\n\t\t\t\t});\n\t\t\t\tif (answer.healthy) {\n\t\t\t\t\tctx.logger.info(` ✓ ${app}: ${url}`);\n\t\t\t\t} else {\n\t\t\t\t\tunhealthy.push({\n\t\t\t\t\t\tapp,\n\t\t\t\t\t\turl,\n\t\t\t\t\t\t...(answer.status !== undefined ? { status: answer.status } : {}),\n\t\t\t\t\t\t...(answer.error ? { error: answer.error } : {}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (unhealthy.length > 0) {\n\t\t\t\tthrow new SurfacesUnhealthy(ctx.stage, unhealthy);\n\t\t\t}\n\t\t},\n\n\t\tresult(ctx, run): DeployResult {\n\t\t\treturn {\n\t\t\t\tapps: run.apps.map((appName) => ({\n\t\t\t\t\tappName,\n\t\t\t\t\ttype: ctx.workspace.apps[appName]?.type ?? 'backend',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\t...(run.urls[appName] ? { url: run.urls[appName] } : {}),\n\t\t\t\t})),\n\t\t\t\tprojectId: '',\n\t\t\t\tenvironmentId: '',\n\t\t\t\tsuccessCount: ctx.dryRun ? 0 : run.apps.length,\n\t\t\t\tfailedCount: 0,\n\t\t\t\tstage: ctx.stage,\n\t\t\t\tidentity: ctx.identity.key,\n\t\t\t\ttag: ctx.tag,\n\t\t\t\tdryRun: ctx.dryRun,\n\t\t\t\tskipped: [...ctx.skipped],\n\t\t\t\turls: { ...run.urls },\n\t\t\t\tchanges: [],\n\t\t\t};\n\t\t},\n\t});\n}\n\nfunction buildCommand(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n): [string, string[]] {\n\treturn projectCommand(run.pm, 'gkm', [\n\t\t'build',\n\t\t'--provider',\n\t\t'aws',\n\t\t'--stage',\n\t\tctx.stage,\n\t]);\n}\n\nfunction deployCommand(\n\tctx: DeployPhaseContext<unknown>,\n\trun: SstRun,\n): [string, string[]] {\n\treturn projectCommand(run.pm, 'sst', ['deploy', '--stage', ctx.stage]);\n}\n\nexport const sstTarget = createSstTarget();\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { y as gkmHome } from "./local-Cd8ZYQG3.mjs";
|
|
3
3
|
import { basename, join } from "node:path";
|
|
4
4
|
import { constants, existsSync, readFileSync } from "node:fs";
|
|
5
5
|
import { chmod, copyFile, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
@@ -412,4 +412,4 @@ function isRemoteStore(workspace, stage) {
|
|
|
412
412
|
//#endregion
|
|
413
413
|
export { getKeyPath as a, readKey as c, imageName as d, imageRef as f, projectName as g, ownershipMarker as h, FileSecretsStore as i, applicationName as l, markerOf as m, secretsStoreFor as n, keystoreProject as o, isOwnedBy as p, store_exports as r, projectKey as s, isRemoteStore as t, deployIdentity as u };
|
|
414
414
|
|
|
415
|
-
//# sourceMappingURL=store-
|
|
415
|
+
//# sourceMappingURL=store-BaaonhkJ.mjs.map
|