@hot-updater/aws 0.25.13 → 0.26.0
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 +298 -274
- package/dist/iac/index.js +298 -274
- package/dist/lambda/index.cjs +283 -295
- package/dist/lambda/index.d.cts +1 -0
- package/package.json +6 -6
package/dist/iac/index.cjs
CHANGED
|
@@ -6457,6 +6457,221 @@ function omit(obj, keys) {
|
|
|
6457
6457
|
return result;
|
|
6458
6458
|
}
|
|
6459
6459
|
|
|
6460
|
+
//#endregion
|
|
6461
|
+
//#region iac/cloudfrontDistributionConfig.ts
|
|
6462
|
+
const HOT_UPDATER_LEGACY_CHECK_UPDATE_HEADERS = [
|
|
6463
|
+
"x-bundle-id",
|
|
6464
|
+
"x-app-version",
|
|
6465
|
+
"x-app-platform",
|
|
6466
|
+
"x-min-bundle-id",
|
|
6467
|
+
"x-channel",
|
|
6468
|
+
"x-fingerprint-hash"
|
|
6469
|
+
];
|
|
6470
|
+
const HOT_UPDATER_LEGACY_CHECK_UPDATE_CACHE_POLICY_CONFIG = {
|
|
6471
|
+
Name: "HotUpdaterLegacyCheckUpdateNoCache",
|
|
6472
|
+
Comment: "Forward legacy check-update headers to origin-request Lambda with effectively no cache",
|
|
6473
|
+
DefaultTTL: 0,
|
|
6474
|
+
MaxTTL: 1,
|
|
6475
|
+
MinTTL: 0,
|
|
6476
|
+
ParametersInCacheKeyAndForwardedToOrigin: {
|
|
6477
|
+
EnableAcceptEncodingBrotli: false,
|
|
6478
|
+
EnableAcceptEncodingGzip: false,
|
|
6479
|
+
HeadersConfig: {
|
|
6480
|
+
HeaderBehavior: "whitelist",
|
|
6481
|
+
Headers: {
|
|
6482
|
+
Quantity: HOT_UPDATER_LEGACY_CHECK_UPDATE_HEADERS.length,
|
|
6483
|
+
Items: [...HOT_UPDATER_LEGACY_CHECK_UPDATE_HEADERS]
|
|
6484
|
+
}
|
|
6485
|
+
},
|
|
6486
|
+
CookiesConfig: { CookieBehavior: "none" },
|
|
6487
|
+
QueryStringsConfig: { QueryStringBehavior: "none" }
|
|
6488
|
+
}
|
|
6489
|
+
};
|
|
6490
|
+
const HOT_UPDATER_SHARED_CACHE_POLICY_CONFIG = {
|
|
6491
|
+
Name: "HotUpdaterOriginCacheControl",
|
|
6492
|
+
Comment: "Honor origin Cache-Control without forwarding viewer Host/cookies/query strings",
|
|
6493
|
+
DefaultTTL: 0,
|
|
6494
|
+
MaxTTL: 31536e3,
|
|
6495
|
+
MinTTL: 0,
|
|
6496
|
+
ParametersInCacheKeyAndForwardedToOrigin: {
|
|
6497
|
+
EnableAcceptEncodingBrotli: true,
|
|
6498
|
+
EnableAcceptEncodingGzip: true,
|
|
6499
|
+
HeadersConfig: { HeaderBehavior: "none" },
|
|
6500
|
+
CookiesConfig: { CookieBehavior: "none" },
|
|
6501
|
+
QueryStringsConfig: { QueryStringBehavior: "none" }
|
|
6502
|
+
}
|
|
6503
|
+
};
|
|
6504
|
+
const READ_ONLY_METHODS = {
|
|
6505
|
+
Quantity: 2,
|
|
6506
|
+
Items: ["HEAD", "GET"],
|
|
6507
|
+
CachedMethods: {
|
|
6508
|
+
Quantity: 2,
|
|
6509
|
+
Items: ["HEAD", "GET"]
|
|
6510
|
+
}
|
|
6511
|
+
};
|
|
6512
|
+
const EMPTY_FUNCTION_ASSOCIATIONS = { Quantity: 0 };
|
|
6513
|
+
const EMPTY_LAMBDA_FUNCTION_ASSOCIATIONS = { Quantity: 0 };
|
|
6514
|
+
const HOT_UPDATER_BEHAVIOR_BASE = {
|
|
6515
|
+
ViewerProtocolPolicy: "redirect-to-https",
|
|
6516
|
+
SmoothStreaming: false,
|
|
6517
|
+
Compress: true,
|
|
6518
|
+
FunctionAssociations: EMPTY_FUNCTION_ASSOCIATIONS,
|
|
6519
|
+
FieldLevelEncryptionId: "",
|
|
6520
|
+
AllowedMethods: READ_ONLY_METHODS
|
|
6521
|
+
};
|
|
6522
|
+
const HOT_UPDATER_CACHE_BEHAVIOR_TEMPLATES = [{
|
|
6523
|
+
pathPattern: "/api/check-update",
|
|
6524
|
+
cachePolicy: "legacy"
|
|
6525
|
+
}, {
|
|
6526
|
+
pathPattern: "/api/check-update/*",
|
|
6527
|
+
cachePolicy: "shared"
|
|
6528
|
+
}];
|
|
6529
|
+
const omitLegacyCacheFields = (value) => {
|
|
6530
|
+
const { ForwardedValues: _forwardedValues, MinTTL: _minTTL, DefaultTTL: _defaultTTL, MaxTTL: _maxTTL, OriginRequestPolicyId: _originRequestPolicyId,...rest } = value;
|
|
6531
|
+
return rest;
|
|
6532
|
+
};
|
|
6533
|
+
const sanitizeDefaultBehavior = (behavior) => ({
|
|
6534
|
+
...omitLegacyCacheFields(behavior),
|
|
6535
|
+
LambdaFunctionAssociations: behavior.LambdaFunctionAssociations ?? EMPTY_LAMBDA_FUNCTION_ASSOCIATIONS,
|
|
6536
|
+
FunctionAssociations: behavior.FunctionAssociations ?? EMPTY_FUNCTION_ASSOCIATIONS
|
|
6537
|
+
});
|
|
6538
|
+
const sanitizeCacheBehavior = (behavior) => ({
|
|
6539
|
+
...omitLegacyCacheFields(behavior),
|
|
6540
|
+
LambdaFunctionAssociations: behavior.LambdaFunctionAssociations ?? EMPTY_LAMBDA_FUNCTION_ASSOCIATIONS,
|
|
6541
|
+
FunctionAssociations: behavior.FunctionAssociations ?? EMPTY_FUNCTION_ASSOCIATIONS
|
|
6542
|
+
});
|
|
6543
|
+
const sanitizeDistributionConfig = (distributionConfig) => ({
|
|
6544
|
+
...distributionConfig,
|
|
6545
|
+
DefaultCacheBehavior: distributionConfig.DefaultCacheBehavior ? sanitizeDefaultBehavior(distributionConfig.DefaultCacheBehavior) : distributionConfig.DefaultCacheBehavior,
|
|
6546
|
+
CacheBehaviors: distributionConfig.CacheBehaviors ? {
|
|
6547
|
+
Quantity: distributionConfig.CacheBehaviors.Quantity,
|
|
6548
|
+
Items: (distributionConfig.CacheBehaviors.Items ?? []).map((behavior) => sanitizeCacheBehavior(behavior))
|
|
6549
|
+
} : distributionConfig.CacheBehaviors
|
|
6550
|
+
});
|
|
6551
|
+
const buildOriginRequestLambdaAssociations = (functionArn) => ({
|
|
6552
|
+
Quantity: 1,
|
|
6553
|
+
Items: [{
|
|
6554
|
+
EventType: "origin-request",
|
|
6555
|
+
LambdaFunctionARN: functionArn
|
|
6556
|
+
}]
|
|
6557
|
+
});
|
|
6558
|
+
const buildS3Origin = (options) => ({
|
|
6559
|
+
Id: options.bucketName,
|
|
6560
|
+
DomainName: options.bucketDomain,
|
|
6561
|
+
OriginAccessControlId: options.oacId,
|
|
6562
|
+
S3OriginConfig: { OriginAccessIdentity: "" },
|
|
6563
|
+
CustomHeaders: { Quantity: 0 }
|
|
6564
|
+
});
|
|
6565
|
+
const buildSharedBehavior = (targetOriginId) => ({
|
|
6566
|
+
TargetOriginId: targetOriginId,
|
|
6567
|
+
...HOT_UPDATER_BEHAVIOR_BASE
|
|
6568
|
+
});
|
|
6569
|
+
const buildDefaultCacheBehavior = (options) => ({
|
|
6570
|
+
...buildSharedBehavior(options.bucketName),
|
|
6571
|
+
TrustedKeyGroups: {
|
|
6572
|
+
Enabled: true,
|
|
6573
|
+
Quantity: 1,
|
|
6574
|
+
Items: [options.keyGroupId]
|
|
6575
|
+
},
|
|
6576
|
+
CachePolicyId: options.sharedCachePolicyId,
|
|
6577
|
+
LambdaFunctionAssociations: EMPTY_LAMBDA_FUNCTION_ASSOCIATIONS
|
|
6578
|
+
});
|
|
6579
|
+
const resolveCachePolicyId = (cachePolicy, { legacyCachePolicyId, sharedCachePolicyId }) => {
|
|
6580
|
+
if (cachePolicy === "legacy") return legacyCachePolicyId;
|
|
6581
|
+
if (cachePolicy === "shared") return sharedCachePolicyId;
|
|
6582
|
+
};
|
|
6583
|
+
const buildCacheBehavior = (template, options) => ({
|
|
6584
|
+
...buildSharedBehavior(options.bucketName),
|
|
6585
|
+
PathPattern: template.pathPattern,
|
|
6586
|
+
CachePolicyId: resolveCachePolicyId(template.cachePolicy, {
|
|
6587
|
+
legacyCachePolicyId: options.legacyCachePolicyId,
|
|
6588
|
+
sharedCachePolicyId: options.sharedCachePolicyId
|
|
6589
|
+
}),
|
|
6590
|
+
LambdaFunctionAssociations: buildOriginRequestLambdaAssociations(options.functionArn)
|
|
6591
|
+
});
|
|
6592
|
+
const mergeOriginWithExisting = (existingOrigin, overrideOrigin) => ({
|
|
6593
|
+
...existingOrigin,
|
|
6594
|
+
...overrideOrigin,
|
|
6595
|
+
CustomHeaders: existingOrigin?.CustomHeaders ?? { Quantity: 0 }
|
|
6596
|
+
});
|
|
6597
|
+
const mergeBehaviorWithExisting = (existingBehavior, overrideBehavior) => ({
|
|
6598
|
+
...omitLegacyCacheFields(existingBehavior ?? {}),
|
|
6599
|
+
...overrideBehavior,
|
|
6600
|
+
LambdaFunctionAssociations: overrideBehavior.LambdaFunctionAssociations ?? existingBehavior?.LambdaFunctionAssociations ?? EMPTY_LAMBDA_FUNCTION_ASSOCIATIONS,
|
|
6601
|
+
FunctionAssociations: overrideBehavior.FunctionAssociations ?? existingBehavior?.FunctionAssociations ?? EMPTY_FUNCTION_ASSOCIATIONS
|
|
6602
|
+
});
|
|
6603
|
+
const buildDistributionConfigOverrides = (options) => ({
|
|
6604
|
+
Origins: {
|
|
6605
|
+
Quantity: 1,
|
|
6606
|
+
Items: [buildS3Origin({
|
|
6607
|
+
bucketName: options.bucketName,
|
|
6608
|
+
bucketDomain: options.bucketDomain,
|
|
6609
|
+
oacId: options.oacId
|
|
6610
|
+
})]
|
|
6611
|
+
},
|
|
6612
|
+
DefaultCacheBehavior: buildDefaultCacheBehavior({
|
|
6613
|
+
bucketName: options.bucketName,
|
|
6614
|
+
keyGroupId: options.keyGroupId,
|
|
6615
|
+
sharedCachePolicyId: options.sharedCachePolicyId
|
|
6616
|
+
}),
|
|
6617
|
+
CacheBehaviors: {
|
|
6618
|
+
Quantity: HOT_UPDATER_CACHE_BEHAVIOR_TEMPLATES.length,
|
|
6619
|
+
Items: HOT_UPDATER_CACHE_BEHAVIOR_TEMPLATES.map((template) => buildCacheBehavior(template, {
|
|
6620
|
+
bucketName: options.bucketName,
|
|
6621
|
+
functionArn: options.functionArn,
|
|
6622
|
+
legacyCachePolicyId: options.legacyCachePolicyId,
|
|
6623
|
+
sharedCachePolicyId: options.sharedCachePolicyId
|
|
6624
|
+
}))
|
|
6625
|
+
}
|
|
6626
|
+
});
|
|
6627
|
+
const applyDistributionConfigOverrides = (distributionConfig, overrides) => {
|
|
6628
|
+
return sanitizeDistributionConfig({
|
|
6629
|
+
...distributionConfig,
|
|
6630
|
+
Origins: {
|
|
6631
|
+
Quantity: overrides.Origins.Quantity,
|
|
6632
|
+
Items: (overrides.Origins.Items ?? []).map((overrideOrigin) => {
|
|
6633
|
+
return mergeOriginWithExisting((distributionConfig.Origins?.Items ?? []).find((origin) => origin.Id === overrideOrigin.Id || origin.DomainName === overrideOrigin.DomainName), overrideOrigin);
|
|
6634
|
+
})
|
|
6635
|
+
},
|
|
6636
|
+
DefaultCacheBehavior: mergeBehaviorWithExisting(distributionConfig.DefaultCacheBehavior, overrides.DefaultCacheBehavior),
|
|
6637
|
+
CacheBehaviors: {
|
|
6638
|
+
Quantity: overrides.CacheBehaviors.Quantity,
|
|
6639
|
+
Items: (overrides.CacheBehaviors.Items ?? []).map((overrideBehavior) => {
|
|
6640
|
+
return mergeBehaviorWithExisting((distributionConfig.CacheBehaviors?.Items ?? []).find((behavior) => behavior.PathPattern === overrideBehavior.PathPattern), overrideBehavior);
|
|
6641
|
+
})
|
|
6642
|
+
}
|
|
6643
|
+
});
|
|
6644
|
+
};
|
|
6645
|
+
const buildDistributionConfig = (options) => sanitizeDistributionConfig({
|
|
6646
|
+
CallerReference: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6647
|
+
Comment: "Hot Updater CloudFront distribution",
|
|
6648
|
+
Enabled: true,
|
|
6649
|
+
...buildDistributionConfigOverrides(options),
|
|
6650
|
+
DefaultRootObject: "index.html",
|
|
6651
|
+
ViewerCertificate: { CloudFrontDefaultCertificate: true },
|
|
6652
|
+
Restrictions: { GeoRestriction: {
|
|
6653
|
+
RestrictionType: "none",
|
|
6654
|
+
Quantity: 0
|
|
6655
|
+
} },
|
|
6656
|
+
PriceClass: "PriceClass_All",
|
|
6657
|
+
Aliases: {
|
|
6658
|
+
Quantity: 0,
|
|
6659
|
+
Items: []
|
|
6660
|
+
}
|
|
6661
|
+
});
|
|
6662
|
+
|
|
6663
|
+
//#endregion
|
|
6664
|
+
//#region iac/cloudfrontPagination.ts
|
|
6665
|
+
const findInPaginatedCloudFrontList = async ({ listPage, matches }) => {
|
|
6666
|
+
let marker;
|
|
6667
|
+
do {
|
|
6668
|
+
const { items, nextMarker } = await listPage(marker);
|
|
6669
|
+
const matchedItem = items.find(matches);
|
|
6670
|
+
if (matchedItem) return matchedItem;
|
|
6671
|
+
marker = nextMarker;
|
|
6672
|
+
} while (marker);
|
|
6673
|
+
};
|
|
6674
|
+
|
|
6460
6675
|
//#endregion
|
|
6461
6676
|
//#region iac/cloudfront.ts
|
|
6462
6677
|
var CloudFrontManager = class {
|
|
@@ -6466,6 +6681,44 @@ var CloudFrontManager = class {
|
|
|
6466
6681
|
this.region = region;
|
|
6467
6682
|
this.credentials = credentials;
|
|
6468
6683
|
}
|
|
6684
|
+
async getOrCreateSharedCachePolicy(cloudfrontClient) {
|
|
6685
|
+
const existingPolicyId = (await findInPaginatedCloudFrontList({
|
|
6686
|
+
listPage: async (marker) => {
|
|
6687
|
+
const listPoliciesResponse = await cloudfrontClient.listCachePolicies({
|
|
6688
|
+
Type: "custom",
|
|
6689
|
+
...marker ? { Marker: marker } : {}
|
|
6690
|
+
});
|
|
6691
|
+
return {
|
|
6692
|
+
items: listPoliciesResponse.CachePolicyList?.Items ?? [],
|
|
6693
|
+
nextMarker: listPoliciesResponse.CachePolicyList?.NextMarker
|
|
6694
|
+
};
|
|
6695
|
+
},
|
|
6696
|
+
matches: (policy) => policy.CachePolicy?.CachePolicyConfig?.Name === HOT_UPDATER_SHARED_CACHE_POLICY_CONFIG.Name
|
|
6697
|
+
}))?.CachePolicy?.Id;
|
|
6698
|
+
if (existingPolicyId) return existingPolicyId;
|
|
6699
|
+
const cachePolicyId = (await cloudfrontClient.createCachePolicy({ CachePolicyConfig: HOT_UPDATER_SHARED_CACHE_POLICY_CONFIG })).CachePolicy?.Id;
|
|
6700
|
+
if (!cachePolicyId) throw new Error("Failed to create shared cache policy");
|
|
6701
|
+
return cachePolicyId;
|
|
6702
|
+
}
|
|
6703
|
+
async getOrCreateLegacyCheckUpdateCachePolicy(cloudfrontClient) {
|
|
6704
|
+
const existingPolicyId = (await findInPaginatedCloudFrontList({
|
|
6705
|
+
listPage: async (marker) => {
|
|
6706
|
+
const listPoliciesResponse = await cloudfrontClient.listCachePolicies({
|
|
6707
|
+
Type: "custom",
|
|
6708
|
+
...marker ? { Marker: marker } : {}
|
|
6709
|
+
});
|
|
6710
|
+
return {
|
|
6711
|
+
items: listPoliciesResponse.CachePolicyList?.Items ?? [],
|
|
6712
|
+
nextMarker: listPoliciesResponse.CachePolicyList?.NextMarker
|
|
6713
|
+
};
|
|
6714
|
+
},
|
|
6715
|
+
matches: (policy) => policy.CachePolicy?.CachePolicyConfig?.Name === HOT_UPDATER_LEGACY_CHECK_UPDATE_CACHE_POLICY_CONFIG.Name
|
|
6716
|
+
}))?.CachePolicy?.Id;
|
|
6717
|
+
if (existingPolicyId) return existingPolicyId;
|
|
6718
|
+
const cachePolicyId = (await cloudfrontClient.createCachePolicy({ CachePolicyConfig: HOT_UPDATER_LEGACY_CHECK_UPDATE_CACHE_POLICY_CONFIG })).CachePolicy?.Id;
|
|
6719
|
+
if (!cachePolicyId) throw new Error("Failed to create legacy check-update cache policy");
|
|
6720
|
+
return cachePolicyId;
|
|
6721
|
+
}
|
|
6469
6722
|
async getOrCreateKeyGroup(publicKey) {
|
|
6470
6723
|
const publicKeyHash = crypto.default.createHash("sha256").update(publicKey).digest("hex").slice(0, 16);
|
|
6471
6724
|
const cloudfrontClient = new __aws_sdk_client_cloudfront.CloudFront({
|
|
@@ -6528,6 +6781,18 @@ var CloudFrontManager = class {
|
|
|
6528
6781
|
}
|
|
6529
6782
|
if (!oacId) throw new Error("Failed to get Origin Access Control ID");
|
|
6530
6783
|
const bucketDomain = `${options.bucketName}.s3.${this.region}.amazonaws.com`;
|
|
6784
|
+
let legacyCachePolicyId;
|
|
6785
|
+
let sharedCachePolicyId;
|
|
6786
|
+
try {
|
|
6787
|
+
legacyCachePolicyId = await this.getOrCreateLegacyCheckUpdateCachePolicy(cloudfrontClient);
|
|
6788
|
+
} catch (error) {
|
|
6789
|
+
throw new Error(`Failed to get or create legacy check-update cache policy: ${error instanceof Error ? error.message : String(error)}`);
|
|
6790
|
+
}
|
|
6791
|
+
try {
|
|
6792
|
+
sharedCachePolicyId = await this.getOrCreateSharedCachePolicy(cloudfrontClient);
|
|
6793
|
+
} catch (error) {
|
|
6794
|
+
throw new Error(`Failed to get or create shared cache policy: ${error instanceof Error ? error.message : String(error)}`);
|
|
6795
|
+
}
|
|
6531
6796
|
const matchingDistributions = [];
|
|
6532
6797
|
try {
|
|
6533
6798
|
const items = (await cloudfrontClient.listDistributions({})).DistributionList?.Items || [];
|
|
@@ -6551,136 +6816,21 @@ var CloudFrontManager = class {
|
|
|
6551
6816
|
if (__hot_updater_cli_tools.p.isCancel(selectedDistributionStr)) process.exit(0);
|
|
6552
6817
|
selectedDistribution = JSON.parse(selectedDistributionStr);
|
|
6553
6818
|
}
|
|
6554
|
-
const newOverrides = {
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
},
|
|
6564
|
-
DefaultCacheBehavior: {
|
|
6565
|
-
TargetOriginId: options.bucketName,
|
|
6566
|
-
ViewerProtocolPolicy: "redirect-to-https",
|
|
6567
|
-
TrustedKeyGroups: {
|
|
6568
|
-
Enabled: true,
|
|
6569
|
-
Quantity: 1,
|
|
6570
|
-
Items: [options.keyGroupId]
|
|
6571
|
-
},
|
|
6572
|
-
ForwardedValues: {
|
|
6573
|
-
QueryString: true,
|
|
6574
|
-
Cookies: { Forward: "none" },
|
|
6575
|
-
QueryStringCacheKeys: {
|
|
6576
|
-
Quantity: 0,
|
|
6577
|
-
Items: []
|
|
6578
|
-
}
|
|
6579
|
-
},
|
|
6580
|
-
MinTTL: 0,
|
|
6581
|
-
SmoothStreaming: false,
|
|
6582
|
-
Compress: true,
|
|
6583
|
-
FieldLevelEncryptionId: "",
|
|
6584
|
-
AllowedMethods: {
|
|
6585
|
-
Quantity: 2,
|
|
6586
|
-
Items: ["HEAD", "GET"],
|
|
6587
|
-
CachedMethods: {
|
|
6588
|
-
Quantity: 2,
|
|
6589
|
-
Items: ["HEAD", "GET"]
|
|
6590
|
-
}
|
|
6591
|
-
}
|
|
6592
|
-
},
|
|
6593
|
-
CacheBehaviors: {
|
|
6594
|
-
Quantity: 2,
|
|
6595
|
-
Items: [{
|
|
6596
|
-
PathPattern: "/api/check-update",
|
|
6597
|
-
TargetOriginId: options.bucketName,
|
|
6598
|
-
ViewerProtocolPolicy: "redirect-to-https",
|
|
6599
|
-
LambdaFunctionAssociations: {
|
|
6600
|
-
Quantity: 1,
|
|
6601
|
-
Items: [{
|
|
6602
|
-
EventType: "origin-request",
|
|
6603
|
-
LambdaFunctionARN: options.functionArn
|
|
6604
|
-
}]
|
|
6605
|
-
},
|
|
6606
|
-
MinTTL: 0,
|
|
6607
|
-
DefaultTTL: 0,
|
|
6608
|
-
MaxTTL: 0,
|
|
6609
|
-
SmoothStreaming: false,
|
|
6610
|
-
Compress: true,
|
|
6611
|
-
FieldLevelEncryptionId: "",
|
|
6612
|
-
AllowedMethods: {
|
|
6613
|
-
Quantity: 2,
|
|
6614
|
-
Items: ["HEAD", "GET"],
|
|
6615
|
-
CachedMethods: {
|
|
6616
|
-
Quantity: 2,
|
|
6617
|
-
Items: ["HEAD", "GET"]
|
|
6618
|
-
}
|
|
6619
|
-
},
|
|
6620
|
-
ForwardedValues: {
|
|
6621
|
-
QueryString: false,
|
|
6622
|
-
Cookies: { Forward: "none" },
|
|
6623
|
-
Headers: {
|
|
6624
|
-
Quantity: 6,
|
|
6625
|
-
Items: [
|
|
6626
|
-
"x-bundle-id",
|
|
6627
|
-
"x-app-version",
|
|
6628
|
-
"x-app-platform",
|
|
6629
|
-
"x-min-bundle-id",
|
|
6630
|
-
"x-channel",
|
|
6631
|
-
"x-fingerprint-hash"
|
|
6632
|
-
]
|
|
6633
|
-
},
|
|
6634
|
-
QueryStringCacheKeys: {
|
|
6635
|
-
Quantity: 0,
|
|
6636
|
-
Items: []
|
|
6637
|
-
}
|
|
6638
|
-
}
|
|
6639
|
-
}, {
|
|
6640
|
-
PathPattern: "/api/check-update/*",
|
|
6641
|
-
TargetOriginId: options.bucketName,
|
|
6642
|
-
ViewerProtocolPolicy: "redirect-to-https",
|
|
6643
|
-
LambdaFunctionAssociations: {
|
|
6644
|
-
Quantity: 1,
|
|
6645
|
-
Items: [{
|
|
6646
|
-
EventType: "origin-request",
|
|
6647
|
-
LambdaFunctionARN: options.functionArn
|
|
6648
|
-
}]
|
|
6649
|
-
},
|
|
6650
|
-
MinTTL: 0,
|
|
6651
|
-
DefaultTTL: 31536e3,
|
|
6652
|
-
MaxTTL: 31536e3,
|
|
6653
|
-
SmoothStreaming: false,
|
|
6654
|
-
Compress: true,
|
|
6655
|
-
FieldLevelEncryptionId: "",
|
|
6656
|
-
AllowedMethods: {
|
|
6657
|
-
Quantity: 2,
|
|
6658
|
-
Items: ["HEAD", "GET"],
|
|
6659
|
-
CachedMethods: {
|
|
6660
|
-
Quantity: 2,
|
|
6661
|
-
Items: ["HEAD", "GET"]
|
|
6662
|
-
}
|
|
6663
|
-
},
|
|
6664
|
-
ForwardedValues: {
|
|
6665
|
-
QueryString: false,
|
|
6666
|
-
Cookies: { Forward: "none" },
|
|
6667
|
-
Headers: {
|
|
6668
|
-
Quantity: 0,
|
|
6669
|
-
Items: []
|
|
6670
|
-
},
|
|
6671
|
-
QueryStringCacheKeys: {
|
|
6672
|
-
Quantity: 0,
|
|
6673
|
-
Items: []
|
|
6674
|
-
}
|
|
6675
|
-
}
|
|
6676
|
-
}]
|
|
6677
|
-
}
|
|
6678
|
-
};
|
|
6819
|
+
const newOverrides = buildDistributionConfigOverrides({
|
|
6820
|
+
bucketName: options.bucketName,
|
|
6821
|
+
bucketDomain,
|
|
6822
|
+
functionArn: options.functionArn,
|
|
6823
|
+
keyGroupId: options.keyGroupId,
|
|
6824
|
+
oacId,
|
|
6825
|
+
legacyCachePolicyId,
|
|
6826
|
+
sharedCachePolicyId
|
|
6827
|
+
});
|
|
6679
6828
|
if (selectedDistribution) {
|
|
6680
6829
|
__hot_updater_cli_tools.p.log.success(`Existing CloudFront distribution selected. Distribution ID: ${selectedDistribution.Id}.`);
|
|
6681
6830
|
try {
|
|
6682
6831
|
const { DistributionConfig, ETag } = await cloudfrontClient.getDistributionConfig({ Id: selectedDistribution.Id });
|
|
6683
|
-
|
|
6832
|
+
if (!DistributionConfig) throw new Error("CloudFront distribution config was not returned");
|
|
6833
|
+
const finalConfig = applyDistributionConfigOverrides(DistributionConfig, newOverrides);
|
|
6684
6834
|
await cloudfrontClient.updateDistribution({
|
|
6685
6835
|
Id: selectedDistribution.Id,
|
|
6686
6836
|
IfMatch: ETag,
|
|
@@ -6707,145 +6857,15 @@ var CloudFrontManager = class {
|
|
|
6707
6857
|
throw err;
|
|
6708
6858
|
}
|
|
6709
6859
|
}
|
|
6710
|
-
const finalDistributionConfig = {
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
OriginAccessControlId: oacId,
|
|
6720
|
-
S3OriginConfig: { OriginAccessIdentity: "" }
|
|
6721
|
-
}]
|
|
6722
|
-
},
|
|
6723
|
-
DefaultCacheBehavior: {
|
|
6724
|
-
TargetOriginId: options.bucketName,
|
|
6725
|
-
ViewerProtocolPolicy: "redirect-to-https",
|
|
6726
|
-
TrustedKeyGroups: {
|
|
6727
|
-
Enabled: true,
|
|
6728
|
-
Quantity: 1,
|
|
6729
|
-
Items: [options.keyGroupId]
|
|
6730
|
-
},
|
|
6731
|
-
ForwardedValues: {
|
|
6732
|
-
QueryString: true,
|
|
6733
|
-
Cookies: { Forward: "none" },
|
|
6734
|
-
QueryStringCacheKeys: {
|
|
6735
|
-
Quantity: 0,
|
|
6736
|
-
Items: []
|
|
6737
|
-
}
|
|
6738
|
-
},
|
|
6739
|
-
MinTTL: 0,
|
|
6740
|
-
SmoothStreaming: false,
|
|
6741
|
-
Compress: true,
|
|
6742
|
-
FieldLevelEncryptionId: "",
|
|
6743
|
-
AllowedMethods: {
|
|
6744
|
-
Quantity: 2,
|
|
6745
|
-
Items: ["HEAD", "GET"],
|
|
6746
|
-
CachedMethods: {
|
|
6747
|
-
Quantity: 2,
|
|
6748
|
-
Items: ["HEAD", "GET"]
|
|
6749
|
-
}
|
|
6750
|
-
}
|
|
6751
|
-
},
|
|
6752
|
-
CacheBehaviors: {
|
|
6753
|
-
Quantity: 2,
|
|
6754
|
-
Items: [{
|
|
6755
|
-
PathPattern: "/api/check-update",
|
|
6756
|
-
TargetOriginId: options.bucketName,
|
|
6757
|
-
ViewerProtocolPolicy: "redirect-to-https",
|
|
6758
|
-
LambdaFunctionAssociations: {
|
|
6759
|
-
Quantity: 1,
|
|
6760
|
-
Items: [{
|
|
6761
|
-
EventType: "origin-request",
|
|
6762
|
-
LambdaFunctionARN: options.functionArn
|
|
6763
|
-
}]
|
|
6764
|
-
},
|
|
6765
|
-
MinTTL: 0,
|
|
6766
|
-
DefaultTTL: 0,
|
|
6767
|
-
MaxTTL: 0,
|
|
6768
|
-
SmoothStreaming: false,
|
|
6769
|
-
Compress: true,
|
|
6770
|
-
FieldLevelEncryptionId: "",
|
|
6771
|
-
AllowedMethods: {
|
|
6772
|
-
Quantity: 2,
|
|
6773
|
-
Items: ["HEAD", "GET"],
|
|
6774
|
-
CachedMethods: {
|
|
6775
|
-
Quantity: 2,
|
|
6776
|
-
Items: ["HEAD", "GET"]
|
|
6777
|
-
}
|
|
6778
|
-
},
|
|
6779
|
-
ForwardedValues: {
|
|
6780
|
-
QueryString: false,
|
|
6781
|
-
Cookies: { Forward: "none" },
|
|
6782
|
-
Headers: {
|
|
6783
|
-
Quantity: 6,
|
|
6784
|
-
Items: [
|
|
6785
|
-
"x-bundle-id",
|
|
6786
|
-
"x-app-version",
|
|
6787
|
-
"x-app-platform",
|
|
6788
|
-
"x-min-bundle-id",
|
|
6789
|
-
"x-channel",
|
|
6790
|
-
"x-fingerprint-hash"
|
|
6791
|
-
]
|
|
6792
|
-
},
|
|
6793
|
-
QueryStringCacheKeys: {
|
|
6794
|
-
Quantity: 0,
|
|
6795
|
-
Items: []
|
|
6796
|
-
}
|
|
6797
|
-
}
|
|
6798
|
-
}, {
|
|
6799
|
-
PathPattern: "/api/check-update/*",
|
|
6800
|
-
TargetOriginId: options.bucketName,
|
|
6801
|
-
ViewerProtocolPolicy: "redirect-to-https",
|
|
6802
|
-
LambdaFunctionAssociations: {
|
|
6803
|
-
Quantity: 1,
|
|
6804
|
-
Items: [{
|
|
6805
|
-
EventType: "origin-request",
|
|
6806
|
-
LambdaFunctionARN: options.functionArn
|
|
6807
|
-
}]
|
|
6808
|
-
},
|
|
6809
|
-
MinTTL: 0,
|
|
6810
|
-
DefaultTTL: 31536e3,
|
|
6811
|
-
MaxTTL: 31536e3,
|
|
6812
|
-
SmoothStreaming: false,
|
|
6813
|
-
Compress: true,
|
|
6814
|
-
FieldLevelEncryptionId: "",
|
|
6815
|
-
AllowedMethods: {
|
|
6816
|
-
Quantity: 2,
|
|
6817
|
-
Items: ["HEAD", "GET"],
|
|
6818
|
-
CachedMethods: {
|
|
6819
|
-
Quantity: 2,
|
|
6820
|
-
Items: ["HEAD", "GET"]
|
|
6821
|
-
}
|
|
6822
|
-
},
|
|
6823
|
-
ForwardedValues: {
|
|
6824
|
-
QueryString: false,
|
|
6825
|
-
Cookies: { Forward: "none" },
|
|
6826
|
-
Headers: {
|
|
6827
|
-
Quantity: 0,
|
|
6828
|
-
Items: []
|
|
6829
|
-
},
|
|
6830
|
-
QueryStringCacheKeys: {
|
|
6831
|
-
Quantity: 0,
|
|
6832
|
-
Items: []
|
|
6833
|
-
}
|
|
6834
|
-
}
|
|
6835
|
-
}]
|
|
6836
|
-
},
|
|
6837
|
-
DefaultRootObject: "index.html",
|
|
6838
|
-
ViewerCertificate: { CloudFrontDefaultCertificate: true },
|
|
6839
|
-
Restrictions: { GeoRestriction: {
|
|
6840
|
-
RestrictionType: "none",
|
|
6841
|
-
Quantity: 0
|
|
6842
|
-
} },
|
|
6843
|
-
PriceClass: "PriceClass_All",
|
|
6844
|
-
Aliases: {
|
|
6845
|
-
Quantity: 0,
|
|
6846
|
-
Items: []
|
|
6847
|
-
}
|
|
6848
|
-
};
|
|
6860
|
+
const finalDistributionConfig = buildDistributionConfig({
|
|
6861
|
+
bucketName: options.bucketName,
|
|
6862
|
+
bucketDomain,
|
|
6863
|
+
functionArn: options.functionArn,
|
|
6864
|
+
keyGroupId: options.keyGroupId,
|
|
6865
|
+
oacId,
|
|
6866
|
+
legacyCachePolicyId,
|
|
6867
|
+
sharedCachePolicyId
|
|
6868
|
+
});
|
|
6849
6869
|
try {
|
|
6850
6870
|
const distResp = await cloudfrontClient.createDistribution({ DistributionConfig: finalDistributionConfig });
|
|
6851
6871
|
if (!distResp.Distribution?.Id || !distResp.Distribution?.DomainName) throw new Error("Failed to create CloudFront distribution: No ID or DomainName returned");
|
|
@@ -6887,6 +6907,14 @@ var IAMManager = class {
|
|
|
6887
6907
|
this.region = region;
|
|
6888
6908
|
this.credentials = credentials;
|
|
6889
6909
|
}
|
|
6910
|
+
async ensureManagedPolicies(iamClient, roleName) {
|
|
6911
|
+
const attachedPolicies = await iamClient.listAttachedRolePolicies({ RoleName: roleName });
|
|
6912
|
+
const attachedPolicyArns = new Set((attachedPolicies.AttachedPolicies ?? []).map((policy) => policy.PolicyArn));
|
|
6913
|
+
for (const policyArn of ["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"]) if (!attachedPolicyArns.has(policyArn)) await iamClient.attachRolePolicy({
|
|
6914
|
+
RoleName: roleName,
|
|
6915
|
+
PolicyArn: policyArn
|
|
6916
|
+
});
|
|
6917
|
+
}
|
|
6890
6918
|
async createOrSelectRole() {
|
|
6891
6919
|
const iamClient = new __aws_sdk_client_iam.IAM({
|
|
6892
6920
|
region: this.region,
|
|
@@ -6917,6 +6945,7 @@ var IAMManager = class {
|
|
|
6917
6945
|
try {
|
|
6918
6946
|
const { Role: existingRole } = await iamClient.getRole({ RoleName: roleName });
|
|
6919
6947
|
if (existingRole?.Arn) {
|
|
6948
|
+
await this.ensureManagedPolicies(iamClient, roleName);
|
|
6920
6949
|
try {
|
|
6921
6950
|
await iamClient.putRolePolicy({
|
|
6922
6951
|
RoleName: roleName,
|
|
@@ -6940,14 +6969,7 @@ var IAMManager = class {
|
|
|
6940
6969
|
if (!createRoleResp.Role?.Arn) throw new Error("Failed to create IAM role: No ARN returned");
|
|
6941
6970
|
const lambdaRoleArn = createRoleResp.Role.Arn;
|
|
6942
6971
|
__hot_updater_cli_tools.p.log.info(`Created IAM role: ${roleName} (${lambdaRoleArn})`);
|
|
6943
|
-
await
|
|
6944
|
-
RoleName: roleName,
|
|
6945
|
-
PolicyArn: "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
|
|
6946
|
-
});
|
|
6947
|
-
await iamClient.attachRolePolicy({
|
|
6948
|
-
RoleName: roleName,
|
|
6949
|
-
PolicyArn: "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
|
|
6950
|
-
});
|
|
6972
|
+
await this.ensureManagedPolicies(iamClient, roleName);
|
|
6951
6973
|
__hot_updater_cli_tools.p.log.info(`Attached managed policies to ${roleName}`);
|
|
6952
6974
|
await iamClient.putRolePolicy({
|
|
6953
6975
|
RoleName: roleName,
|
|
@@ -6986,7 +7008,8 @@ var LambdaEdgeDeployer = class {
|
|
|
6986
7008
|
const code = (0, __hot_updater_cli_tools.transformEnv)(indexPath, {
|
|
6987
7009
|
CLOUDFRONT_KEY_PAIR_ID: config.publicKeyId,
|
|
6988
7010
|
SSM_PARAMETER_NAME: config.ssmParameterName,
|
|
6989
|
-
SSM_REGION: config.ssmRegion
|
|
7011
|
+
SSM_REGION: config.ssmRegion,
|
|
7012
|
+
S3_BUCKET_NAME: config.bucketName
|
|
6990
7013
|
});
|
|
6991
7014
|
await fs_promises.default.writeFile(indexPath, code);
|
|
6992
7015
|
const lambdaClient = new __aws_sdk_client_lambda.Lambda({
|
|
@@ -7754,6 +7777,7 @@ const runInit = async ({ build }) => {
|
|
|
7754
7777
|
const lambdaEdgeDeployer = new LambdaEdgeDeployer(credentials);
|
|
7755
7778
|
const ssmParameterName = `/hot-updater/${bucketName}/keypair`;
|
|
7756
7779
|
const { functionArn } = await lambdaEdgeDeployer.deploy(lambdaRoleArn, {
|
|
7780
|
+
bucketName,
|
|
7757
7781
|
publicKeyId,
|
|
7758
7782
|
ssmParameterName,
|
|
7759
7783
|
ssmRegion: bucketRegion
|