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