@awsless/awsless 0.0.23 → 0.0.25
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/bin.cjs +114 -39
- package/dist/bin.js +115 -40
- package/dist/index.d.ts +3 -0
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -183,7 +183,9 @@ var getAtt = (logicalId, attr) => {
|
|
|
183
183
|
return { "Fn::GetAtt": [logicalId, attr] };
|
|
184
184
|
};
|
|
185
185
|
var importValue = (name) => {
|
|
186
|
-
return
|
|
186
|
+
return new Lazy((stack) => ({
|
|
187
|
+
"Fn::ImportValue": `${stack.app.name}-${name}`
|
|
188
|
+
}));
|
|
187
189
|
};
|
|
188
190
|
var formatLogicalId = (id) => {
|
|
189
191
|
return (0, import_change_case2.pascalCase)(id).replaceAll("_", "");
|
|
@@ -453,10 +455,18 @@ var Stack = class {
|
|
|
453
455
|
this.name = name;
|
|
454
456
|
this.region = region;
|
|
455
457
|
}
|
|
458
|
+
parent;
|
|
456
459
|
exports = /* @__PURE__ */ new Map();
|
|
457
460
|
resources = /* @__PURE__ */ new Set();
|
|
458
461
|
tags = /* @__PURE__ */ new Map();
|
|
459
462
|
assets = /* @__PURE__ */ new Set();
|
|
463
|
+
get app() {
|
|
464
|
+
return this.parent;
|
|
465
|
+
}
|
|
466
|
+
setApp(app) {
|
|
467
|
+
this.parent = app;
|
|
468
|
+
return this;
|
|
469
|
+
}
|
|
460
470
|
add(...resources) {
|
|
461
471
|
for (const item of resources) {
|
|
462
472
|
if (item instanceof Asset) {
|
|
@@ -530,7 +540,9 @@ var Stack = class {
|
|
|
530
540
|
for (const [name, value] of this.exports.entries()) {
|
|
531
541
|
Object.assign(outputs, {
|
|
532
542
|
[formatLogicalId(name)]: {
|
|
533
|
-
Export: {
|
|
543
|
+
Export: {
|
|
544
|
+
Name: `${this.app?.name || "default"}-${name}`
|
|
545
|
+
},
|
|
534
546
|
Value: value
|
|
535
547
|
}
|
|
536
548
|
});
|
|
@@ -2275,6 +2287,9 @@ var Definition = class extends Asset {
|
|
|
2275
2287
|
}));
|
|
2276
2288
|
const defs = (0, import_merge.mergeTypeDefs)(schemas);
|
|
2277
2289
|
const schema2 = (0, import_graphql.print)(defs);
|
|
2290
|
+
if (schema2.length === 0) {
|
|
2291
|
+
throw new Error(`Graphql schema definition can't be empty. [${this.id}]`);
|
|
2292
|
+
}
|
|
2278
2293
|
const size = Buffer.from(schema2, "utf8").byteLength;
|
|
2279
2294
|
await write("schema.gql", schema2);
|
|
2280
2295
|
this.schema = schema2;
|
|
@@ -2940,6 +2955,7 @@ var Vpc = class extends Resource {
|
|
|
2940
2955
|
constructor(logicalId, props) {
|
|
2941
2956
|
super("AWS::EC2::VPC", logicalId);
|
|
2942
2957
|
this.props = props;
|
|
2958
|
+
this.tag("Name", props.name);
|
|
2943
2959
|
}
|
|
2944
2960
|
get id() {
|
|
2945
2961
|
return ref(this.logicalId);
|
|
@@ -3102,6 +3118,7 @@ var vpcPlugin = definePlugin({
|
|
|
3102
3118
|
// }),
|
|
3103
3119
|
onApp({ config, bootstrap: bootstrap2 }) {
|
|
3104
3120
|
const vpc = new Vpc("main", {
|
|
3121
|
+
name: config.name,
|
|
3105
3122
|
cidrBlock: Peer.ipv4("10.0.0.0/16")
|
|
3106
3123
|
});
|
|
3107
3124
|
const privateRouteTable = new RouteTable("private", {
|
|
@@ -3831,7 +3848,10 @@ var App = class {
|
|
|
3831
3848
|
}
|
|
3832
3849
|
list = /* @__PURE__ */ new Map();
|
|
3833
3850
|
add(...stacks) {
|
|
3834
|
-
stacks.forEach((stack) =>
|
|
3851
|
+
stacks.forEach((stack) => {
|
|
3852
|
+
this.list.set(stack.name, stack);
|
|
3853
|
+
stack.setApp(this);
|
|
3854
|
+
});
|
|
3835
3855
|
return this;
|
|
3836
3856
|
}
|
|
3837
3857
|
find(resourceType) {
|
|
@@ -4619,6 +4639,7 @@ var Renderer = class {
|
|
|
4619
4639
|
}
|
|
4620
4640
|
}
|
|
4621
4641
|
}
|
|
4642
|
+
await this.setCursor(0, size - start);
|
|
4622
4643
|
this.screen = screen;
|
|
4623
4644
|
this.flushing = false;
|
|
4624
4645
|
}
|
|
@@ -4803,20 +4824,26 @@ var assetBuilder = (app) => {
|
|
|
4803
4824
|
]);
|
|
4804
4825
|
group.update((group2) => [...group2, line]);
|
|
4805
4826
|
const timer = createTimer();
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4827
|
+
try {
|
|
4828
|
+
const data = await asset.build({
|
|
4829
|
+
async write(file, data2) {
|
|
4830
|
+
const fullpath = (0, import_path8.join)(directories.asset, asset.type, app.name, stack.name, asset.id, file);
|
|
4831
|
+
const basepath = (0, import_path8.dirname)(fullpath);
|
|
4832
|
+
await (0, import_promises6.mkdir)(basepath, { recursive: true });
|
|
4833
|
+
await (0, import_promises6.writeFile)(fullpath, data2);
|
|
4834
|
+
}
|
|
4835
|
+
});
|
|
4836
|
+
details.set({
|
|
4837
|
+
...data,
|
|
4838
|
+
time: timer()
|
|
4839
|
+
});
|
|
4840
|
+
icon.set(style.success(symbol.success));
|
|
4841
|
+
} catch (error) {
|
|
4842
|
+
icon.set(style.error(symbol.error));
|
|
4843
|
+
throw error;
|
|
4844
|
+
} finally {
|
|
4845
|
+
stop();
|
|
4846
|
+
}
|
|
4820
4847
|
}));
|
|
4821
4848
|
}));
|
|
4822
4849
|
done("Done building stack assets");
|
|
@@ -4914,7 +4941,7 @@ var StackClient = class {
|
|
|
4914
4941
|
maxWaitTime = 60 * 30;
|
|
4915
4942
|
// 30 minutes
|
|
4916
4943
|
maxDelay = 30;
|
|
4917
|
-
//
|
|
4944
|
+
// 10 seconds
|
|
4918
4945
|
assetBucketName;
|
|
4919
4946
|
getClient(region) {
|
|
4920
4947
|
return new import_client_cloudformation.CloudFormationClient({
|
|
@@ -4961,7 +4988,7 @@ var StackClient = class {
|
|
|
4961
4988
|
async create(stack, capabilities) {
|
|
4962
4989
|
debug("Create the", style.info(stack.name), "stack");
|
|
4963
4990
|
const client = this.getClient(stack.region);
|
|
4964
|
-
await client.send(new import_client_cloudformation.CreateStackCommand({
|
|
4991
|
+
const result = await client.send(new import_client_cloudformation.CreateStackCommand({
|
|
4965
4992
|
StackName: this.stackName(stack.name),
|
|
4966
4993
|
EnableTerminationProtection: false,
|
|
4967
4994
|
OnFailure: import_client_cloudformation.OnFailure.DELETE,
|
|
@@ -4969,36 +4996,53 @@ var StackClient = class {
|
|
|
4969
4996
|
Tags: this.tags(stack),
|
|
4970
4997
|
...this.templateProp(stack)
|
|
4971
4998
|
}));
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4999
|
+
try {
|
|
5000
|
+
await (0, import_client_cloudformation.waitUntilStackCreateComplete)({
|
|
5001
|
+
client,
|
|
5002
|
+
maxWaitTime: this.maxWaitTime,
|
|
5003
|
+
maxDelay: this.maxDelay
|
|
5004
|
+
}, {
|
|
5005
|
+
StackName: result.StackId
|
|
5006
|
+
});
|
|
5007
|
+
} catch (_) {
|
|
5008
|
+
const reason = await this.getFailureReason(
|
|
5009
|
+
result.StackId,
|
|
5010
|
+
stack.region
|
|
5011
|
+
);
|
|
5012
|
+
throw new Error(reason);
|
|
5013
|
+
}
|
|
4979
5014
|
}
|
|
4980
5015
|
async update(stack, capabilities) {
|
|
4981
5016
|
debug("Update the", style.info(stack.name), "stack");
|
|
4982
5017
|
const client = this.getClient(stack.region);
|
|
5018
|
+
let result;
|
|
4983
5019
|
try {
|
|
4984
|
-
await client.send(new import_client_cloudformation.UpdateStackCommand({
|
|
5020
|
+
result = await client.send(new import_client_cloudformation.UpdateStackCommand({
|
|
4985
5021
|
StackName: this.stackName(stack.name),
|
|
4986
5022
|
Capabilities: capabilities,
|
|
4987
5023
|
Tags: this.tags(stack),
|
|
4988
5024
|
...this.templateProp(stack)
|
|
4989
5025
|
}));
|
|
5026
|
+
} catch (error) {
|
|
5027
|
+
if (error instanceof Error && error.name === "ValidationError" && error.message.toLowerCase().includes("no updates")) {
|
|
5028
|
+
return;
|
|
5029
|
+
}
|
|
5030
|
+
throw error;
|
|
5031
|
+
}
|
|
5032
|
+
try {
|
|
4990
5033
|
await (0, import_client_cloudformation.waitUntilStackUpdateComplete)({
|
|
4991
5034
|
client,
|
|
4992
5035
|
maxWaitTime: this.maxWaitTime,
|
|
4993
5036
|
maxDelay: this.maxDelay
|
|
4994
5037
|
}, {
|
|
4995
|
-
StackName:
|
|
5038
|
+
StackName: result.StackId
|
|
4996
5039
|
});
|
|
4997
5040
|
} catch (error) {
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5041
|
+
const reason = await this.getFailureReason(
|
|
5042
|
+
result.StackId,
|
|
5043
|
+
stack.region
|
|
5044
|
+
);
|
|
5045
|
+
throw new Error(reason);
|
|
5002
5046
|
}
|
|
5003
5047
|
}
|
|
5004
5048
|
async validate(stack) {
|
|
@@ -5079,13 +5123,44 @@ var StackClient = class {
|
|
|
5079
5123
|
await client.send(new import_client_cloudformation.DeleteStackCommand({
|
|
5080
5124
|
StackName: this.stackName(name)
|
|
5081
5125
|
}));
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5126
|
+
try {
|
|
5127
|
+
await (0, import_client_cloudformation.waitUntilStackDeleteComplete)({
|
|
5128
|
+
client,
|
|
5129
|
+
maxWaitTime: this.maxWaitTime,
|
|
5130
|
+
maxDelay: this.maxDelay
|
|
5131
|
+
}, {
|
|
5132
|
+
StackName: this.stackName(name)
|
|
5133
|
+
});
|
|
5134
|
+
} catch (_) {
|
|
5135
|
+
const reason = await this.getFailureReason(name, region);
|
|
5136
|
+
throw new Error(reason);
|
|
5137
|
+
}
|
|
5138
|
+
}
|
|
5139
|
+
async getFailureReason(name, region) {
|
|
5140
|
+
const client = this.getClient(region);
|
|
5141
|
+
const result = await client.send(await new import_client_cloudformation.DescribeStackEventsCommand({
|
|
5142
|
+
StackName: name
|
|
5143
|
+
}));
|
|
5144
|
+
const failureStatuses = [
|
|
5145
|
+
"UPDATE_ROLLBACK_IN_PROGRESS",
|
|
5146
|
+
"CREATE_FAILED",
|
|
5147
|
+
"UPDATE_FAILED",
|
|
5148
|
+
"DELETE_FAILED"
|
|
5149
|
+
];
|
|
5150
|
+
let reason = "Unknown failure reason";
|
|
5151
|
+
for (const event of result.StackEvents || []) {
|
|
5152
|
+
if (event.ResourceStatusReason?.toLowerCase() === "user initiated") {
|
|
5153
|
+
break;
|
|
5154
|
+
}
|
|
5155
|
+
if (failureStatuses.includes(event.ResourceStatus || "") && event.ResourceStatusReason) {
|
|
5156
|
+
reason = [
|
|
5157
|
+
`Logical ID: ${event.LogicalResourceId}`,
|
|
5158
|
+
`Type: ${event.ResourceType}`,
|
|
5159
|
+
`Reason: ${event.ResourceStatusReason}`
|
|
5160
|
+
].join("\n");
|
|
5161
|
+
}
|
|
5162
|
+
}
|
|
5163
|
+
return reason;
|
|
5089
5164
|
}
|
|
5090
5165
|
};
|
|
5091
5166
|
|
package/dist/bin.js
CHANGED
|
@@ -163,7 +163,9 @@ var getAtt = (logicalId, attr) => {
|
|
|
163
163
|
return { "Fn::GetAtt": [logicalId, attr] };
|
|
164
164
|
};
|
|
165
165
|
var importValue = (name) => {
|
|
166
|
-
return
|
|
166
|
+
return new Lazy((stack) => ({
|
|
167
|
+
"Fn::ImportValue": `${stack.app.name}-${name}`
|
|
168
|
+
}));
|
|
167
169
|
};
|
|
168
170
|
var formatLogicalId = (id) => {
|
|
169
171
|
return pascalCase(id).replaceAll("_", "");
|
|
@@ -433,10 +435,18 @@ var Stack = class {
|
|
|
433
435
|
this.name = name;
|
|
434
436
|
this.region = region;
|
|
435
437
|
}
|
|
438
|
+
parent;
|
|
436
439
|
exports = /* @__PURE__ */ new Map();
|
|
437
440
|
resources = /* @__PURE__ */ new Set();
|
|
438
441
|
tags = /* @__PURE__ */ new Map();
|
|
439
442
|
assets = /* @__PURE__ */ new Set();
|
|
443
|
+
get app() {
|
|
444
|
+
return this.parent;
|
|
445
|
+
}
|
|
446
|
+
setApp(app) {
|
|
447
|
+
this.parent = app;
|
|
448
|
+
return this;
|
|
449
|
+
}
|
|
440
450
|
add(...resources) {
|
|
441
451
|
for (const item of resources) {
|
|
442
452
|
if (item instanceof Asset) {
|
|
@@ -510,7 +520,9 @@ var Stack = class {
|
|
|
510
520
|
for (const [name, value] of this.exports.entries()) {
|
|
511
521
|
Object.assign(outputs, {
|
|
512
522
|
[formatLogicalId(name)]: {
|
|
513
|
-
Export: {
|
|
523
|
+
Export: {
|
|
524
|
+
Name: `${this.app?.name || "default"}-${name}`
|
|
525
|
+
},
|
|
514
526
|
Value: value
|
|
515
527
|
}
|
|
516
528
|
});
|
|
@@ -2252,6 +2264,9 @@ var Definition = class extends Asset {
|
|
|
2252
2264
|
}));
|
|
2253
2265
|
const defs = mergeTypeDefs(schemas);
|
|
2254
2266
|
const schema2 = print(defs);
|
|
2267
|
+
if (schema2.length === 0) {
|
|
2268
|
+
throw new Error(`Graphql schema definition can't be empty. [${this.id}]`);
|
|
2269
|
+
}
|
|
2255
2270
|
const size = Buffer.from(schema2, "utf8").byteLength;
|
|
2256
2271
|
await write("schema.gql", schema2);
|
|
2257
2272
|
this.schema = schema2;
|
|
@@ -2917,6 +2932,7 @@ var Vpc = class extends Resource {
|
|
|
2917
2932
|
constructor(logicalId, props) {
|
|
2918
2933
|
super("AWS::EC2::VPC", logicalId);
|
|
2919
2934
|
this.props = props;
|
|
2935
|
+
this.tag("Name", props.name);
|
|
2920
2936
|
}
|
|
2921
2937
|
get id() {
|
|
2922
2938
|
return ref(this.logicalId);
|
|
@@ -3079,6 +3095,7 @@ var vpcPlugin = definePlugin({
|
|
|
3079
3095
|
// }),
|
|
3080
3096
|
onApp({ config, bootstrap: bootstrap2 }) {
|
|
3081
3097
|
const vpc = new Vpc("main", {
|
|
3098
|
+
name: config.name,
|
|
3082
3099
|
cidrBlock: Peer.ipv4("10.0.0.0/16")
|
|
3083
3100
|
});
|
|
3084
3101
|
const privateRouteTable = new RouteTable("private", {
|
|
@@ -3808,7 +3825,10 @@ var App = class {
|
|
|
3808
3825
|
}
|
|
3809
3826
|
list = /* @__PURE__ */ new Map();
|
|
3810
3827
|
add(...stacks) {
|
|
3811
|
-
stacks.forEach((stack) =>
|
|
3828
|
+
stacks.forEach((stack) => {
|
|
3829
|
+
this.list.set(stack.name, stack);
|
|
3830
|
+
stack.setApp(this);
|
|
3831
|
+
});
|
|
3812
3832
|
return this;
|
|
3813
3833
|
}
|
|
3814
3834
|
find(resourceType) {
|
|
@@ -4596,6 +4616,7 @@ var Renderer = class {
|
|
|
4596
4616
|
}
|
|
4597
4617
|
}
|
|
4598
4618
|
}
|
|
4619
|
+
await this.setCursor(0, size - start);
|
|
4599
4620
|
this.screen = screen;
|
|
4600
4621
|
this.flushing = false;
|
|
4601
4622
|
}
|
|
@@ -4780,20 +4801,26 @@ var assetBuilder = (app) => {
|
|
|
4780
4801
|
]);
|
|
4781
4802
|
group.update((group2) => [...group2, line]);
|
|
4782
4803
|
const timer = createTimer();
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4804
|
+
try {
|
|
4805
|
+
const data = await asset.build({
|
|
4806
|
+
async write(file, data2) {
|
|
4807
|
+
const fullpath = join4(directories.asset, asset.type, app.name, stack.name, asset.id, file);
|
|
4808
|
+
const basepath = dirname3(fullpath);
|
|
4809
|
+
await mkdir2(basepath, { recursive: true });
|
|
4810
|
+
await writeFile2(fullpath, data2);
|
|
4811
|
+
}
|
|
4812
|
+
});
|
|
4813
|
+
details.set({
|
|
4814
|
+
...data,
|
|
4815
|
+
time: timer()
|
|
4816
|
+
});
|
|
4817
|
+
icon.set(style.success(symbol.success));
|
|
4818
|
+
} catch (error) {
|
|
4819
|
+
icon.set(style.error(symbol.error));
|
|
4820
|
+
throw error;
|
|
4821
|
+
} finally {
|
|
4822
|
+
stop();
|
|
4823
|
+
}
|
|
4797
4824
|
}));
|
|
4798
4825
|
}));
|
|
4799
4826
|
done("Done building stack assets");
|
|
@@ -4877,7 +4904,7 @@ var shouldDeployBootstrap = async (client, stack) => {
|
|
|
4877
4904
|
};
|
|
4878
4905
|
|
|
4879
4906
|
// src/formation/client.ts
|
|
4880
|
-
import { CloudFormationClient, CreateStackCommand, DeleteStackCommand, DescribeStacksCommand, GetTemplateCommand, OnFailure, TemplateStage, UpdateStackCommand, ValidateTemplateCommand, waitUntilStackCreateComplete, waitUntilStackDeleteComplete, waitUntilStackUpdateComplete } from "@aws-sdk/client-cloudformation";
|
|
4907
|
+
import { CloudFormationClient, CreateStackCommand, DeleteStackCommand, DescribeStackEventsCommand, DescribeStacksCommand, GetTemplateCommand, OnFailure, TemplateStage, UpdateStackCommand, ValidateTemplateCommand, waitUntilStackCreateComplete, waitUntilStackDeleteComplete, waitUntilStackUpdateComplete } from "@aws-sdk/client-cloudformation";
|
|
4881
4908
|
import { S3Client, PutObjectCommand, ObjectCannedACL, StorageClass } from "@aws-sdk/client-s3";
|
|
4882
4909
|
import { paramCase as paramCase4 } from "change-case";
|
|
4883
4910
|
var StackClient = class {
|
|
@@ -4891,7 +4918,7 @@ var StackClient = class {
|
|
|
4891
4918
|
maxWaitTime = 60 * 30;
|
|
4892
4919
|
// 30 minutes
|
|
4893
4920
|
maxDelay = 30;
|
|
4894
|
-
//
|
|
4921
|
+
// 10 seconds
|
|
4895
4922
|
assetBucketName;
|
|
4896
4923
|
getClient(region) {
|
|
4897
4924
|
return new CloudFormationClient({
|
|
@@ -4938,7 +4965,7 @@ var StackClient = class {
|
|
|
4938
4965
|
async create(stack, capabilities) {
|
|
4939
4966
|
debug("Create the", style.info(stack.name), "stack");
|
|
4940
4967
|
const client = this.getClient(stack.region);
|
|
4941
|
-
await client.send(new CreateStackCommand({
|
|
4968
|
+
const result = await client.send(new CreateStackCommand({
|
|
4942
4969
|
StackName: this.stackName(stack.name),
|
|
4943
4970
|
EnableTerminationProtection: false,
|
|
4944
4971
|
OnFailure: OnFailure.DELETE,
|
|
@@ -4946,36 +4973,53 @@ var StackClient = class {
|
|
|
4946
4973
|
Tags: this.tags(stack),
|
|
4947
4974
|
...this.templateProp(stack)
|
|
4948
4975
|
}));
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4976
|
+
try {
|
|
4977
|
+
await waitUntilStackCreateComplete({
|
|
4978
|
+
client,
|
|
4979
|
+
maxWaitTime: this.maxWaitTime,
|
|
4980
|
+
maxDelay: this.maxDelay
|
|
4981
|
+
}, {
|
|
4982
|
+
StackName: result.StackId
|
|
4983
|
+
});
|
|
4984
|
+
} catch (_) {
|
|
4985
|
+
const reason = await this.getFailureReason(
|
|
4986
|
+
result.StackId,
|
|
4987
|
+
stack.region
|
|
4988
|
+
);
|
|
4989
|
+
throw new Error(reason);
|
|
4990
|
+
}
|
|
4956
4991
|
}
|
|
4957
4992
|
async update(stack, capabilities) {
|
|
4958
4993
|
debug("Update the", style.info(stack.name), "stack");
|
|
4959
4994
|
const client = this.getClient(stack.region);
|
|
4995
|
+
let result;
|
|
4960
4996
|
try {
|
|
4961
|
-
await client.send(new UpdateStackCommand({
|
|
4997
|
+
result = await client.send(new UpdateStackCommand({
|
|
4962
4998
|
StackName: this.stackName(stack.name),
|
|
4963
4999
|
Capabilities: capabilities,
|
|
4964
5000
|
Tags: this.tags(stack),
|
|
4965
5001
|
...this.templateProp(stack)
|
|
4966
5002
|
}));
|
|
5003
|
+
} catch (error) {
|
|
5004
|
+
if (error instanceof Error && error.name === "ValidationError" && error.message.toLowerCase().includes("no updates")) {
|
|
5005
|
+
return;
|
|
5006
|
+
}
|
|
5007
|
+
throw error;
|
|
5008
|
+
}
|
|
5009
|
+
try {
|
|
4967
5010
|
await waitUntilStackUpdateComplete({
|
|
4968
5011
|
client,
|
|
4969
5012
|
maxWaitTime: this.maxWaitTime,
|
|
4970
5013
|
maxDelay: this.maxDelay
|
|
4971
5014
|
}, {
|
|
4972
|
-
StackName:
|
|
5015
|
+
StackName: result.StackId
|
|
4973
5016
|
});
|
|
4974
5017
|
} catch (error) {
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
5018
|
+
const reason = await this.getFailureReason(
|
|
5019
|
+
result.StackId,
|
|
5020
|
+
stack.region
|
|
5021
|
+
);
|
|
5022
|
+
throw new Error(reason);
|
|
4979
5023
|
}
|
|
4980
5024
|
}
|
|
4981
5025
|
async validate(stack) {
|
|
@@ -5056,13 +5100,44 @@ var StackClient = class {
|
|
|
5056
5100
|
await client.send(new DeleteStackCommand({
|
|
5057
5101
|
StackName: this.stackName(name)
|
|
5058
5102
|
}));
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5103
|
+
try {
|
|
5104
|
+
await waitUntilStackDeleteComplete({
|
|
5105
|
+
client,
|
|
5106
|
+
maxWaitTime: this.maxWaitTime,
|
|
5107
|
+
maxDelay: this.maxDelay
|
|
5108
|
+
}, {
|
|
5109
|
+
StackName: this.stackName(name)
|
|
5110
|
+
});
|
|
5111
|
+
} catch (_) {
|
|
5112
|
+
const reason = await this.getFailureReason(name, region);
|
|
5113
|
+
throw new Error(reason);
|
|
5114
|
+
}
|
|
5115
|
+
}
|
|
5116
|
+
async getFailureReason(name, region) {
|
|
5117
|
+
const client = this.getClient(region);
|
|
5118
|
+
const result = await client.send(await new DescribeStackEventsCommand({
|
|
5119
|
+
StackName: name
|
|
5120
|
+
}));
|
|
5121
|
+
const failureStatuses = [
|
|
5122
|
+
"UPDATE_ROLLBACK_IN_PROGRESS",
|
|
5123
|
+
"CREATE_FAILED",
|
|
5124
|
+
"UPDATE_FAILED",
|
|
5125
|
+
"DELETE_FAILED"
|
|
5126
|
+
];
|
|
5127
|
+
let reason = "Unknown failure reason";
|
|
5128
|
+
for (const event of result.StackEvents || []) {
|
|
5129
|
+
if (event.ResourceStatusReason?.toLowerCase() === "user initiated") {
|
|
5130
|
+
break;
|
|
5131
|
+
}
|
|
5132
|
+
if (failureStatuses.includes(event.ResourceStatus || "") && event.ResourceStatusReason) {
|
|
5133
|
+
reason = [
|
|
5134
|
+
`Logical ID: ${event.LogicalResourceId}`,
|
|
5135
|
+
`Type: ${event.ResourceType}`,
|
|
5136
|
+
`Reason: ${event.ResourceStatusReason}`
|
|
5137
|
+
].join("\n");
|
|
5138
|
+
}
|
|
5139
|
+
}
|
|
5140
|
+
return reason;
|
|
5066
5141
|
}
|
|
5067
5142
|
};
|
|
5068
5143
|
|
package/dist/index.d.ts
CHANGED
|
@@ -2320,11 +2320,14 @@ type ConstructorOf<C> = {
|
|
|
2320
2320
|
declare class Stack {
|
|
2321
2321
|
readonly name: string;
|
|
2322
2322
|
readonly region: Region;
|
|
2323
|
+
private parent?;
|
|
2323
2324
|
readonly exports: Map<string, string>;
|
|
2324
2325
|
readonly resources: Set<Resource>;
|
|
2325
2326
|
readonly tags: Map<string, string>;
|
|
2326
2327
|
readonly assets: Set<Asset>;
|
|
2327
2328
|
constructor(name: string, region: Region);
|
|
2329
|
+
get app(): App | undefined;
|
|
2330
|
+
setApp(app: App): this;
|
|
2328
2331
|
add(...resources: (Resource | Asset | Group)[]): this;
|
|
2329
2332
|
export(name: string, value: string): this;
|
|
2330
2333
|
get(name: string): string;
|