@geekmidas/cli 10.0.0-alpha.95 → 10.0.0-alpha.97
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-BwW51hPm.mjs → GoDaddyProvider-AqNu60WQ.mjs} +2 -2
- package/dist/{GoDaddyProvider-BwW51hPm.mjs.map → GoDaddyProvider-AqNu60WQ.mjs.map} +1 -1
- package/dist/{GoDaddyProvider-C_DgIkMv.cjs → GoDaddyProvider-B4R_QFl8.cjs} +2 -2
- package/dist/{GoDaddyProvider-C_DgIkMv.cjs.map → GoDaddyProvider-B4R_QFl8.cjs.map} +1 -1
- package/dist/{LegacyStateStore-D5DarNA2.mjs → LegacyStateStore-8F05-BOo.mjs} +3 -3
- package/dist/{LegacyStateStore-D5DarNA2.mjs.map → LegacyStateStore-8F05-BOo.mjs.map} +1 -1
- package/dist/{LegacyStateStore-BawjE_5n.cjs → LegacyStateStore-B-aRqRdD.cjs} +3 -3
- package/dist/{LegacyStateStore-BawjE_5n.cjs.map → LegacyStateStore-B-aRqRdD.cjs.map} +1 -1
- package/dist/{LocalStateStore-D8fu5WiF.cjs → LocalStateStore-B_bRI8M7.cjs} +2 -2
- package/dist/{LocalStateStore-D8fu5WiF.cjs.map → LocalStateStore-B_bRI8M7.cjs.map} +1 -1
- package/dist/{LocalStateStore-YjIqlgAz.mjs → LocalStateStore-B_mfgcO8.mjs} +2 -2
- package/dist/{LocalStateStore-YjIqlgAz.mjs.map → LocalStateStore-B_mfgcO8.mjs.map} +1 -1
- package/dist/{S3StateStore-CjTAVsWh.mjs → S3StateStore-CMN0Uzdp.mjs} +69 -8
- package/dist/S3StateStore-CMN0Uzdp.mjs.map +1 -0
- package/dist/{S3StateStore-Cm-v2IPI.cjs → S3StateStore-zK9zcd9f.cjs} +69 -8
- package/dist/S3StateStore-zK9zcd9f.cjs.map +1 -0
- package/dist/{SSMStateStore-BS4BiZCN.cjs → SSMStateStore-C489DnR6.cjs} +58 -7
- package/dist/SSMStateStore-C489DnR6.cjs.map +1 -0
- package/dist/{SSMStateStore-BhtM6jOh.mjs → SSMStateStore-Cv7VcMak.mjs} +58 -7
- package/dist/SSMStateStore-Cv7VcMak.mjs.map +1 -0
- package/dist/{add-ylx8dejw.mjs → add-BA5d4pA0.mjs} +4 -4
- package/dist/{add-ylx8dejw.mjs.map → add-BA5d4pA0.mjs.map} +1 -1
- package/dist/{add-D-3IKT7W.cjs → add-HXzTCy_I.cjs} +4 -4
- package/dist/{add-D-3IKT7W.cjs.map → add-HXzTCy_I.cjs.map} +1 -1
- package/dist/{bundler-ywR3C1B_.mjs → bundler-CBomFsnd.mjs} +5 -5
- package/dist/{bundler-ywR3C1B_.mjs.map → bundler-CBomFsnd.mjs.map} +1 -1
- package/dist/{bundler-CI3elfZS.cjs → bundler-SX3Uy8qT.cjs} +5 -5
- package/dist/{bundler-CI3elfZS.cjs.map → bundler-SX3Uy8qT.cjs.map} +1 -1
- package/dist/{cli-Dewt2T21.cjs → cli-1l0L9LCA.cjs} +2 -2
- package/dist/{cli-Dewt2T21.cjs.map → cli-1l0L9LCA.cjs.map} +1 -1
- package/dist/{cli-BCSuCfQk.mjs → cli-D7z1lQtO.mjs} +2 -2
- package/dist/{cli-BCSuCfQk.mjs.map → cli-D7z1lQtO.mjs.map} +1 -1
- package/dist/{compose-Dd0XphvF.cjs → compose-C39XupJu.cjs} +7 -7
- package/dist/{compose-Dd0XphvF.cjs.map → compose-C39XupJu.cjs.map} +1 -1
- package/dist/{compose-C4js1JDv.mjs → compose-DgWrNd2k.mjs} +7 -7
- package/dist/{compose-C4js1JDv.mjs.map → compose-DgWrNd2k.mjs.map} +1 -1
- package/dist/{config-4yirvxS8.d.cts → config-D-k0gaAr.d.mts} +4 -4
- package/dist/{config-4yirvxS8.d.cts.map → config-D-k0gaAr.d.mts.map} +1 -1
- package/dist/{config-C8NPCn1l.d.mts → config-xIWIaDhW.d.cts} +4 -4
- package/dist/{config-C8NPCn1l.d.mts.map → config-xIWIaDhW.d.cts.map} +1 -1
- package/dist/config.cjs +1 -1
- package/dist/config.d.cts +3 -3
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +1 -1
- package/dist/deploy/public.cjs +7 -7
- package/dist/deploy/public.d.cts +5 -5
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts +5 -5
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +7 -7
- package/dist/{deploy-Bw1FjX_x.cjs → deploy-Cu_HyWoJ.cjs} +212 -47
- package/dist/deploy-Cu_HyWoJ.cjs.map +1 -0
- package/dist/{deploy-B0drCD6s.mjs → deploy-LY-20Yeb.mjs} +212 -47
- package/dist/deploy-LY-20Yeb.mjs.map +1 -0
- package/dist/{discover-BtFofyQB.d.cts → discover-CbJCQq4J.d.mts} +2 -2
- package/dist/{discover-BtFofyQB.d.cts.map → discover-CbJCQq4J.d.mts.map} +1 -1
- package/dist/{discover-D-MdXZgm.d.mts → discover-RCW5mBXb.d.cts} +2 -2
- package/dist/{discover-D-MdXZgm.d.mts.map → discover-RCW5mBXb.d.cts.map} +1 -1
- package/dist/{dns-Bmk7P9c2.cjs → dns-BFnoawgh.cjs} +3 -3
- package/dist/{dns-Bmk7P9c2.cjs.map → dns-BFnoawgh.cjs.map} +1 -1
- package/dist/{dns-idXfyCay.mjs → dns-BbTOzmVp.mjs} +3 -3
- package/dist/{dns-idXfyCay.mjs.map → dns-BbTOzmVp.mjs.map} +1 -1
- package/dist/{dns-X3oqEV4C.mjs → dns-Bmbhmz41.mjs} +5 -5
- package/dist/{dns-X3oqEV4C.mjs.map → dns-Bmbhmz41.mjs.map} +1 -1
- package/dist/{dns-CyMIq6to.cjs → dns-Dro_vbk9.cjs} +5 -5
- package/dist/{dns-CyMIq6to.cjs.map → dns-Dro_vbk9.cjs.map} +1 -1
- package/dist/{dokploy-DaT0mgLU.cjs → dokploy-CKgSww82.cjs} +2 -2
- package/dist/{dokploy-DaT0mgLU.cjs.map → dokploy-CKgSww82.cjs.map} +1 -1
- package/dist/{dokploy-CZYxXeMa.mjs → dokploy-LR94sBVI.mjs} +2 -2
- package/dist/{dokploy-CZYxXeMa.mjs.map → dokploy-LR94sBVI.mjs.map} +1 -1
- package/dist/{encryption-D0ucY4O7.mjs → encryption-C0plOf4a.mjs} +3 -3
- package/dist/{encryption-D0ucY4O7.mjs.map → encryption-C0plOf4a.mjs.map} +1 -1
- package/dist/{encryption-Dp0IvLVX.cjs → encryption-CUyw-8sc.cjs} +3 -3
- package/dist/{encryption-Dp0IvLVX.cjs.map → encryption-CUyw-8sc.cjs.map} +1 -1
- package/dist/{engine-WY6j_kvA.cjs → engine-D8TeraDK.cjs} +4 -4
- package/dist/{engine-WY6j_kvA.cjs.map → engine-D8TeraDK.cjs.map} +1 -1
- package/dist/{engine-BcuhnyQO.mjs → engine-DqbqQhck.mjs} +4 -4
- package/dist/{engine-BcuhnyQO.mjs.map → engine-DqbqQhck.mjs.map} +1 -1
- package/dist/{github-DgmW83OP.cjs → github-DC4SIqV1.cjs} +35 -20
- package/dist/github-DC4SIqV1.cjs.map +1 -0
- package/dist/{github-DUGA57du.mjs → github-zgaBOQvh.mjs} +35 -20
- package/dist/github-zgaBOQvh.mjs.map +1 -0
- package/dist/{index-5eL8rM6H.d.mts → index-ClqOsbBl.d.mts} +2 -2
- package/dist/{index-5eL8rM6H.d.mts.map → index-ClqOsbBl.d.mts.map} +1 -1
- package/dist/{index-Dz-gyjm_.d.cts → index-DgOBAEl5.d.cts} +2 -2
- package/dist/{index-Dz-gyjm_.d.cts.map → index-DgOBAEl5.d.cts.map} +1 -1
- package/dist/index.cjs +56 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +56 -52
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-CZ-v5WV0.mjs → migrate-BJ8aLOWk.mjs} +3 -3
- package/dist/{migrate-CZ-v5WV0.mjs.map → migrate-BJ8aLOWk.mjs.map} +1 -1
- package/dist/{migrate-D6PlNv2o.mjs → migrate-C230QeXU.mjs} +3 -3
- package/dist/{migrate-D6PlNv2o.mjs.map → migrate-C230QeXU.mjs.map} +1 -1
- package/dist/{migrate-afgRL3Hg.cjs → migrate-CWq8-s21.cjs} +3 -3
- package/dist/{migrate-afgRL3Hg.cjs.map → migrate-CWq8-s21.cjs.map} +1 -1
- package/dist/{migrate-BBcG1dhS.cjs → migrate-CsMrI7Dk.cjs} +3 -3
- package/dist/{migrate-BBcG1dhS.cjs.map → migrate-CsMrI7Dk.cjs.map} +1 -1
- package/dist/openapi.cjs +1 -1
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +1 -1
- package/dist/projectBucket-BFp-SFee.mjs +177 -0
- package/dist/projectBucket-BFp-SFee.mjs.map +1 -0
- package/dist/projectBucket-Cho9DpSh.cjs +206 -0
- package/dist/projectBucket-Cho9DpSh.cjs.map +1 -0
- package/dist/reconcile/public.d.cts +2 -2
- package/dist/reconcile/public.d.mts +2 -2
- package/dist/{resolve-DakDhr6Z.mjs → resolve-6EYNqYdr.mjs} +3 -3
- package/dist/{resolve-DakDhr6Z.mjs.map → resolve-6EYNqYdr.mjs.map} +1 -1
- package/dist/{resolve-CFb4Navi.cjs → resolve-C8VkR4oW.cjs} +3 -3
- package/dist/{resolve-CFb4Navi.cjs.map → resolve-C8VkR4oW.cjs.map} +1 -1
- package/dist/{rollback-B1TIpjdE.mjs → rollback-BsThTeSN.mjs} +7 -6
- package/dist/{rollback-B1TIpjdE.mjs.map → rollback-BsThTeSN.mjs.map} +1 -1
- package/dist/{rollback-B-1dPP0m.cjs → rollback-CvGfm4DX.cjs} +7 -6
- package/dist/{rollback-B-1dPP0m.cjs.map → rollback-CvGfm4DX.cjs.map} +1 -1
- package/dist/{runtime-DUQdM-mW.d.cts → runtime-CaW4QqF2.d.cts} +2 -2
- package/dist/{runtime-DUQdM-mW.d.cts.map → runtime-CaW4QqF2.d.cts.map} +1 -1
- package/dist/{runtime-Vr6mleo2.d.mts → runtime-K5uxp6HE.d.mts} +2 -2
- package/dist/{runtime-Vr6mleo2.d.mts.map → runtime-K5uxp6HE.d.mts.map} +1 -1
- package/dist/{sandbox-DGOsMPMf.d.mts → sandbox-B_BkfmTP.d.mts} +2 -2
- package/dist/{sandbox-BbJmh2rI.d.cts.map → sandbox-B_BkfmTP.d.mts.map} +1 -1
- package/dist/{sandbox-BbJmh2rI.d.cts → sandbox-D8cfZUAA.d.cts} +2 -2
- package/dist/{sandbox-DGOsMPMf.d.mts.map → sandbox-D8cfZUAA.d.cts.map} +1 -1
- package/dist/{secrets-CPM0Qffe.cjs → secrets-BTY6JhTp.cjs} +3 -3
- package/dist/{secrets-CPM0Qffe.cjs.map → secrets-BTY6JhTp.cjs.map} +1 -1
- package/dist/{secrets-oI9ClAPR.mjs → secrets-HzKNTWg9.mjs} +3 -3
- package/dist/{secrets-oI9ClAPR.mjs.map → secrets-HzKNTWg9.mjs.map} +1 -1
- package/dist/{seeds-CnXkgKUv.cjs → seeds-BQlj9Fsg.cjs} +4 -4
- package/dist/{seeds-CnXkgKUv.cjs.map → seeds-BQlj9Fsg.cjs.map} +1 -1
- package/dist/{seeds-CoKkrSny.mjs → seeds-BsJRUL1K.mjs} +4 -4
- package/dist/{seeds-CoKkrSny.mjs.map → seeds-BsJRUL1K.mjs.map} +1 -1
- package/dist/{sniffer-vbiQ2Isn.cjs → sniffer-CeUKUoHn.cjs} +100 -10
- package/dist/sniffer-CeUKUoHn.cjs.map +1 -0
- package/dist/{sniffer-CFRzIrby.mjs → sniffer-DVsvP8s-.mjs} +77 -11
- package/dist/sniffer-DVsvP8s-.mjs.map +1 -0
- package/dist/{stack-B7O975TR.mjs → stack-BQOyqaVG.mjs} +3 -3
- package/dist/{stack-B7O975TR.mjs.map → stack-BQOyqaVG.mjs.map} +1 -1
- package/dist/{stack-1g57OfOw.cjs → stack-Clzi40EE.cjs} +3 -3
- package/dist/{stack-1g57OfOw.cjs.map → stack-Clzi40EE.cjs.map} +1 -1
- package/dist/{stages-BujUB4we.cjs → stages-BpDXFPGg.cjs} +4 -4
- package/dist/{stages-BujUB4we.cjs.map → stages-BpDXFPGg.cjs.map} +1 -1
- package/dist/{stages-Bt4OggMm.mjs → stages-DEmn7qI8.mjs} +4 -4
- package/dist/{stages-Bt4OggMm.mjs.map → stages-DEmn7qI8.mjs.map} +1 -1
- 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/{types-dipJRmKV.d.cts → types-4vPS_YFX.d.cts} +21 -4
- package/dist/types-4vPS_YFX.d.cts.map +1 -0
- package/dist/{types-bkqVscdN.d.mts → types-CFsEyFb1.d.mts} +21 -4
- package/dist/types-CFsEyFb1.d.mts.map +1 -0
- 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-DWK1PTXP.mjs → workspace-Bv4xROeu.mjs} +61 -5
- package/dist/workspace-Bv4xROeu.mjs.map +1 -0
- package/dist/{workspace-cSyi5nb1.cjs → workspace-C1M-S4al.cjs} +78 -4
- package/dist/workspace-C1M-S4al.cjs.map +1 -0
- package/package.json +16 -15
- package/dist/S3StateStore-CjTAVsWh.mjs.map +0 -1
- package/dist/S3StateStore-Cm-v2IPI.cjs.map +0 -1
- package/dist/SSMStateStore-BS4BiZCN.cjs.map +0 -1
- package/dist/SSMStateStore-BhtM6jOh.mjs.map +0 -1
- package/dist/deploy-B0drCD6s.mjs.map +0 -1
- package/dist/deploy-Bw1FjX_x.cjs.map +0 -1
- package/dist/github-DUGA57du.mjs.map +0 -1
- package/dist/github-DgmW83OP.cjs.map +0 -1
- package/dist/sniffer-CFRzIrby.mjs.map +0 -1
- package/dist/sniffer-vbiQ2Isn.cjs.map +0 -1
- package/dist/types-bkqVscdN.d.mts.map +0 -1
- package/dist/types-dipJRmKV.d.cts.map +0 -1
- package/dist/workspace-DWK1PTXP.mjs.map +0 -1
- package/dist/workspace-cSyi5nb1.cjs.map +0 -1
|
@@ -5,15 +5,15 @@ const require_credentials = require("./credentials-Zqr3QQYB.cjs");
|
|
|
5
5
|
const require_discover = require("./discover-DPgu-ScS.cjs");
|
|
6
6
|
const require_sandbox = require("./sandbox-CHv3OYXg.cjs");
|
|
7
7
|
const require_derive = require("./derive-DAbo49sm.cjs");
|
|
8
|
-
const require_workspace = require("./workspace-
|
|
8
|
+
const require_workspace = require("./workspace-C1M-S4al.cjs");
|
|
9
9
|
const require_define = require("./define-crmMcXFS.cjs");
|
|
10
10
|
const require_config = require("./config.cjs");
|
|
11
|
-
const require_seeds = require("./seeds-
|
|
12
|
-
const require_resolve = require("./resolve-
|
|
11
|
+
const require_seeds = require("./seeds-BQlj9Fsg.cjs");
|
|
12
|
+
const require_resolve = require("./resolve-C8VkR4oW.cjs");
|
|
13
13
|
const require_local = require("./local-DNhnkugT.cjs");
|
|
14
|
-
const require_sniffer = require("./sniffer-
|
|
15
|
-
const require_dns = require("./dns-
|
|
16
|
-
const require_dns$1 = require("./dns-
|
|
14
|
+
const require_sniffer = require("./sniffer-CeUKUoHn.cjs");
|
|
15
|
+
const require_dns = require("./dns-BFnoawgh.cjs");
|
|
16
|
+
const require_dns$1 = require("./dns-Dro_vbk9.cjs");
|
|
17
17
|
const require_credentialSchemas = require("./credentialSchemas-CAPKFkrG.cjs");
|
|
18
18
|
let node_path = require("node:path");
|
|
19
19
|
let _geekmidas_manifest = require("@geekmidas/manifest");
|
|
@@ -449,6 +449,74 @@ function errorName(error) {
|
|
|
449
449
|
const e = error;
|
|
450
450
|
return e?.Code ?? e?.name ?? "";
|
|
451
451
|
}
|
|
452
|
+
/** The answer an SDK call failed with. */
|
|
453
|
+
function s3Answer(error) {
|
|
454
|
+
const e = error;
|
|
455
|
+
const headers = Object.fromEntries(Object.entries(e?.$response?.headers ?? {}).map(([k, v]) => [k.toLowerCase(), v]));
|
|
456
|
+
const status = e?.$metadata?.httpStatusCode ?? e?.$response?.statusCode;
|
|
457
|
+
const region = headers["x-amz-bucket-region"];
|
|
458
|
+
const requestId = e?.$metadata?.requestId ?? headers["x-amz-request-id"];
|
|
459
|
+
const id2 = e?.$metadata?.extendedRequestId ?? headers["x-amz-id-2"];
|
|
460
|
+
return {
|
|
461
|
+
...status !== void 0 ? { status } : {},
|
|
462
|
+
name: errorName(error) || "Error",
|
|
463
|
+
message: e?.message ?? String(error),
|
|
464
|
+
...region ? { region } : {},
|
|
465
|
+
...requestId ? { requestId } : {},
|
|
466
|
+
...id2 ? { id2 } : {}
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* `HTTP 403 Unknown: UnknownError [x-amz-bucket-region: eu-west-1,
|
|
471
|
+
* x-amz-request-id: …, x-amz-id-2: …]` — everything S3 said, for a message.
|
|
472
|
+
*/
|
|
473
|
+
function describeAnswer(answer) {
|
|
474
|
+
const said = answer.message && answer.message !== answer.name ? `${answer.name}: ${answer.message}` : answer.name;
|
|
475
|
+
const headers = [
|
|
476
|
+
answer.region && `x-amz-bucket-region: ${answer.region}`,
|
|
477
|
+
answer.requestId && `x-amz-request-id: ${answer.requestId}`,
|
|
478
|
+
answer.id2 && `x-amz-id-2: ${answer.id2}`
|
|
479
|
+
].filter(Boolean);
|
|
480
|
+
return `${answer.status === void 0 ? "no response" : `HTTP ${answer.status}`} ${said}` + (headers.length > 0 ? ` [${headers.join(", ")}]` : "");
|
|
481
|
+
}
|
|
482
|
+
/** `HeadBucket`: the bucket's region when it answers, else what S3 said. */
|
|
483
|
+
async function headBucket(S3, client, bucket) {
|
|
484
|
+
try {
|
|
485
|
+
const out = await client.send(new S3.HeadBucketCommand({ Bucket: bucket }));
|
|
486
|
+
return {
|
|
487
|
+
ok: true,
|
|
488
|
+
...out.BucketRegion ? { region: out.BucketRegion } : {}
|
|
489
|
+
};
|
|
490
|
+
} catch (error) {
|
|
491
|
+
return {
|
|
492
|
+
ok: false,
|
|
493
|
+
...s3Answer(error)
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
/** `GetBucketLocation`'s answer as a region: none is us-east-1, `EU` eu-west-1. */
|
|
498
|
+
async function bucketLocation(S3, client, bucket) {
|
|
499
|
+
try {
|
|
500
|
+
const location = (await client.send(new S3.GetBucketLocationCommand({ Bucket: bucket }))).LocationConstraint;
|
|
501
|
+
return { region: !location ? "us-east-1" : location === "EU" ? "eu-west-1" : location };
|
|
502
|
+
} catch (error) {
|
|
503
|
+
return { failed: s3Answer(error) };
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Where `bucket` is: `HeadBucket`'s `x-amz-bucket-region` — on a 200, a 301
|
|
508
|
+
* or a 400 alike — else `GetBucketLocation`.
|
|
509
|
+
*
|
|
510
|
+
* @throws {BucketRegionUnknown}
|
|
511
|
+
*/
|
|
512
|
+
async function bucketRegion(clients, bucket) {
|
|
513
|
+
const { S3, s3 } = clients;
|
|
514
|
+
const head = await headBucket(S3, s3, bucket);
|
|
515
|
+
if (head.region) return head.region;
|
|
516
|
+
const location = await bucketLocation(S3, s3, bucket);
|
|
517
|
+
if ("region" in location) return location.region;
|
|
518
|
+
throw new require_workspace.BucketRegionUnknown(bucket, head.ok ? "HTTP 200 without x-amz-bucket-region" : describeAnswer(head), describeAnswer(location.failed));
|
|
519
|
+
}
|
|
452
520
|
/** A read whose "there is none" answer is one of `missing`. */
|
|
453
521
|
async function readOr(read, missing) {
|
|
454
522
|
try {
|
|
@@ -502,7 +570,7 @@ function identityTags(ctx, id) {
|
|
|
502
570
|
}
|
|
503
571
|
];
|
|
504
572
|
}
|
|
505
|
-
async function ensureBucket(ctx,
|
|
573
|
+
async function ensureBucket(ctx, stageClients, construct) {
|
|
506
574
|
const { id } = construct;
|
|
507
575
|
const nameInput = {
|
|
508
576
|
scope: ctx.identity.scope,
|
|
@@ -511,7 +579,13 @@ async function ensureBucket(ctx, clients, construct) {
|
|
|
511
579
|
};
|
|
512
580
|
const versioning = ctx.config.versioning ?? construct.versioned;
|
|
513
581
|
const open = [...new Set(construct.servers.flatMap((s) => s.open))].sort();
|
|
514
|
-
const
|
|
582
|
+
const located = await ensureBucketName(ctx, stageClients, id, bucketName(nameInput));
|
|
583
|
+
const { bucket, exists } = located;
|
|
584
|
+
let clients = stageClients;
|
|
585
|
+
if (located.region !== stageClients.region) {
|
|
586
|
+
clients = await makeClients(ctx.credential, located.region);
|
|
587
|
+
ctx.log(` '${bucket}' is in ${located.region}, not ${stageClients.region}: '${id}' is reached and addressed there`);
|
|
588
|
+
}
|
|
515
589
|
await ensureBucketSettings(ctx, clients, {
|
|
516
590
|
id,
|
|
517
591
|
bucket,
|
|
@@ -519,10 +593,11 @@ async function ensureBucket(ctx, clients, construct) {
|
|
|
519
593
|
versioning,
|
|
520
594
|
open
|
|
521
595
|
});
|
|
596
|
+
const user = await ensureUser(ctx, clients, id, iamUserName(nameInput), userPolicy(bucket, { versioning }));
|
|
522
597
|
await ensureAccessKey(ctx, clients, {
|
|
523
598
|
id,
|
|
524
599
|
bucket,
|
|
525
|
-
...
|
|
600
|
+
...user
|
|
526
601
|
});
|
|
527
602
|
const publicUrl = bucketPublicUrl(bucket, clients.region, clients.endpoint);
|
|
528
603
|
for (const server of construct.servers) {
|
|
@@ -559,26 +634,32 @@ async function ensureBucketName(ctx, clients, id, good) {
|
|
|
559
634
|
const { S3, s3, region } = clients;
|
|
560
635
|
const key = `s3-bucket:${id}`;
|
|
561
636
|
const record = ctx.state.record(key);
|
|
562
|
-
const entry = (name) => ({
|
|
637
|
+
const entry = (name, where) => ({
|
|
563
638
|
key,
|
|
564
639
|
type: "s3-bucket",
|
|
565
640
|
data: {
|
|
566
641
|
name,
|
|
567
|
-
region
|
|
642
|
+
region: where
|
|
568
643
|
}
|
|
569
644
|
});
|
|
570
|
-
/**
|
|
645
|
+
/**
|
|
646
|
+
* Whether this account holds `name`: yes, no, or someone else does. Read
|
|
647
|
+
* by status — a `HEAD` has no body, so its error is named `Unknown` — and,
|
|
648
|
+
* when S3 says the bucket is in another region, asked again there.
|
|
649
|
+
*/
|
|
571
650
|
const probe = async (name) => {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
const name = errorName(error);
|
|
577
|
-
if (name === "NotFound" || name === "NoSuchBucket") return "none";
|
|
578
|
-
if (name === "Forbidden" || name === "AccessDenied") return "taken";
|
|
579
|
-
throw error;
|
|
651
|
+
let head = await headBucket(S3, s3, name);
|
|
652
|
+
if (!head.ok && head.region && head.region !== region && (head.status === 301 || head.status === 400)) {
|
|
653
|
+
const there = await makeClients(ctx.credential, head.region);
|
|
654
|
+
head = await headBucket(there.S3, there.s3, name);
|
|
580
655
|
}
|
|
656
|
+
if (head.ok) return "ours";
|
|
657
|
+
if (head.status === 404) return "none";
|
|
658
|
+
if (head.status === 403) return "taken";
|
|
659
|
+
throw new require_workspace.BucketProbeFailed(name, describeAnswer(head));
|
|
581
660
|
};
|
|
661
|
+
/** Where the bucket is now — read, not assumed: it may be adopted. */
|
|
662
|
+
const located = async (name, made) => ctx.dryRun && made === "created" ? region : bucketRegion(clients, name);
|
|
582
663
|
const create = async (name) => {
|
|
583
664
|
if (ctx.dryRun) {
|
|
584
665
|
const found = await probe(name);
|
|
@@ -592,7 +673,7 @@ async function ensureBucketName(ctx, clients, id, good) {
|
|
|
592
673
|
}
|
|
593
674
|
return found;
|
|
594
675
|
}
|
|
595
|
-
await ctx.state.pending(entry(name));
|
|
676
|
+
await ctx.state.pending(entry(name, region));
|
|
596
677
|
try {
|
|
597
678
|
await s3.send(new S3.CreateBucketCommand({
|
|
598
679
|
Bucket: name,
|
|
@@ -611,23 +692,22 @@ async function ensureBucketName(ctx, clients, id, good) {
|
|
|
611
692
|
}, async () => {});
|
|
612
693
|
return "created";
|
|
613
694
|
};
|
|
614
|
-
const adopt = async (name) => {
|
|
615
|
-
const
|
|
695
|
+
const adopt = async (name, where) => {
|
|
696
|
+
const there = where === region ? clients : await makeClients(ctx.credential, where);
|
|
697
|
+
const owner = (await readOr(() => there.s3.send(new there.S3.GetBucketTaggingCommand({ Bucket: name })), ["NoSuchTagSet", "NoSuchTagSetError"]))?.TagSet?.find((t) => t.Key === TAG_PROJECT)?.Value;
|
|
616
698
|
if (owner && owner !== ctx.identity.key) throw new require_workspace.BucketOwnedByAnotherProject(name, owner, ctx.identity.key);
|
|
617
699
|
};
|
|
618
700
|
if (record?.status === "ready" && record.id) {
|
|
619
701
|
const found = await probe(record.id);
|
|
620
|
-
if (found === "ours") return {
|
|
621
|
-
bucket: record.id,
|
|
622
|
-
exists: true
|
|
623
|
-
};
|
|
624
702
|
if (found === "taken") throw new require_workspace.RecordedBucketUnreachable(id, record.id);
|
|
625
|
-
const made = await create(record.id);
|
|
703
|
+
const made = found === "ours" ? "ours" : await create(record.id);
|
|
626
704
|
if (made === "taken") throw new require_workspace.RecordedBucketUnreachable(id, record.id);
|
|
627
|
-
|
|
705
|
+
const where = await located(record.id, made);
|
|
706
|
+
if (!ctx.dryRun) await ctx.state.ready(entry(record.id, where), record.id);
|
|
628
707
|
return {
|
|
629
708
|
bucket: record.id,
|
|
630
|
-
exists: made === "ours"
|
|
709
|
+
exists: made === "ours",
|
|
710
|
+
region: where
|
|
631
711
|
};
|
|
632
712
|
}
|
|
633
713
|
const pending = record?.data?.name;
|
|
@@ -641,12 +721,14 @@ async function ensureBucketName(ctx, clients, id, good) {
|
|
|
641
721
|
tried.push(name);
|
|
642
722
|
const made = await create(name);
|
|
643
723
|
if (made === "taken") continue;
|
|
644
|
-
|
|
645
|
-
if (
|
|
724
|
+
const where = await located(name, made);
|
|
725
|
+
if (made === "ours") await adopt(name, where);
|
|
726
|
+
if (!ctx.dryRun) await ctx.state.ready(entry(name, where), name);
|
|
646
727
|
if (name !== good) ctx.log(` '${good}' is taken by another account; '${id}' is '${name}', recorded in the stage's state`);
|
|
647
728
|
return {
|
|
648
729
|
bucket: name,
|
|
649
|
-
exists: made === "ours"
|
|
730
|
+
exists: made === "ours",
|
|
731
|
+
region: where
|
|
650
732
|
};
|
|
651
733
|
}
|
|
652
734
|
throw new require_workspace.BucketNameUnavailable(id, tried.filter((n) => n !== pending));
|
|
@@ -810,8 +892,8 @@ async function ensureAccessKey(ctx, clients, input) {
|
|
|
810
892
|
const record = ctx.state.record(entryKey);
|
|
811
893
|
const given = ctx.secrets[urlKey];
|
|
812
894
|
let inUrl;
|
|
895
|
+
let parsed;
|
|
813
896
|
if (given !== void 0) {
|
|
814
|
-
let parsed;
|
|
815
897
|
try {
|
|
816
898
|
parsed = _geekmidas_storage_s3_url.parse(given);
|
|
817
899
|
} catch {
|
|
@@ -855,7 +937,20 @@ async function ensureAccessKey(ctx, clients, input) {
|
|
|
855
937
|
await ctx.state.ready(entry(), inUrl);
|
|
856
938
|
current = inUrl;
|
|
857
939
|
}
|
|
858
|
-
if (current !== void 0 && listed.includes(current) && inUrl === current && !ctx.rotateKeys)
|
|
940
|
+
if (current !== void 0 && listed.includes(current) && inUrl === current && !ctx.rotateKeys) {
|
|
941
|
+
if (parsed && parsed.region !== clients.region) {
|
|
942
|
+
const address = parsed;
|
|
943
|
+
await ctx.change({
|
|
944
|
+
construct: id,
|
|
945
|
+
resource: urlKey,
|
|
946
|
+
change: `name ${clients.region}, the bucket's region (it said ${address.region ?? "none"})`
|
|
947
|
+
}, () => ctx.writeSecrets({ [urlKey]: _geekmidas_storage_s3_url.build({
|
|
948
|
+
...address,
|
|
949
|
+
region: clients.region
|
|
950
|
+
}) }));
|
|
951
|
+
}
|
|
952
|
+
return;
|
|
953
|
+
}
|
|
859
954
|
if (ctx.rotateKeys && previous) throw new require_workspace.RotationInProgress(id, previous, ctx.stage);
|
|
860
955
|
const outgoing = current && listed.includes(current) ? current : void 0;
|
|
861
956
|
if (listed.length >= 2) throw new require_workspace.AccessKeyLimit(user, listed);
|
|
@@ -877,28 +972,58 @@ async function ensureAccessKey(ctx, clients, input) {
|
|
|
877
972
|
accessKeyId: key.AccessKeyId,
|
|
878
973
|
secretAccessKey: key.SecretAccessKey
|
|
879
974
|
}) });
|
|
975
|
+
const issuedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
880
976
|
await ctx.state.ready(entry(outgoing ? {
|
|
881
977
|
previous: outgoing,
|
|
882
|
-
rotatedAt:
|
|
883
|
-
|
|
978
|
+
rotatedAt: issuedAt,
|
|
979
|
+
issuedAt
|
|
980
|
+
} : { issuedAt }), key.AccessKeyId);
|
|
884
981
|
});
|
|
885
982
|
if (outgoing) ctx.log(` ${urlKey} holds the new key. This deploy moves '${ctx.stage}' onto it; the next deploy after it deletes the old key ${outgoing}`);
|
|
886
983
|
}
|
|
984
|
+
/** How long a key issued this recently counts as new to IAM. */
|
|
985
|
+
const NEW_KEY_WINDOW_MS = 6e5;
|
|
986
|
+
/** The waits between asks while a new key becomes usable: about a minute. */
|
|
987
|
+
let newKeyWaits = [
|
|
988
|
+
2e3,
|
|
989
|
+
4e3,
|
|
990
|
+
8e3,
|
|
991
|
+
15e3,
|
|
992
|
+
15e3,
|
|
993
|
+
15e3
|
|
994
|
+
];
|
|
995
|
+
/** When the key in the URL was issued, if the stage's state says it was just now. */
|
|
996
|
+
function issuedJustNow(ctx, id, accessKeyId) {
|
|
997
|
+
const record = ctx.resources?.[`iam-access-key:${id}`];
|
|
998
|
+
const issuedAt = record?.data?.issuedAt;
|
|
999
|
+
if (record?.id !== accessKeyId || typeof issuedAt !== "string") return;
|
|
1000
|
+
const age = Date.now() - Date.parse(issuedAt);
|
|
1001
|
+
return age >= 0 && age < NEW_KEY_WINDOW_MS ? issuedAt : void 0;
|
|
1002
|
+
}
|
|
887
1003
|
/**
|
|
888
1004
|
* Each provisioned bucket answers `HeadBucket` to the key in the stage's
|
|
889
1005
|
* secrets — the one the apps will use. A bucket whose URL carries no key is
|
|
890
1006
|
* not one this provider wrote, and the deploy's own check covers a URL that
|
|
891
1007
|
* is missing.
|
|
1008
|
+
*
|
|
1009
|
+
* A failure is read by its status, never its name — a `HEAD` has no body,
|
|
1010
|
+
* so SDK v3 calls a 301, 400 or 403 `Unknown` — and the message carries
|
|
1011
|
+
* everything S3 said: status, error, region, request ids.
|
|
1012
|
+
*
|
|
1013
|
+
* @throws {BucketRegionMismatch} the bucket is in another region than its URL says
|
|
1014
|
+
* @throws {ProvisionedBucketUnreachable}
|
|
892
1015
|
*/
|
|
893
1016
|
async function verifyS3(ctx) {
|
|
894
1017
|
const S3 = await import("@aws-sdk/client-s3");
|
|
895
1018
|
for (const { id } of bucketConstructs(ctx.manifest)) {
|
|
896
|
-
const
|
|
1019
|
+
const urlKey = (0, _geekmidas_manifest.provideKey)(id, "url");
|
|
1020
|
+
const url = ctx.secrets[urlKey];
|
|
897
1021
|
if (url === void 0) continue;
|
|
898
1022
|
const address = _geekmidas_storage_s3_url.parse(url);
|
|
899
1023
|
if (!address.accessKeyId || !address.secretAccessKey) continue;
|
|
1024
|
+
const asked = address.region ?? ctx.config.region ?? "us-east-1";
|
|
900
1025
|
const client = new S3.S3Client({
|
|
901
|
-
region:
|
|
1026
|
+
region: asked,
|
|
902
1027
|
credentials: {
|
|
903
1028
|
accessKeyId: address.accessKeyId,
|
|
904
1029
|
secretAccessKey: address.secretAccessKey
|
|
@@ -907,10 +1032,35 @@ async function verifyS3(ctx) {
|
|
|
907
1032
|
...address.forcePathStyle ? { forcePathStyle: true } : {}
|
|
908
1033
|
});
|
|
909
1034
|
try {
|
|
910
|
-
await
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
1035
|
+
let head = await headBucket(S3, client, address.bucket);
|
|
1036
|
+
const issuedAt = issuedJustNow(ctx, id, address.accessKeyId);
|
|
1037
|
+
let waited = 0;
|
|
1038
|
+
if (!head.ok && head.status === 403 && issuedAt) {
|
|
1039
|
+
ctx.log?.(` ${id}: waiting for the new key ${address.accessKeyId} to become active…`);
|
|
1040
|
+
for (const wait of newKeyWaits) {
|
|
1041
|
+
await new Promise((resolve) => setTimeout(resolve, wait));
|
|
1042
|
+
waited += wait;
|
|
1043
|
+
head = await headBucket(S3, client, address.bucket);
|
|
1044
|
+
if (head.ok || head.status !== 403) break;
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
if (head.ok) continue;
|
|
1048
|
+
const fail = (reason) => new require_workspace.ProvisionedBucketUnreachable(id, address.bucket, ctx.stage, reason);
|
|
1049
|
+
const said = describeAnswer(head);
|
|
1050
|
+
if (head.status === 301 || head.status === 400 && head.region && head.region !== asked) {
|
|
1051
|
+
let where = head.region;
|
|
1052
|
+
let located = "";
|
|
1053
|
+
if (!where) {
|
|
1054
|
+
const location = await bucketLocation(S3, client, address.bucket);
|
|
1055
|
+
if ("region" in location) where = location.region;
|
|
1056
|
+
else located = `; GetBucketLocation answered ${describeAnswer(location.failed)}`;
|
|
1057
|
+
}
|
|
1058
|
+
if (where && where !== asked) throw new require_workspace.BucketRegionMismatch(id, address.bucket, ctx.stage, urlKey, where, address.region, asked, said);
|
|
1059
|
+
throw fail(`S3 redirected the request (${said}${located})`);
|
|
1060
|
+
}
|
|
1061
|
+
if (head.status === 404) throw fail(`it does not exist (${said})`);
|
|
1062
|
+
if (head.status === 403) throw fail(`the key is refused — AccessDenied, or an invalid or not-yet-active key (${said})` + (issuedAt ? `. The key was issued at ${issuedAt} by this deploy, and IAM keys take seconds to become usable: it was still refused after waiting ${Math.round(waited / 1e3)}s` : ""));
|
|
1063
|
+
throw fail(said);
|
|
914
1064
|
} finally {
|
|
915
1065
|
client.destroy();
|
|
916
1066
|
}
|
|
@@ -963,7 +1113,9 @@ async function verifyStageProviders(input) {
|
|
|
963
1113
|
manifest: input.manifest,
|
|
964
1114
|
stage: input.stage,
|
|
965
1115
|
config: choice.config,
|
|
966
|
-
secrets: input.secrets
|
|
1116
|
+
secrets: input.secrets,
|
|
1117
|
+
...input.resources ? { resources: input.resources } : {},
|
|
1118
|
+
...input.log ? { log: input.log } : {}
|
|
967
1119
|
});
|
|
968
1120
|
verified.push(`${kind}: ${provider.name}`);
|
|
969
1121
|
}
|
|
@@ -1257,7 +1409,9 @@ async function assertStageReady(ctx) {
|
|
|
1257
1409
|
workspace,
|
|
1258
1410
|
manifest,
|
|
1259
1411
|
stage,
|
|
1260
|
-
secrets: supplied
|
|
1412
|
+
secrets: supplied,
|
|
1413
|
+
resources: (await ctx.state.read(stage))?.resources ?? {},
|
|
1414
|
+
log: (line) => ctx.logger.info(line)
|
|
1261
1415
|
});
|
|
1262
1416
|
for (const line of verified) ctx.logger.info(`✓ ${line} verified`);
|
|
1263
1417
|
}
|
|
@@ -1443,6 +1597,16 @@ async function runDeploy(source, request, ctx) {
|
|
|
1443
1597
|
throw error;
|
|
1444
1598
|
}
|
|
1445
1599
|
try {
|
|
1600
|
+
try {
|
|
1601
|
+
await require_sniffer.assertStateRoom(store, stage);
|
|
1602
|
+
} catch (error) {
|
|
1603
|
+
emit({
|
|
1604
|
+
type: "phase.failed",
|
|
1605
|
+
phase: "validate",
|
|
1606
|
+
error: require_sniffer.eventError(error)
|
|
1607
|
+
});
|
|
1608
|
+
throw error;
|
|
1609
|
+
}
|
|
1446
1610
|
if (resources) await provision();
|
|
1447
1611
|
if (request.resourcesOnly) return resourcesOnly(target, phaseCtx, emit);
|
|
1448
1612
|
const run = await validate(phaseCtx, emit, () => readyToDeploy(target, phaseCtx));
|
|
@@ -1668,7 +1832,8 @@ async function prepare(source, request, ctx, emit, redactor) {
|
|
|
1668
1832
|
const store = await require_sniffer.createStateStore({
|
|
1669
1833
|
config: workspace.state,
|
|
1670
1834
|
workspaceRoot: workspace.root,
|
|
1671
|
-
workspaceName: workspace.name
|
|
1835
|
+
workspaceName: workspace.name,
|
|
1836
|
+
namespace: workspace.deploy?.namespace
|
|
1672
1837
|
});
|
|
1673
1838
|
const secrets = await deploySecrets(workspace, stage, redactor, { ...ctx.home ? { home: ctx.home } : {} });
|
|
1674
1839
|
const line = (level) => (message) => emit({
|
|
@@ -1900,4 +2065,4 @@ Object.defineProperty(exports, "iamUserName", {
|
|
|
1900
2065
|
}
|
|
1901
2066
|
});
|
|
1902
2067
|
|
|
1903
|
-
//# sourceMappingURL=deploy-
|
|
2068
|
+
//# sourceMappingURL=deploy-Cu_HyWoJ.cjs.map
|