@hot-updater/aws 0.35.7 → 0.35.9
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/iac/index.cjs +563 -233
- package/dist/iac/index.d.cts +4 -5
- package/dist/iac/index.d.mts +4 -5
- package/dist/iac/index.mjs +564 -234
- package/dist/init/index.cjs +149 -0
- package/dist/init/index.d.cts +102 -0
- package/dist/init/index.d.mts +102 -0
- package/dist/init/index.mjs +144 -0
- package/dist/lambda/index.cjs +1 -1
- package/package.json +13 -8
package/dist/iac/index.cjs
CHANGED
|
@@ -22,7 +22,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
22
22
|
enumerable: true
|
|
23
23
|
}) : target, mod));
|
|
24
24
|
//#endregion
|
|
25
|
-
let _aws_sdk_credential_providers = require("@aws-sdk/credential-providers");
|
|
26
25
|
let _hot_updater_cli_tools = require("@hot-updater/cli-tools");
|
|
27
26
|
let node_url = require("node:url");
|
|
28
27
|
let node_child_process = require("node:child_process");
|
|
@@ -44,6 +43,7 @@ let node_fs = require("node:fs");
|
|
|
44
43
|
let node_stream_promises = require("node:stream/promises");
|
|
45
44
|
let node_stream = require("node:stream");
|
|
46
45
|
let node_buffer = require("node:buffer");
|
|
46
|
+
let _aws_sdk_credential_providers = require("@aws-sdk/credential-providers");
|
|
47
47
|
let crypto = require("crypto");
|
|
48
48
|
crypto = __toESM(crypto);
|
|
49
49
|
let _aws_sdk_client_cloudfront = require("@aws-sdk/client-cloudfront");
|
|
@@ -6214,6 +6214,380 @@ createExeca(mapNode);
|
|
|
6214
6214
|
createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync);
|
|
6215
6215
|
const { sendMessage, getOneMessage, getEachMessage, getCancelSignal } = getIpcExport();
|
|
6216
6216
|
//#endregion
|
|
6217
|
+
//#region iac/init/index.ts
|
|
6218
|
+
const AWS_AUTH_MODES = [
|
|
6219
|
+
"local-session",
|
|
6220
|
+
"shared-profile",
|
|
6221
|
+
"sso",
|
|
6222
|
+
"account"
|
|
6223
|
+
];
|
|
6224
|
+
const isAwsAuthMode = (value) => value !== void 0 && AWS_AUTH_MODES.some((mode) => mode === value);
|
|
6225
|
+
const AWS_REGION_VALUES = [
|
|
6226
|
+
"af-south-1",
|
|
6227
|
+
"ap-east-1",
|
|
6228
|
+
"ap-east-2",
|
|
6229
|
+
"ap-northeast-1",
|
|
6230
|
+
"ap-northeast-2",
|
|
6231
|
+
"ap-northeast-3",
|
|
6232
|
+
"ap-south-1",
|
|
6233
|
+
"ap-south-2",
|
|
6234
|
+
"ap-southeast-1",
|
|
6235
|
+
"ap-southeast-2",
|
|
6236
|
+
"ap-southeast-3",
|
|
6237
|
+
"ap-southeast-4",
|
|
6238
|
+
"ap-southeast-5",
|
|
6239
|
+
"ap-southeast-6",
|
|
6240
|
+
"ap-southeast-7",
|
|
6241
|
+
"ca-central-1",
|
|
6242
|
+
"ca-west-1",
|
|
6243
|
+
"cn-north-1",
|
|
6244
|
+
"cn-northwest-1",
|
|
6245
|
+
"eu-central-1",
|
|
6246
|
+
"eu-central-2",
|
|
6247
|
+
"eu-north-1",
|
|
6248
|
+
"eu-south-1",
|
|
6249
|
+
"eu-south-2",
|
|
6250
|
+
"eu-west-1",
|
|
6251
|
+
"eu-west-2",
|
|
6252
|
+
"eu-west-3",
|
|
6253
|
+
"il-central-1",
|
|
6254
|
+
"me-central-1",
|
|
6255
|
+
"me-south-1",
|
|
6256
|
+
"mx-central-1",
|
|
6257
|
+
"sa-east-1",
|
|
6258
|
+
"us-east-1",
|
|
6259
|
+
"us-east-2",
|
|
6260
|
+
"us-gov-east-1",
|
|
6261
|
+
"us-gov-west-1",
|
|
6262
|
+
"us-west-1",
|
|
6263
|
+
"us-west-2"
|
|
6264
|
+
];
|
|
6265
|
+
const isAwsRegionValue = (value) => value !== void 0 && AWS_REGION_VALUES.some((region) => region === value);
|
|
6266
|
+
const initProvider = {
|
|
6267
|
+
label: "AWS S3 + Lambda@Edge",
|
|
6268
|
+
inputs: {
|
|
6269
|
+
authMode: {
|
|
6270
|
+
envKey: "HOT_UPDATER_AWS_AUTH_MODE",
|
|
6271
|
+
help: "AWS authentication mode: local-session, shared-profile, sso, or account",
|
|
6272
|
+
prompt: {
|
|
6273
|
+
message: "Select the mode to login to AWS",
|
|
6274
|
+
type: "select"
|
|
6275
|
+
},
|
|
6276
|
+
validate: isAwsAuthMode
|
|
6277
|
+
},
|
|
6278
|
+
profile: {
|
|
6279
|
+
envKey: "HOT_UPDATER_AWS_PROFILE",
|
|
6280
|
+
help: "AWS profile name",
|
|
6281
|
+
requiredWhen: (inputs) => inputs.authMode === "shared-profile" || inputs.authMode === "sso",
|
|
6282
|
+
requirementHint: "required for shared-profile and sso auth",
|
|
6283
|
+
prompt: {
|
|
6284
|
+
defaultValue: "default",
|
|
6285
|
+
message: "Enter the AWS profile name",
|
|
6286
|
+
placeholder: "default",
|
|
6287
|
+
type: "text"
|
|
6288
|
+
}
|
|
6289
|
+
},
|
|
6290
|
+
accessKeyId: {
|
|
6291
|
+
envKey: "HOT_UPDATER_S3_ACCESS_KEY_ID",
|
|
6292
|
+
help: "AWS access key ID",
|
|
6293
|
+
persistence: "with-consent",
|
|
6294
|
+
requiredWhen: (inputs) => inputs.authMode === "account",
|
|
6295
|
+
requirementHint: "required for account auth",
|
|
6296
|
+
prompt: {
|
|
6297
|
+
message: "Enter your AWS Access Key ID",
|
|
6298
|
+
placeholder: "AKIA...",
|
|
6299
|
+
type: "text"
|
|
6300
|
+
}
|
|
6301
|
+
},
|
|
6302
|
+
secretAccessKey: {
|
|
6303
|
+
envKey: "HOT_UPDATER_S3_SECRET_ACCESS_KEY",
|
|
6304
|
+
help: "AWS secret access key",
|
|
6305
|
+
persistence: "with-consent",
|
|
6306
|
+
requiredWhen: (inputs) => inputs.authMode === "account",
|
|
6307
|
+
requirementHint: "required for account auth",
|
|
6308
|
+
prompt: {
|
|
6309
|
+
message: "Enter your AWS Secret Access Key",
|
|
6310
|
+
type: "password"
|
|
6311
|
+
}
|
|
6312
|
+
},
|
|
6313
|
+
bucketName: {
|
|
6314
|
+
envKey: "HOT_UPDATER_S3_BUCKET_NAME",
|
|
6315
|
+
help: "S3 bucket name",
|
|
6316
|
+
prompt: {
|
|
6317
|
+
defaultValue: "hot-updater-storage",
|
|
6318
|
+
message: "Enter the name of the new S3 Bucket",
|
|
6319
|
+
placeholder: "hot-updater-storage",
|
|
6320
|
+
type: "text"
|
|
6321
|
+
}
|
|
6322
|
+
},
|
|
6323
|
+
bucketRegion: {
|
|
6324
|
+
envKey: "HOT_UPDATER_S3_REGION",
|
|
6325
|
+
help: "S3 bucket region",
|
|
6326
|
+
prompt: {
|
|
6327
|
+
message: "Enter AWS region for the S3 bucket",
|
|
6328
|
+
type: "select"
|
|
6329
|
+
},
|
|
6330
|
+
validate: isAwsRegionValue
|
|
6331
|
+
},
|
|
6332
|
+
lambdaName: {
|
|
6333
|
+
envKey: "HOT_UPDATER_AWS_LAMBDA_NAME",
|
|
6334
|
+
help: "Lambda@Edge function name",
|
|
6335
|
+
prompt: {
|
|
6336
|
+
defaultValue: "hot-updater-edge",
|
|
6337
|
+
message: "Enter the name of the Lambda@Edge function",
|
|
6338
|
+
placeholder: "hot-updater-edge",
|
|
6339
|
+
type: "text"
|
|
6340
|
+
}
|
|
6341
|
+
},
|
|
6342
|
+
distributionId: {
|
|
6343
|
+
envKey: "HOT_UPDATER_CLOUDFRONT_DISTRIBUTION_ID",
|
|
6344
|
+
help: "Existing CloudFront distribution ID",
|
|
6345
|
+
optional: true
|
|
6346
|
+
},
|
|
6347
|
+
migrationApproved: {
|
|
6348
|
+
envKey: "HOT_UPDATER_AWS_MIGRATION_APPROVED",
|
|
6349
|
+
help: "Allow pending Hot Updater S3 migrations (true)",
|
|
6350
|
+
optional: true,
|
|
6351
|
+
prompt: {
|
|
6352
|
+
message: "Apply pending Hot Updater S3 migrations during init and future infrastructure updates?",
|
|
6353
|
+
type: "confirm"
|
|
6354
|
+
},
|
|
6355
|
+
validate: (value) => value === "true"
|
|
6356
|
+
}
|
|
6357
|
+
}
|
|
6358
|
+
};
|
|
6359
|
+
//#endregion
|
|
6360
|
+
//#region iac/regionLocationMap.ts
|
|
6361
|
+
const regionLocationMap = {
|
|
6362
|
+
"af-south-1": "Cape Town, South Africa",
|
|
6363
|
+
"ap-east-1": "Hong Kong",
|
|
6364
|
+
"ap-east-2": "Taipei, Taiwan",
|
|
6365
|
+
"ap-northeast-1": "Tokyo, Japan",
|
|
6366
|
+
"ap-northeast-2": "Seoul, South Korea",
|
|
6367
|
+
"ap-northeast-3": "Osaka, Japan",
|
|
6368
|
+
"ap-south-1": "Mumbai, India",
|
|
6369
|
+
"ap-south-2": "Hyderabad, India",
|
|
6370
|
+
"ap-southeast-1": "Singapore",
|
|
6371
|
+
"ap-southeast-2": "Sydney, Australia",
|
|
6372
|
+
"ap-southeast-3": "Jakarta, Indonesia",
|
|
6373
|
+
"ap-southeast-4": "Melbourne, Australia",
|
|
6374
|
+
"ap-southeast-5": "Auckland, New Zealand",
|
|
6375
|
+
"ap-southeast-6": "New Zealand",
|
|
6376
|
+
"ap-southeast-7": "Thailand",
|
|
6377
|
+
"ca-central-1": "Montreal, Canada",
|
|
6378
|
+
"ca-west-1": "Calgary, Canada",
|
|
6379
|
+
"cn-north-1": "Beijing, China",
|
|
6380
|
+
"cn-northwest-1": "Ningxia, China",
|
|
6381
|
+
"eu-central-1": "Frankfurt, Germany",
|
|
6382
|
+
"eu-north-1": "Stockholm, Sweden",
|
|
6383
|
+
"eu-south-1": "Milan, Italy",
|
|
6384
|
+
"eu-south-2": "Spain",
|
|
6385
|
+
"eu-west-1": "Ireland",
|
|
6386
|
+
"eu-west-2": "London, UK",
|
|
6387
|
+
"eu-west-3": "Paris, France",
|
|
6388
|
+
"il-central-1": "Tel Aviv, Israel",
|
|
6389
|
+
"me-central-1": "UAE",
|
|
6390
|
+
"me-south-1": "Bahrain",
|
|
6391
|
+
"mx-central-1": "Mexico",
|
|
6392
|
+
"sa-east-1": "São Paulo, Brazil",
|
|
6393
|
+
"us-east-1": "Virginia, USA",
|
|
6394
|
+
"us-east-2": "Ohio, USA",
|
|
6395
|
+
"us-gov-east-1": "US Gov East (Virginia, USA)",
|
|
6396
|
+
"us-gov-west-1": "US Gov West (Oregon, USA)",
|
|
6397
|
+
"us-west-1": "California, USA",
|
|
6398
|
+
"us-west-2": "Oregon, USA",
|
|
6399
|
+
"eu-central-2": "Zurich, Switzerland"
|
|
6400
|
+
};
|
|
6401
|
+
//#endregion
|
|
6402
|
+
//#region iac/awsInitInputs.ts
|
|
6403
|
+
const resolveAwsInitInputs = (existingEnv) => {
|
|
6404
|
+
const { inputs } = initProvider;
|
|
6405
|
+
const savedAuthMode = (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputs.authMode);
|
|
6406
|
+
return {
|
|
6407
|
+
accessKeyId: (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputs.accessKeyId),
|
|
6408
|
+
authMode: isAwsAuthMode(savedAuthMode) ? savedAuthMode : void 0,
|
|
6409
|
+
bucketName: (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputs.bucketName),
|
|
6410
|
+
bucketRegion: (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputs.bucketRegion),
|
|
6411
|
+
distributionId: (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputs.distributionId),
|
|
6412
|
+
lambdaName: (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputs.lambdaName),
|
|
6413
|
+
migrationApproved: (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputs.migrationApproved),
|
|
6414
|
+
profile: (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputs.profile),
|
|
6415
|
+
secretAccessKey: (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputs.secretAccessKey)
|
|
6416
|
+
};
|
|
6417
|
+
};
|
|
6418
|
+
const assertAwsNonInteractiveInputs = (inputs, nonInteractive) => {
|
|
6419
|
+
(0, _hot_updater_cli_tools.assertInitProviderInputs)({
|
|
6420
|
+
inputs: {
|
|
6421
|
+
...inputs,
|
|
6422
|
+
bucketRegion: inputs.bucketRegion && Object.hasOwn(regionLocationMap, inputs.bucketRegion) ? inputs.bucketRegion : void 0
|
|
6423
|
+
},
|
|
6424
|
+
provider: initProvider,
|
|
6425
|
+
strict: nonInteractive
|
|
6426
|
+
});
|
|
6427
|
+
};
|
|
6428
|
+
//#endregion
|
|
6429
|
+
//#region iac/awsAuth.ts
|
|
6430
|
+
const exitWithCredentialError = (error) => {
|
|
6431
|
+
if (error instanceof ExecaError) _hot_updater_cli_tools.p.log.error(error.stdout || error.stderr || error.message);
|
|
6432
|
+
else _hot_updater_cli_tools.p.log.error(error.message);
|
|
6433
|
+
process.exit(1);
|
|
6434
|
+
};
|
|
6435
|
+
const resolveAwsAuth = async (existingEnv, nonInteractive = false) => {
|
|
6436
|
+
const inputDefinitions = initProvider.inputs;
|
|
6437
|
+
const savedMode = (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputDefinitions.authMode);
|
|
6438
|
+
const mode = isAwsAuthMode(savedMode) ? savedMode : void 0;
|
|
6439
|
+
const savedProfile = (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputDefinitions.profile);
|
|
6440
|
+
const savedAccessKeyId = (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputDefinitions.accessKeyId);
|
|
6441
|
+
const savedSecretAccessKey = (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputDefinitions.secretAccessKey);
|
|
6442
|
+
if (nonInteractive && mode === "account" && savedAccessKeyId && savedSecretAccessKey) return {
|
|
6443
|
+
awsProfile: null,
|
|
6444
|
+
configAuthMode: { mode: "account" },
|
|
6445
|
+
credentials: {
|
|
6446
|
+
accessKeyId: savedAccessKeyId,
|
|
6447
|
+
secretAccessKey: savedSecretAccessKey
|
|
6448
|
+
},
|
|
6449
|
+
mode
|
|
6450
|
+
};
|
|
6451
|
+
const inputs = await _hot_updater_cli_tools.p.group({
|
|
6452
|
+
mode: () => nonInteractive && mode ? Promise.resolve(mode) : _hot_updater_cli_tools.p.select({
|
|
6453
|
+
initialValue: mode,
|
|
6454
|
+
message: inputDefinitions.authMode.prompt.message,
|
|
6455
|
+
options: [
|
|
6456
|
+
{
|
|
6457
|
+
label: "Current AWS CLI Session / Default Credential Chain",
|
|
6458
|
+
value: "local-session"
|
|
6459
|
+
},
|
|
6460
|
+
{
|
|
6461
|
+
label: "Shared AWS Profile",
|
|
6462
|
+
value: "shared-profile"
|
|
6463
|
+
},
|
|
6464
|
+
{
|
|
6465
|
+
label: "AWS SSO Login",
|
|
6466
|
+
value: "sso"
|
|
6467
|
+
},
|
|
6468
|
+
{
|
|
6469
|
+
label: "AWS Access Key ID & Secret Access Key",
|
|
6470
|
+
value: "account"
|
|
6471
|
+
}
|
|
6472
|
+
]
|
|
6473
|
+
}),
|
|
6474
|
+
profile: ({ results }) => {
|
|
6475
|
+
if (results.mode !== "shared-profile" && results.mode !== "sso") return Promise.resolve(void 0);
|
|
6476
|
+
if (nonInteractive && savedProfile) return Promise.resolve(savedProfile);
|
|
6477
|
+
const prompt = inputDefinitions.profile.prompt;
|
|
6478
|
+
return _hot_updater_cli_tools.p.text({
|
|
6479
|
+
...(0, _hot_updater_cli_tools.getInitProviderTextPromptValues)(prompt, savedProfile ?? process.env.AWS_PROFILE),
|
|
6480
|
+
message: prompt.message,
|
|
6481
|
+
validate: (value) => (value ?? "").trim() ? void 0 : "AWS profile name is required"
|
|
6482
|
+
});
|
|
6483
|
+
},
|
|
6484
|
+
accessKeyId: ({ results }) => {
|
|
6485
|
+
if (results.mode !== "account") return Promise.resolve(void 0);
|
|
6486
|
+
if (nonInteractive && savedAccessKeyId) return Promise.resolve(savedAccessKeyId);
|
|
6487
|
+
const prompt = inputDefinitions.accessKeyId.prompt;
|
|
6488
|
+
return _hot_updater_cli_tools.p.text({
|
|
6489
|
+
...(0, _hot_updater_cli_tools.getInitProviderTextPromptValues)(prompt, savedAccessKeyId),
|
|
6490
|
+
message: prompt.message,
|
|
6491
|
+
validate: (value) => value ? void 0 : "Access Key ID is required"
|
|
6492
|
+
});
|
|
6493
|
+
},
|
|
6494
|
+
secretAccessKey: ({ results }) => {
|
|
6495
|
+
if (results.mode !== "account") return Promise.resolve(void 0);
|
|
6496
|
+
if (nonInteractive && savedSecretAccessKey) return Promise.resolve(savedSecretAccessKey);
|
|
6497
|
+
return _hot_updater_cli_tools.p.password({
|
|
6498
|
+
message: inputDefinitions.secretAccessKey.prompt.message,
|
|
6499
|
+
validate: (value) => value ? void 0 : "Secret Access Key is required"
|
|
6500
|
+
});
|
|
6501
|
+
}
|
|
6502
|
+
}, { onCancel: () => process.exit(1) });
|
|
6503
|
+
switch (inputs.mode) {
|
|
6504
|
+
case "account":
|
|
6505
|
+
if (!inputs.accessKeyId || !inputs.secretAccessKey) {
|
|
6506
|
+
_hot_updater_cli_tools.p.log.error("AWS access key credentials are required.");
|
|
6507
|
+
process.exit(1);
|
|
6508
|
+
}
|
|
6509
|
+
return {
|
|
6510
|
+
awsProfile: null,
|
|
6511
|
+
configAuthMode: { mode: "account" },
|
|
6512
|
+
credentials: {
|
|
6513
|
+
accessKeyId: inputs.accessKeyId,
|
|
6514
|
+
secretAccessKey: inputs.secretAccessKey
|
|
6515
|
+
},
|
|
6516
|
+
mode: inputs.mode
|
|
6517
|
+
};
|
|
6518
|
+
case "local-session": try {
|
|
6519
|
+
return {
|
|
6520
|
+
awsProfile: null,
|
|
6521
|
+
configAuthMode: {
|
|
6522
|
+
mode: "local",
|
|
6523
|
+
profile: null
|
|
6524
|
+
},
|
|
6525
|
+
credentials: await (0, _aws_sdk_credential_providers.fromNodeProviderChain)()(),
|
|
6526
|
+
mode: inputs.mode
|
|
6527
|
+
};
|
|
6528
|
+
} catch (error) {
|
|
6529
|
+
if (error instanceof Error) return exitWithCredentialError(error);
|
|
6530
|
+
throw error;
|
|
6531
|
+
}
|
|
6532
|
+
case "shared-profile": {
|
|
6533
|
+
if (!inputs.profile) {
|
|
6534
|
+
_hot_updater_cli_tools.p.log.error("AWS profile is required.");
|
|
6535
|
+
process.exit(1);
|
|
6536
|
+
}
|
|
6537
|
+
const profile = inputs.profile.trim();
|
|
6538
|
+
try {
|
|
6539
|
+
return {
|
|
6540
|
+
awsProfile: profile,
|
|
6541
|
+
configAuthMode: {
|
|
6542
|
+
mode: "local",
|
|
6543
|
+
profile
|
|
6544
|
+
},
|
|
6545
|
+
credentials: await (0, _aws_sdk_credential_providers.fromIni)({ profile })(),
|
|
6546
|
+
mode: inputs.mode
|
|
6547
|
+
};
|
|
6548
|
+
} catch (error) {
|
|
6549
|
+
if (error instanceof Error) return exitWithCredentialError(error);
|
|
6550
|
+
throw error;
|
|
6551
|
+
}
|
|
6552
|
+
}
|
|
6553
|
+
case "sso": {
|
|
6554
|
+
if (!inputs.profile) {
|
|
6555
|
+
_hot_updater_cli_tools.p.log.error("AWS SSO profile is required.");
|
|
6556
|
+
process.exit(1);
|
|
6557
|
+
}
|
|
6558
|
+
const profile = inputs.profile.trim();
|
|
6559
|
+
try {
|
|
6560
|
+
let credentials;
|
|
6561
|
+
try {
|
|
6562
|
+
credentials = await (0, _aws_sdk_credential_providers.fromSSO)({ profile })();
|
|
6563
|
+
} catch {
|
|
6564
|
+
if (nonInteractive) throw new _hot_updater_cli_tools.MissingInitInputsError(["active AWS SSO session (`aws sso login`)"]);
|
|
6565
|
+
await execa("aws", [
|
|
6566
|
+
"sso",
|
|
6567
|
+
"login",
|
|
6568
|
+
"--profile",
|
|
6569
|
+
profile
|
|
6570
|
+
], { stdio: "inherit" });
|
|
6571
|
+
credentials = await (0, _aws_sdk_credential_providers.fromSSO)({ profile })();
|
|
6572
|
+
}
|
|
6573
|
+
return {
|
|
6574
|
+
awsProfile: profile,
|
|
6575
|
+
configAuthMode: {
|
|
6576
|
+
mode: "sso",
|
|
6577
|
+
profile
|
|
6578
|
+
},
|
|
6579
|
+
credentials,
|
|
6580
|
+
mode: inputs.mode
|
|
6581
|
+
};
|
|
6582
|
+
} catch (error) {
|
|
6583
|
+
if (error instanceof _hot_updater_cli_tools.MissingInitInputsError) throw error;
|
|
6584
|
+
if (error instanceof Error) return exitWithCredentialError(error);
|
|
6585
|
+
throw error;
|
|
6586
|
+
}
|
|
6587
|
+
}
|
|
6588
|
+
}
|
|
6589
|
+
};
|
|
6590
|
+
//#endregion
|
|
6217
6591
|
//#region ../../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/_internal/globalThis.mjs
|
|
6218
6592
|
const globalThis_ = typeof globalThis === "object" && globalThis || typeof window === "object" && window || typeof self === "object" && self || typeof global === "object" && global || (function() {
|
|
6219
6593
|
return this;
|
|
@@ -6596,6 +6970,16 @@ const buildDistributionConfig = (options) => sanitizeDistributionConfig({
|
|
|
6596
6970
|
});
|
|
6597
6971
|
//#endregion
|
|
6598
6972
|
//#region iac/cloudfrontPagination.ts
|
|
6973
|
+
const collectPaginatedCloudFrontList = async ({ listPage }) => {
|
|
6974
|
+
const items = [];
|
|
6975
|
+
let marker;
|
|
6976
|
+
do {
|
|
6977
|
+
const page = await listPage(marker);
|
|
6978
|
+
items.push(...page.items);
|
|
6979
|
+
marker = page.nextMarker;
|
|
6980
|
+
} while (marker);
|
|
6981
|
+
return items;
|
|
6982
|
+
};
|
|
6599
6983
|
const findInPaginatedCloudFrontList = async ({ listPage, matches }) => {
|
|
6600
6984
|
let marker;
|
|
6601
6985
|
do {
|
|
@@ -6675,6 +7059,11 @@ var CloudFrontManager = class {
|
|
|
6675
7059
|
region: this.region,
|
|
6676
7060
|
credentials: this.credentials
|
|
6677
7061
|
});
|
|
7062
|
+
const selectedDistribution = options.distribution === void 0 ? await this.selectDistribution({
|
|
7063
|
+
bucketName: options.bucketName,
|
|
7064
|
+
distributionId: options.distributionId,
|
|
7065
|
+
nonInteractive: options.nonInteractive
|
|
7066
|
+
}) : options.distribution;
|
|
6678
7067
|
let oacId;
|
|
6679
7068
|
if (!options.functionArn.split(":")[4]) throw new Error("Failed to get AWS account ID");
|
|
6680
7069
|
try {
|
|
@@ -6701,29 +7090,6 @@ var CloudFrontManager = class {
|
|
|
6701
7090
|
} catch (error) {
|
|
6702
7091
|
throw new Error(`Failed to get or create shared cache policy: ${error instanceof Error ? error.message : String(error)}`);
|
|
6703
7092
|
}
|
|
6704
|
-
const matchingDistributions = [];
|
|
6705
|
-
try {
|
|
6706
|
-
const items = (await cloudfrontClient.listDistributions({})).DistributionList?.Items || [];
|
|
6707
|
-
for (const dist of items) if ((dist.Origins?.Items || []).some((origin) => origin.DomainName === bucketDomain)) matchingDistributions.push({
|
|
6708
|
-
Id: dist.Id,
|
|
6709
|
-
DomainName: dist.DomainName
|
|
6710
|
-
});
|
|
6711
|
-
} catch (error) {
|
|
6712
|
-
console.error("Error listing CloudFront distributions:", error);
|
|
6713
|
-
}
|
|
6714
|
-
let selectedDistribution = null;
|
|
6715
|
-
if (matchingDistributions.length === 1) selectedDistribution = matchingDistributions[0];
|
|
6716
|
-
else if (matchingDistributions.length > 1) {
|
|
6717
|
-
const selectedDistributionStr = await _hot_updater_cli_tools.p.select({
|
|
6718
|
-
message: "Multiple CloudFront distributions found. Please select one to use:",
|
|
6719
|
-
options: matchingDistributions.map((dist) => ({
|
|
6720
|
-
value: JSON.stringify(dist),
|
|
6721
|
-
label: `${dist.Id} (${dist.DomainName})`
|
|
6722
|
-
}))
|
|
6723
|
-
});
|
|
6724
|
-
if (_hot_updater_cli_tools.p.isCancel(selectedDistributionStr)) process.exit(0);
|
|
6725
|
-
selectedDistribution = JSON.parse(selectedDistributionStr);
|
|
6726
|
-
}
|
|
6727
7093
|
const newOverrides = buildDistributionConfigOverrides({
|
|
6728
7094
|
bucketName: options.bucketName,
|
|
6729
7095
|
bucketDomain,
|
|
@@ -6733,6 +7099,7 @@ var CloudFrontManager = class {
|
|
|
6733
7099
|
sharedCachePolicyId
|
|
6734
7100
|
});
|
|
6735
7101
|
if (selectedDistribution) {
|
|
7102
|
+
await (0, _hot_updater_cli_tools.makeEnv)({ HOT_UPDATER_CLOUDFRONT_DISTRIBUTION_ID: selectedDistribution.Id });
|
|
6736
7103
|
_hot_updater_cli_tools.p.log.success(`Existing CloudFront distribution selected. Distribution ID: ${selectedDistribution.Id}.`);
|
|
6737
7104
|
try {
|
|
6738
7105
|
const { DistributionConfig, ETag } = await cloudfrontClient.getDistributionConfig({ Id: selectedDistribution.Id });
|
|
@@ -6777,6 +7144,7 @@ var CloudFrontManager = class {
|
|
|
6777
7144
|
if (!distResp.Distribution?.Id || !distResp.Distribution?.DomainName) throw new Error("Failed to create CloudFront distribution: No ID or DomainName returned");
|
|
6778
7145
|
const distributionId = distResp.Distribution.Id;
|
|
6779
7146
|
const distributionDomain = distResp.Distribution.DomainName;
|
|
7147
|
+
await (0, _hot_updater_cli_tools.makeEnv)({ HOT_UPDATER_CLOUDFRONT_DISTRIBUTION_ID: distributionId });
|
|
6780
7148
|
_hot_updater_cli_tools.p.log.success(`Created new CloudFront distribution. Distribution ID: ${distributionId}`);
|
|
6781
7149
|
let retryCount = 0;
|
|
6782
7150
|
await _hot_updater_cli_tools.p.tasks([{
|
|
@@ -6802,6 +7170,53 @@ var CloudFrontManager = class {
|
|
|
6802
7170
|
throw error;
|
|
6803
7171
|
}
|
|
6804
7172
|
}
|
|
7173
|
+
async selectDistribution({ bucketName, distributionId, nonInteractive }) {
|
|
7174
|
+
const bucketDomain = `${bucketName}.s3.${this.region}.amazonaws.com`;
|
|
7175
|
+
const cloudfrontClient = new _aws_sdk_client_cloudfront.CloudFront({
|
|
7176
|
+
region: this.region,
|
|
7177
|
+
credentials: this.credentials
|
|
7178
|
+
});
|
|
7179
|
+
const distributions = await collectPaginatedCloudFrontList({ listPage: async (marker) => {
|
|
7180
|
+
const options = marker ? { Marker: marker } : {};
|
|
7181
|
+
const response = await cloudfrontClient.listDistributions(options);
|
|
7182
|
+
return {
|
|
7183
|
+
items: response.DistributionList?.Items ?? [],
|
|
7184
|
+
nextMarker: response.DistributionList?.NextMarker
|
|
7185
|
+
};
|
|
7186
|
+
} });
|
|
7187
|
+
const matchingDistributions = distributions.flatMap((distribution) => {
|
|
7188
|
+
return (distribution.Origins?.Items ?? []).some((origin) => origin.DomainName === bucketDomain) && distribution.Id && distribution.DomainName ? [{
|
|
7189
|
+
Id: distribution.Id,
|
|
7190
|
+
DomainName: distribution.DomainName
|
|
7191
|
+
}] : [];
|
|
7192
|
+
});
|
|
7193
|
+
const savedDistribution = matchingDistributions.find((distribution) => distribution.Id === distributionId);
|
|
7194
|
+
const savedDistributionExists = distributions.some((distribution) => distribution.Id === distributionId);
|
|
7195
|
+
if (nonInteractive && savedDistribution) return savedDistribution;
|
|
7196
|
+
if (distributionId && !savedDistribution) {
|
|
7197
|
+
if (matchingDistributions.length === 0 && !savedDistributionExists) {
|
|
7198
|
+
_hot_updater_cli_tools.p.log.warn("Saved CloudFront distribution was not found. A new distribution will be created.");
|
|
7199
|
+
return null;
|
|
7200
|
+
}
|
|
7201
|
+
if (nonInteractive) throw new _hot_updater_cli_tools.MissingInitInputsError(["HOT_UPDATER_CLOUDFRONT_DISTRIBUTION_ID"]);
|
|
7202
|
+
_hot_updater_cli_tools.p.log.warn("Saved CloudFront distribution was not found. Select a distribution again.");
|
|
7203
|
+
}
|
|
7204
|
+
if (matchingDistributions.length === 0) return null;
|
|
7205
|
+
if (nonInteractive) {
|
|
7206
|
+
if (!distributionId && matchingDistributions.length === 1) return matchingDistributions[0] ?? null;
|
|
7207
|
+
throw new _hot_updater_cli_tools.MissingInitInputsError(["HOT_UPDATER_CLOUDFRONT_DISTRIBUTION_ID"]);
|
|
7208
|
+
}
|
|
7209
|
+
const selectedDistributionId = await _hot_updater_cli_tools.p.select({
|
|
7210
|
+
initialValue: savedDistribution?.Id ?? matchingDistributions[0]?.Id,
|
|
7211
|
+
message: "Select a CloudFront distribution:",
|
|
7212
|
+
options: matchingDistributions.map((distribution) => ({
|
|
7213
|
+
value: distribution.Id,
|
|
7214
|
+
label: `${distribution.Id} (${distribution.DomainName})`
|
|
7215
|
+
}))
|
|
7216
|
+
});
|
|
7217
|
+
if (_hot_updater_cli_tools.p.isCancel(selectedDistributionId)) process.exit(0);
|
|
7218
|
+
return matchingDistributions.find((distribution) => distribution.Id === selectedDistributionId) ?? null;
|
|
7219
|
+
}
|
|
6805
7220
|
};
|
|
6806
7221
|
//#endregion
|
|
6807
7222
|
//#region iac/iam.ts
|
|
@@ -6898,14 +7313,8 @@ var LambdaEdgeDeployer = class {
|
|
|
6898
7313
|
constructor(credentials) {
|
|
6899
7314
|
this.credentials = credentials;
|
|
6900
7315
|
}
|
|
6901
|
-
async deploy(lambdaRoleArn, config) {
|
|
7316
|
+
async deploy(lambdaRoleArn, lambdaName, config) {
|
|
6902
7317
|
const cwd = (0, _hot_updater_cli_tools.getCwd)();
|
|
6903
|
-
const lambdaName = await _hot_updater_cli_tools.p.text({
|
|
6904
|
-
message: "Enter the name of the Lambda@Edge function",
|
|
6905
|
-
defaultValue: "hot-updater-edge",
|
|
6906
|
-
placeholder: "hot-updater-edge"
|
|
6907
|
-
});
|
|
6908
|
-
if (_hot_updater_cli_tools.p.isCancel(lambdaName)) process.exit(1);
|
|
6909
7318
|
const lambdaPath = require.resolve("@hot-updater/aws/lambda");
|
|
6910
7319
|
const { tmpDir, removeTmpDir } = await (0, _hot_updater_cli_tools.copyDirToTmp)(path.default.dirname(lambdaPath));
|
|
6911
7320
|
const indexPath = path.default.join(tmpDir, "index.cjs");
|
|
@@ -7302,48 +7711,6 @@ var Migration0001HotUpdater0_18_0 = class extends S3Migration {
|
|
|
7302
7711
|
}
|
|
7303
7712
|
};
|
|
7304
7713
|
//#endregion
|
|
7305
|
-
//#region iac/regionLocationMap.ts
|
|
7306
|
-
const regionLocationMap = {
|
|
7307
|
-
"af-south-1": "Cape Town, South Africa",
|
|
7308
|
-
"ap-east-1": "Hong Kong",
|
|
7309
|
-
"ap-east-2": "Taipei, Taiwan",
|
|
7310
|
-
"ap-northeast-1": "Tokyo, Japan",
|
|
7311
|
-
"ap-northeast-2": "Seoul, South Korea",
|
|
7312
|
-
"ap-northeast-3": "Osaka, Japan",
|
|
7313
|
-
"ap-south-1": "Mumbai, India",
|
|
7314
|
-
"ap-south-2": "Hyderabad, India",
|
|
7315
|
-
"ap-southeast-1": "Singapore",
|
|
7316
|
-
"ap-southeast-2": "Sydney, Australia",
|
|
7317
|
-
"ap-southeast-3": "Jakarta, Indonesia",
|
|
7318
|
-
"ap-southeast-4": "Melbourne, Australia",
|
|
7319
|
-
"ap-southeast-5": "Auckland, New Zealand",
|
|
7320
|
-
"ap-southeast-6": "New Zealand",
|
|
7321
|
-
"ap-southeast-7": "Thailand",
|
|
7322
|
-
"ca-central-1": "Montreal, Canada",
|
|
7323
|
-
"ca-west-1": "Calgary, Canada",
|
|
7324
|
-
"cn-north-1": "Beijing, China",
|
|
7325
|
-
"cn-northwest-1": "Ningxia, China",
|
|
7326
|
-
"eu-central-1": "Frankfurt, Germany",
|
|
7327
|
-
"eu-north-1": "Stockholm, Sweden",
|
|
7328
|
-
"eu-south-1": "Milan, Italy",
|
|
7329
|
-
"eu-south-2": "Spain",
|
|
7330
|
-
"eu-west-1": "Ireland",
|
|
7331
|
-
"eu-west-2": "London, UK",
|
|
7332
|
-
"eu-west-3": "Paris, France",
|
|
7333
|
-
"il-central-1": "Tel Aviv, Israel",
|
|
7334
|
-
"me-central-1": "UAE",
|
|
7335
|
-
"me-south-1": "Bahrain",
|
|
7336
|
-
"mx-central-1": "Mexico",
|
|
7337
|
-
"sa-east-1": "São Paulo, Brazil",
|
|
7338
|
-
"us-east-1": "Virginia, USA",
|
|
7339
|
-
"us-east-2": "Ohio, USA",
|
|
7340
|
-
"us-gov-east-1": "US Gov East (Virginia, USA)",
|
|
7341
|
-
"us-gov-west-1": "US Gov West (Oregon, USA)",
|
|
7342
|
-
"us-west-1": "California, USA",
|
|
7343
|
-
"us-west-2": "Oregon, USA",
|
|
7344
|
-
"eu-central-2": "Zurich, Switzerland"
|
|
7345
|
-
};
|
|
7346
|
-
//#endregion
|
|
7347
7714
|
//#region iac/s3.ts
|
|
7348
7715
|
function normalizeBucketRegion(region) {
|
|
7349
7716
|
if (region == null) return "us-east-1";
|
|
@@ -7361,7 +7728,7 @@ var S3Manager = class {
|
|
|
7361
7728
|
credentials: this.credentials
|
|
7362
7729
|
});
|
|
7363
7730
|
const buckets = (await s3Client.listBuckets({})).Buckets ?? [];
|
|
7364
|
-
return await Promise.all(buckets.filter((bucket) => bucket.Name).map(async (bucket) => {
|
|
7731
|
+
return await Promise.all(buckets.filter((bucket) => typeof bucket.Name === "string").map(async (bucket) => {
|
|
7365
7732
|
const { LocationConstraint } = await s3Client.getBucketLocation({ Bucket: bucket.Name });
|
|
7366
7733
|
return {
|
|
7367
7734
|
name: bucket.Name,
|
|
@@ -7379,7 +7746,7 @@ var S3Manager = class {
|
|
|
7379
7746
|
});
|
|
7380
7747
|
_hot_updater_cli_tools.p.log.info(`Created S3 bucket: ${bucketName}`);
|
|
7381
7748
|
}
|
|
7382
|
-
async runMigrations({ bucketName, region, migrations }) {
|
|
7749
|
+
async runMigrations({ approved, bucketName, nonInteractive, region, migrations }) {
|
|
7383
7750
|
const migrator = new S3Migrator({
|
|
7384
7751
|
s3: new _aws_sdk_client_s3.S3({
|
|
7385
7752
|
region,
|
|
@@ -7390,16 +7757,22 @@ var S3Manager = class {
|
|
|
7390
7757
|
});
|
|
7391
7758
|
const { pending } = await migrator.list();
|
|
7392
7759
|
await migrator.migrate({ dryRun: true });
|
|
7393
|
-
if (pending.length
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7760
|
+
if (pending.length === 0) return false;
|
|
7761
|
+
_hot_updater_cli_tools.p.log.step("Pending migrations:");
|
|
7762
|
+
for (const migration of pending) _hot_updater_cli_tools.p.log.step(`- ${migration.name}`);
|
|
7763
|
+
if (!nonInteractive || !approved) {
|
|
7764
|
+
if (nonInteractive) throw new _hot_updater_cli_tools.MissingInitInputsError(["HOT_UPDATER_AWS_MIGRATION_APPROVED"]);
|
|
7765
|
+
const confirm = await _hot_updater_cli_tools.p.confirm({
|
|
7766
|
+
initialValue: approved,
|
|
7767
|
+
message: "Do you want to continue?"
|
|
7768
|
+
});
|
|
7769
|
+
if (_hot_updater_cli_tools.p.isCancel(confirm) || !confirm) {
|
|
7770
|
+
_hot_updater_cli_tools.p.log.info("Migration cancelled.");
|
|
7771
|
+
process.exit(1);
|
|
7772
|
+
}
|
|
7401
7773
|
}
|
|
7402
7774
|
await migrator.migrate({ dryRun: false });
|
|
7775
|
+
return true;
|
|
7403
7776
|
}
|
|
7404
7777
|
async updateBucketPolicy({ bucketName, region, distributionId, accountId }) {
|
|
7405
7778
|
const s3Client = new _aws_sdk_client_s3.S3({
|
|
@@ -7595,118 +7968,34 @@ const checkIfAwsCliInstalled = async () => {
|
|
|
7595
7968
|
return false;
|
|
7596
7969
|
}
|
|
7597
7970
|
};
|
|
7598
|
-
const
|
|
7971
|
+
const isAwsRegion = (value) => {
|
|
7972
|
+
return value !== void 0 && Object.hasOwn(regionLocationMap, value);
|
|
7973
|
+
};
|
|
7974
|
+
const runInit = async ({ build, envFile }) => {
|
|
7975
|
+
const nonInteractive = envFile !== void 0;
|
|
7976
|
+
const initEnvSources = await (0, _hot_updater_cli_tools.readHotUpdaterInitEnv)(process.cwd(), envFile);
|
|
7977
|
+
const { managedEnv } = initEnvSources;
|
|
7978
|
+
const providerEnv = (0, _hot_updater_cli_tools.getHotUpdaterInitInputEnv)(initEnvSources, nonInteractive);
|
|
7979
|
+
const savedInputs = resolveAwsInitInputs(providerEnv);
|
|
7980
|
+
assertAwsNonInteractiveInputs(savedInputs, nonInteractive);
|
|
7599
7981
|
if (!await checkIfAwsCliInstalled()) {
|
|
7600
7982
|
_hot_updater_cli_tools.p.log.error(`AWS CLI is not installed. Please visit ${(0, _hot_updater_cli_tools.link)("https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html")} for installation instructions`);
|
|
7601
7983
|
process.exit(1);
|
|
7602
7984
|
}
|
|
7603
|
-
let credentials;
|
|
7604
|
-
let configAuthMode = { mode: "account" };
|
|
7605
|
-
let awsProfile = null;
|
|
7606
|
-
const mode = await _hot_updater_cli_tools.p.select({
|
|
7607
|
-
message: "Select the mode to login to AWS",
|
|
7608
|
-
options: [
|
|
7609
|
-
{
|
|
7610
|
-
label: "Current AWS CLI Session / Default Credential Chain",
|
|
7611
|
-
value: "local-session"
|
|
7612
|
-
},
|
|
7613
|
-
{
|
|
7614
|
-
label: "Shared AWS Profile",
|
|
7615
|
-
value: "shared-profile"
|
|
7616
|
-
},
|
|
7617
|
-
{
|
|
7618
|
-
label: "AWS SSO Login",
|
|
7619
|
-
value: "sso"
|
|
7620
|
-
},
|
|
7621
|
-
{
|
|
7622
|
-
label: "AWS Access Key ID & Secret Access Key",
|
|
7623
|
-
value: "account"
|
|
7624
|
-
}
|
|
7625
|
-
]
|
|
7626
|
-
});
|
|
7627
|
-
if (_hot_updater_cli_tools.p.isCancel(mode)) process.exit(1);
|
|
7628
7985
|
_hot_updater_cli_tools.p.log.message(_hot_updater_cli_tools.colors.blue("The following permissions are required:"));
|
|
7629
7986
|
_hot_updater_cli_tools.p.log.message(`${_hot_updater_cli_tools.colors.blue("AmazonS3FullAccess")}: Create and read S3 buckets`);
|
|
7630
7987
|
_hot_updater_cli_tools.p.log.message(`${_hot_updater_cli_tools.colors.blue("AWSLambda_FullAccess")}: Create and update Lambda functions`);
|
|
7631
7988
|
_hot_updater_cli_tools.p.log.message(`${_hot_updater_cli_tools.colors.blue("CloudFrontFullAccess")}: Create and update CloudFront distributions`);
|
|
7632
7989
|
_hot_updater_cli_tools.p.log.message(`${_hot_updater_cli_tools.colors.blue("IAMFullAccess")}: Get or create IAM roles for Lambda@Edge`);
|
|
7633
7990
|
_hot_updater_cli_tools.p.log.message(`${_hot_updater_cli_tools.colors.blue("AmazonSSMFullAccess")}: Access to SSM Parameters for storing CloudFront key pairs`);
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
configAuthMode = {
|
|
7643
|
-
mode: "sso",
|
|
7644
|
-
profile
|
|
7645
|
-
};
|
|
7646
|
-
await execa("aws", [
|
|
7647
|
-
"sso",
|
|
7648
|
-
"login",
|
|
7649
|
-
"--profile",
|
|
7650
|
-
profile
|
|
7651
|
-
], {
|
|
7652
|
-
stdio: "inherit",
|
|
7653
|
-
shell: true
|
|
7654
|
-
});
|
|
7655
|
-
credentials = await (0, _aws_sdk_credential_providers.fromSSO)({ profile })();
|
|
7656
|
-
} catch (error) {
|
|
7657
|
-
if (error instanceof ExecaError) _hot_updater_cli_tools.p.log.error(error.stdout || error.stderr || error.message);
|
|
7658
|
-
process.exit(1);
|
|
7659
|
-
}
|
|
7660
|
-
else if (mode === "local-session") try {
|
|
7661
|
-
configAuthMode = {
|
|
7662
|
-
mode: "local",
|
|
7663
|
-
profile: null
|
|
7664
|
-
};
|
|
7665
|
-
credentials = await (0, _aws_sdk_credential_providers.fromNodeProviderChain)()();
|
|
7666
|
-
} catch (error) {
|
|
7667
|
-
if (error instanceof Error) _hot_updater_cli_tools.p.log.error(error.message);
|
|
7668
|
-
process.exit(1);
|
|
7669
|
-
}
|
|
7670
|
-
else if (mode === "shared-profile") try {
|
|
7671
|
-
const profile = await _hot_updater_cli_tools.p.text({
|
|
7672
|
-
message: "Enter the AWS profile name",
|
|
7673
|
-
defaultValue: process.env.AWS_PROFILE ?? "default",
|
|
7674
|
-
placeholder: process.env.AWS_PROFILE ?? "default",
|
|
7675
|
-
validate: (value) => (value ?? "").trim() ? void 0 : "AWS profile name is required"
|
|
7676
|
-
});
|
|
7677
|
-
if (_hot_updater_cli_tools.p.isCancel(profile)) process.exit(1);
|
|
7678
|
-
awsProfile = profile.trim();
|
|
7679
|
-
configAuthMode = {
|
|
7680
|
-
mode: "local",
|
|
7681
|
-
profile: awsProfile
|
|
7682
|
-
};
|
|
7683
|
-
credentials = await (0, _aws_sdk_credential_providers.fromIni)({ profile: awsProfile })();
|
|
7684
|
-
} catch (error) {
|
|
7685
|
-
if (error instanceof Error) _hot_updater_cli_tools.p.log.error(error.message);
|
|
7686
|
-
process.exit(1);
|
|
7687
|
-
}
|
|
7688
|
-
else {
|
|
7689
|
-
const creds = await _hot_updater_cli_tools.p.group({
|
|
7690
|
-
accessKeyId: () => _hot_updater_cli_tools.p.text({
|
|
7691
|
-
message: "Enter your AWS Access Key ID",
|
|
7692
|
-
validate: (value) => value ? void 0 : "Access Key ID is required"
|
|
7693
|
-
}),
|
|
7694
|
-
secretAccessKey: () => _hot_updater_cli_tools.p.password({
|
|
7695
|
-
message: "Enter your AWS Secret Access Key",
|
|
7696
|
-
validate: (value) => value ? void 0 : "Secret Access Key is required"
|
|
7697
|
-
})
|
|
7698
|
-
});
|
|
7699
|
-
if (_hot_updater_cli_tools.p.isCancel(creds)) process.exit(1);
|
|
7700
|
-
credentials = {
|
|
7701
|
-
accessKeyId: creds.accessKeyId,
|
|
7702
|
-
secretAccessKey: creds.secretAccessKey
|
|
7703
|
-
};
|
|
7704
|
-
configAuthMode = { mode: "account" };
|
|
7705
|
-
}
|
|
7706
|
-
if (!credentials) {
|
|
7707
|
-
_hot_updater_cli_tools.p.log.error("Couldn't fetch the credentials.");
|
|
7708
|
-
process.exit(1);
|
|
7709
|
-
}
|
|
7991
|
+
const { awsProfile, configAuthMode, credentials, mode } = await resolveAwsAuth(providerEnv, nonInteractive);
|
|
7992
|
+
const resolvedAuthInputs = {
|
|
7993
|
+
...savedInputs,
|
|
7994
|
+
accessKeyId: mode === "account" ? credentials.accessKeyId : savedInputs.accessKeyId,
|
|
7995
|
+
authMode: mode,
|
|
7996
|
+
profile: awsProfile ?? void 0,
|
|
7997
|
+
secretAccessKey: mode === "account" ? credentials.secretAccessKey : savedInputs.secretAccessKey
|
|
7998
|
+
};
|
|
7710
7999
|
const s3Manager = new S3Manager(credentials);
|
|
7711
8000
|
let availableBuckets = [];
|
|
7712
8001
|
try {
|
|
@@ -7721,54 +8010,109 @@ const runInit = async ({ build }) => {
|
|
|
7721
8010
|
throw e;
|
|
7722
8011
|
}
|
|
7723
8012
|
const createKey = `create/${Math.random().toString(36).substring(2, 15)}`;
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
|
|
8013
|
+
const savedBucketName = savedInputs.bucketName;
|
|
8014
|
+
const savedBucketRegion = savedInputs.bucketRegion;
|
|
8015
|
+
const existingBucket = availableBuckets.find((bucket) => bucket.name === savedBucketName);
|
|
8016
|
+
const createSavedBucket = nonInteractive && savedBucketName !== void 0 && isAwsRegion(savedBucketRegion) && !existingBucket;
|
|
8017
|
+
if (createSavedBucket && savedInputs.migrationApproved !== "true") throw new _hot_updater_cli_tools.MissingInitInputsError(["HOT_UPDATER_AWS_MIGRATION_APPROVED"]);
|
|
8018
|
+
if (savedBucketName && !existingBucket && !createSavedBucket) _hot_updater_cli_tools.p.log.warn("Saved S3 bucket was not found. Select a bucket again.");
|
|
8019
|
+
const savedLambdaName = savedInputs.lambdaName;
|
|
8020
|
+
const resourceInputs = await _hot_updater_cli_tools.p.group({
|
|
8021
|
+
bucketSelection: () => {
|
|
8022
|
+
if (nonInteractive && existingBucket) return Promise.resolve(existingBucket.name);
|
|
8023
|
+
if (createSavedBucket) return Promise.resolve(createKey);
|
|
8024
|
+
return _hot_updater_cli_tools.p.select({
|
|
8025
|
+
initialValue: existingBucket?.name ?? availableBuckets[0]?.name,
|
|
8026
|
+
message: "S3 Bucket List",
|
|
8027
|
+
options: [...availableBuckets.map((bucket) => ({
|
|
8028
|
+
value: bucket.name,
|
|
8029
|
+
label: `${bucket.name} (${bucket.region})`
|
|
8030
|
+
})), {
|
|
8031
|
+
value: createKey,
|
|
8032
|
+
label: "Create New S3 Bucket"
|
|
8033
|
+
}]
|
|
8034
|
+
});
|
|
8035
|
+
},
|
|
8036
|
+
bucketName: ({ results }) => results.bucketSelection === createKey ? createSavedBucket ? Promise.resolve(savedBucketName) : _hot_updater_cli_tools.p.text({
|
|
8037
|
+
...(0, _hot_updater_cli_tools.getInitProviderTextPromptValues)(initProvider.inputs.bucketName.prompt, savedBucketName),
|
|
8038
|
+
message: initProvider.inputs.bucketName.prompt.message,
|
|
8039
|
+
validate: (value) => value ? void 0 : "S3 bucket name is required"
|
|
8040
|
+
}) : Promise.resolve(results.bucketSelection),
|
|
8041
|
+
bucketRegion: ({ results }) => results.bucketSelection === createKey ? createSavedBucket ? Promise.resolve(savedBucketRegion) : _hot_updater_cli_tools.p.select({
|
|
8042
|
+
initialValue: isAwsRegion(savedBucketRegion) ? savedBucketRegion : void 0,
|
|
8043
|
+
message: initProvider.inputs.bucketRegion.prompt.message,
|
|
7746
8044
|
options: Object.entries(regionLocationMap).map(([region, location]) => ({
|
|
7747
8045
|
label: `${region} (${location})`,
|
|
7748
8046
|
value: region
|
|
7749
8047
|
}))
|
|
7750
|
-
})
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
|
|
8048
|
+
}) : Promise.resolve(availableBuckets.find((bucket) => bucket.name === results.bucketSelection)?.region),
|
|
8049
|
+
lambdaName: () => nonInteractive && savedLambdaName ? Promise.resolve(savedLambdaName) : _hot_updater_cli_tools.p.text({
|
|
8050
|
+
...(0, _hot_updater_cli_tools.getInitProviderTextPromptValues)(initProvider.inputs.lambdaName.prompt, savedLambdaName),
|
|
8051
|
+
message: initProvider.inputs.lambdaName.prompt.message,
|
|
8052
|
+
validate: (value) => value ? void 0 : "Lambda function name is required"
|
|
8053
|
+
})
|
|
8054
|
+
}, { onCancel: () => process.exit(1) });
|
|
8055
|
+
const { bucketName, bucketRegion, lambdaName } = resourceInputs;
|
|
8056
|
+
if (!bucketName || !lambdaName) {
|
|
8057
|
+
_hot_updater_cli_tools.p.log.error("AWS resource names are required.");
|
|
8058
|
+
process.exit(1);
|
|
7754
8059
|
}
|
|
7755
|
-
if (!bucketRegion) {
|
|
7756
|
-
_hot_updater_cli_tools.p.log.error("
|
|
8060
|
+
if (!isAwsRegion(bucketRegion)) {
|
|
8061
|
+
_hot_updater_cli_tools.p.log.error("AWS bucket region is required.");
|
|
7757
8062
|
process.exit(1);
|
|
7758
8063
|
}
|
|
8064
|
+
const cloudFrontManager = new CloudFrontManager(bucketRegion, credentials);
|
|
8065
|
+
const selectedDistribution = await cloudFrontManager.selectDistribution({
|
|
8066
|
+
bucketName,
|
|
8067
|
+
distributionId: savedInputs.distributionId,
|
|
8068
|
+
nonInteractive
|
|
8069
|
+
});
|
|
8070
|
+
const resolvedInputs = {
|
|
8071
|
+
...resolvedAuthInputs,
|
|
8072
|
+
bucketName,
|
|
8073
|
+
bucketRegion,
|
|
8074
|
+
distributionId: selectedDistribution?.Id,
|
|
8075
|
+
lambdaName,
|
|
8076
|
+
migrationApproved: savedInputs.migrationApproved
|
|
8077
|
+
};
|
|
8078
|
+
const initEnv = (0, _hot_updater_cli_tools.getInitProviderEnvVars)({
|
|
8079
|
+
includeConsentInputs: await (0, _hot_updater_cli_tools.confirmInitInputPersistence)({
|
|
8080
|
+
existingEnv: managedEnv,
|
|
8081
|
+
inputs: resolvedInputs,
|
|
8082
|
+
nonInteractive,
|
|
8083
|
+
provider: initProvider
|
|
8084
|
+
}),
|
|
8085
|
+
inputs: resolvedInputs,
|
|
8086
|
+
provider: initProvider
|
|
8087
|
+
});
|
|
8088
|
+
const accessKeyEnvKey = initProvider.inputs.accessKeyId.envKey;
|
|
8089
|
+
const secretAccessKeyEnvKey = initProvider.inputs.secretAccessKey.envKey;
|
|
8090
|
+
await (0, _hot_updater_cli_tools.makeEnv)({
|
|
8091
|
+
...initEnv,
|
|
8092
|
+
...initEnv[accessKeyEnvKey] ? { [accessKeyEnvKey]: {
|
|
8093
|
+
comment: "The current key may have excessive permissions. Update it with an S3FullAccess and CloudFrontFullAccess key.",
|
|
8094
|
+
value: initEnv[accessKeyEnvKey]
|
|
8095
|
+
} } : {},
|
|
8096
|
+
...initEnv[secretAccessKeyEnvKey] ? { [secretAccessKeyEnvKey]: {
|
|
8097
|
+
comment: "The current key may have excessive permissions. Update it with an S3FullAccess and CloudFrontFullAccess key.",
|
|
8098
|
+
value: initEnv[secretAccessKeyEnvKey]
|
|
8099
|
+
} } : {}
|
|
8100
|
+
});
|
|
8101
|
+
if (resourceInputs.bucketSelection === createKey) await s3Manager.createBucket(bucketName, bucketRegion);
|
|
7759
8102
|
_hot_updater_cli_tools.p.log.info(`Selected S3 Bucket: ${bucketName} (${bucketRegion})`);
|
|
7760
|
-
await s3Manager.runMigrations({
|
|
8103
|
+
if (await s3Manager.runMigrations({
|
|
8104
|
+
approved: savedInputs.migrationApproved === "true",
|
|
7761
8105
|
bucketName,
|
|
8106
|
+
nonInteractive,
|
|
7762
8107
|
region: bucketRegion,
|
|
7763
8108
|
migrations: [new Migration0001HotUpdater0_13_0(), new Migration0001HotUpdater0_18_0()]
|
|
7764
|
-
});
|
|
8109
|
+
}) && savedInputs.migrationApproved !== "true") await (0, _hot_updater_cli_tools.makeEnv)({ [initProvider.inputs.migrationApproved.envKey]: "true" });
|
|
7765
8110
|
const lambdaRoleArn = await new IAMManager(bucketRegion, credentials).createOrSelectRole();
|
|
7766
8111
|
const keyPair = await new SSMKeyPairManager(bucketRegion, credentials).getOrCreateKeyPair(`/hot-updater/${bucketName}/keypair`);
|
|
7767
|
-
const cloudFrontManager = new CloudFrontManager(bucketRegion, credentials);
|
|
7768
8112
|
const { publicKeyId, keyGroupId } = await cloudFrontManager.getOrCreateKeyGroup(keyPair.publicKey);
|
|
7769
8113
|
const lambdaEdgeDeployer = new LambdaEdgeDeployer(credentials);
|
|
7770
8114
|
const ssmParameterName = `/hot-updater/${bucketName}/keypair`;
|
|
7771
|
-
const { functionArn } = await lambdaEdgeDeployer.deploy(lambdaRoleArn, {
|
|
8115
|
+
const { functionArn } = await lambdaEdgeDeployer.deploy(lambdaRoleArn, lambdaName, {
|
|
7772
8116
|
bucketName,
|
|
7773
8117
|
publicKeyId,
|
|
7774
8118
|
ssmParameterName,
|
|
@@ -7777,6 +8121,7 @@ const runInit = async ({ build }) => {
|
|
|
7777
8121
|
const { distributionDomain, distributionId } = await cloudFrontManager.createOrUpdateDistribution({
|
|
7778
8122
|
keyGroupId,
|
|
7779
8123
|
bucketName,
|
|
8124
|
+
distribution: selectedDistribution,
|
|
7780
8125
|
functionArn
|
|
7781
8126
|
});
|
|
7782
8127
|
const accountId = functionArn.split(":")[4];
|
|
@@ -7787,22 +8132,7 @@ const runInit = async ({ build }) => {
|
|
|
7787
8132
|
accountId
|
|
7788
8133
|
});
|
|
7789
8134
|
const configWriteResult = await (0, _hot_updater_cli_tools.writeHotUpdaterConfig)(getConfigScaffold(build, configAuthMode));
|
|
7790
|
-
await (0, _hot_updater_cli_tools.makeEnv)({
|
|
7791
|
-
HOT_UPDATER_S3_BUCKET_NAME: bucketName,
|
|
7792
|
-
HOT_UPDATER_S3_REGION: bucketRegion,
|
|
7793
|
-
...mode === "account" ? {
|
|
7794
|
-
HOT_UPDATER_S3_ACCESS_KEY_ID: {
|
|
7795
|
-
comment: "The current key may have excessive permissions. Update it with an S3FullAccess and CloudFrontFullAccess key.",
|
|
7796
|
-
value: credentials.accessKeyId
|
|
7797
|
-
},
|
|
7798
|
-
HOT_UPDATER_S3_SECRET_ACCESS_KEY: {
|
|
7799
|
-
comment: "The current key may have excessive permissions. Update it with an S3FullAccess and CloudFrontFullAccess key.",
|
|
7800
|
-
value: credentials.secretAccessKey
|
|
7801
|
-
}
|
|
7802
|
-
} : {},
|
|
7803
|
-
...awsProfile !== null ? { HOT_UPDATER_AWS_PROFILE: awsProfile } : {},
|
|
7804
|
-
HOT_UPDATER_CLOUDFRONT_DISTRIBUTION_ID: distributionId
|
|
7805
|
-
});
|
|
8135
|
+
await (0, _hot_updater_cli_tools.makeEnv)({ [initProvider.inputs.distributionId.envKey]: distributionId });
|
|
7806
8136
|
if (mode === "sso") await (0, _hot_updater_cli_tools.ensureInstallPackages)({ devDependencies: ["@aws-sdk/credential-provider-sso"] });
|
|
7807
8137
|
else if (mode === "local-session" || mode === "shared-profile") await (0, _hot_updater_cli_tools.ensureInstallPackages)({ devDependencies: ["@aws-sdk/credential-providers"] });
|
|
7808
8138
|
_hot_updater_cli_tools.p.log.success("Generated '.env.hotupdater' file with AWS settings.");
|