@awsless/awsless 0.0.19 → 0.0.21
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 +482 -189
- package/dist/bin.js +483 -190
- package/dist/index.d.ts +242 -5
- package/package.json +3 -1
package/dist/bin.js
CHANGED
|
@@ -171,6 +171,12 @@ var formatLogicalId = (id) => {
|
|
|
171
171
|
var formatName = (name) => {
|
|
172
172
|
return paramCase2(name);
|
|
173
173
|
};
|
|
174
|
+
var formatArn = (props) => {
|
|
175
|
+
return sub("arn:${AWS::Partition}:${service}:${AWS::Region}:${AWS::AccountId}:${resource}${seperator}${resourceName}", {
|
|
176
|
+
seperator: "/",
|
|
177
|
+
...props
|
|
178
|
+
});
|
|
179
|
+
};
|
|
174
180
|
|
|
175
181
|
// src/formation/resource.ts
|
|
176
182
|
var Resource = class {
|
|
@@ -180,13 +186,19 @@ var Resource = class {
|
|
|
180
186
|
this.logicalId = formatLogicalId(`${logicalId}-${type.replace(/^AWS::/, "")}`);
|
|
181
187
|
}
|
|
182
188
|
logicalId;
|
|
189
|
+
tags = /* @__PURE__ */ new Map();
|
|
183
190
|
deps = /* @__PURE__ */ new Set();
|
|
191
|
+
stack;
|
|
184
192
|
dependsOn(...dependencies) {
|
|
185
193
|
for (const dependency of dependencies) {
|
|
186
194
|
this.deps.add(dependency);
|
|
187
195
|
}
|
|
188
196
|
return this;
|
|
189
197
|
}
|
|
198
|
+
tag(key, value) {
|
|
199
|
+
this.tags.set(key, value);
|
|
200
|
+
return this;
|
|
201
|
+
}
|
|
190
202
|
attr(name, value) {
|
|
191
203
|
if (typeof value === "undefined") {
|
|
192
204
|
return {};
|
|
@@ -195,12 +207,41 @@ var Resource = class {
|
|
|
195
207
|
[name]: value
|
|
196
208
|
};
|
|
197
209
|
}
|
|
210
|
+
setStack(stack) {
|
|
211
|
+
this.stack = stack;
|
|
212
|
+
return this;
|
|
213
|
+
}
|
|
214
|
+
ref() {
|
|
215
|
+
return this.getAtt("ref");
|
|
216
|
+
}
|
|
217
|
+
getAtt(attr) {
|
|
218
|
+
return new Lazy((stack) => {
|
|
219
|
+
if (!this.stack) {
|
|
220
|
+
throw new TypeError("Resource stack not defined before building template");
|
|
221
|
+
}
|
|
222
|
+
const value = attr === "ref" ? ref(this.logicalId) : getAtt(this.logicalId, attr);
|
|
223
|
+
if (stack === this.stack) {
|
|
224
|
+
return value;
|
|
225
|
+
}
|
|
226
|
+
const name = `${this.stack.name}-${this.logicalId}-${attr}`;
|
|
227
|
+
this.stack.export(name, value);
|
|
228
|
+
return this.stack.import(name);
|
|
229
|
+
});
|
|
230
|
+
}
|
|
198
231
|
toJSON() {
|
|
199
232
|
return {
|
|
200
233
|
[this.logicalId]: {
|
|
201
234
|
Type: this.type,
|
|
202
235
|
DependsOn: [...this.deps].map((dep) => dep.logicalId),
|
|
203
|
-
Properties:
|
|
236
|
+
Properties: {
|
|
237
|
+
...this.tags.size ? {
|
|
238
|
+
Tags: Array.from(this.tags.entries()).map(([key, value]) => ({
|
|
239
|
+
Key: key,
|
|
240
|
+
Value: value
|
|
241
|
+
}))
|
|
242
|
+
} : {},
|
|
243
|
+
...this.properties()
|
|
244
|
+
}
|
|
204
245
|
}
|
|
205
246
|
};
|
|
206
247
|
}
|
|
@@ -210,6 +251,11 @@ var Group = class {
|
|
|
210
251
|
this.children = children;
|
|
211
252
|
}
|
|
212
253
|
};
|
|
254
|
+
var Lazy = class {
|
|
255
|
+
constructor(callback) {
|
|
256
|
+
this.callback = callback;
|
|
257
|
+
}
|
|
258
|
+
};
|
|
213
259
|
|
|
214
260
|
// src/formation/resource/iam/inline-policy.ts
|
|
215
261
|
var InlinePolicy = class {
|
|
@@ -315,6 +361,7 @@ var Function = class extends Resource {
|
|
|
315
361
|
this.policy = policy;
|
|
316
362
|
this.name = formatName(this.props.name || logicalId);
|
|
317
363
|
this.environmentVariables = props.environment ? { ...props.environment } : {};
|
|
364
|
+
this.tag("name", this.name);
|
|
318
365
|
}
|
|
319
366
|
name;
|
|
320
367
|
role;
|
|
@@ -328,11 +375,15 @@ var Function = class extends Resource {
|
|
|
328
375
|
this.environmentVariables[name] = value;
|
|
329
376
|
return this;
|
|
330
377
|
}
|
|
378
|
+
setVpc(vpc) {
|
|
379
|
+
this.props.vpc = vpc;
|
|
380
|
+
return this;
|
|
381
|
+
}
|
|
331
382
|
get id() {
|
|
332
|
-
return ref(
|
|
383
|
+
return this.ref();
|
|
333
384
|
}
|
|
334
385
|
get arn() {
|
|
335
|
-
return getAtt(
|
|
386
|
+
return this.getAtt("Arn");
|
|
336
387
|
}
|
|
337
388
|
get permissions() {
|
|
338
389
|
return {
|
|
@@ -340,7 +391,14 @@ var Function = class extends Resource {
|
|
|
340
391
|
"lambda:InvokeFunction",
|
|
341
392
|
"lambda:InvokeAsync"
|
|
342
393
|
],
|
|
343
|
-
resources: [
|
|
394
|
+
resources: [
|
|
395
|
+
formatArn({
|
|
396
|
+
service: "lambda",
|
|
397
|
+
resource: "function",
|
|
398
|
+
resourceName: this.name,
|
|
399
|
+
seperator: ":"
|
|
400
|
+
})
|
|
401
|
+
]
|
|
344
402
|
};
|
|
345
403
|
}
|
|
346
404
|
properties() {
|
|
@@ -356,6 +414,12 @@ var Function = class extends Resource {
|
|
|
356
414
|
EphemeralStorage: {
|
|
357
415
|
Size: this.props.ephemeralStorageSize?.toMegaBytes() ?? 512
|
|
358
416
|
},
|
|
417
|
+
...this.props.vpc ? {
|
|
418
|
+
VpcConfig: {
|
|
419
|
+
SecurityGroupIds: this.props.vpc.securityGroupIds,
|
|
420
|
+
SubnetIds: this.props.vpc.subnetIds
|
|
421
|
+
}
|
|
422
|
+
} : {},
|
|
359
423
|
Environment: {
|
|
360
424
|
Variables: this.environmentVariables
|
|
361
425
|
}
|
|
@@ -380,6 +444,7 @@ var Stack = class {
|
|
|
380
444
|
} else {
|
|
381
445
|
this.add(...item.children);
|
|
382
446
|
if (item instanceof Resource) {
|
|
447
|
+
item.setStack(this);
|
|
383
448
|
this.resources.add(item);
|
|
384
449
|
}
|
|
385
450
|
}
|
|
@@ -423,8 +488,24 @@ var Stack = class {
|
|
|
423
488
|
toJSON() {
|
|
424
489
|
const resources = {};
|
|
425
490
|
const outputs = {};
|
|
491
|
+
const walk = (object) => {
|
|
492
|
+
for (const [key, value] of Object.entries(object)) {
|
|
493
|
+
if (!object.hasOwnProperty(key)) {
|
|
494
|
+
continue;
|
|
495
|
+
}
|
|
496
|
+
if (value instanceof Lazy) {
|
|
497
|
+
object[key] = value.callback(this);
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
if (typeof value === "object" && value !== null) {
|
|
501
|
+
walk(value);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
};
|
|
426
505
|
for (const resource of this) {
|
|
427
|
-
|
|
506
|
+
const json2 = resource.toJSON();
|
|
507
|
+
walk(json2);
|
|
508
|
+
Object.assign(resources, json2);
|
|
428
509
|
}
|
|
429
510
|
for (const [name, value] of this.exports.entries()) {
|
|
430
511
|
Object.assign(outputs, {
|
|
@@ -492,54 +573,35 @@ var toStack = ({ config, app, stackConfig, bootstrap: bootstrap2, usEastBootstra
|
|
|
492
573
|
}
|
|
493
574
|
return {
|
|
494
575
|
stack,
|
|
495
|
-
|
|
576
|
+
bindings
|
|
577
|
+
// depends: stackConfig.depends,
|
|
496
578
|
};
|
|
497
579
|
};
|
|
498
580
|
|
|
499
581
|
// src/util/deployment.ts
|
|
500
|
-
var
|
|
582
|
+
var createDeploymentLine = (stacks) => {
|
|
501
583
|
const list3 = stacks.map(({ stack, config }) => ({
|
|
502
584
|
stack,
|
|
503
585
|
depends: config?.depends?.map((dep) => dep.name) || []
|
|
504
586
|
}));
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
587
|
+
const names = stacks.map(({ stack }) => stack.name);
|
|
588
|
+
const line = [];
|
|
589
|
+
const deps = [];
|
|
590
|
+
let limit = 100;
|
|
591
|
+
while (deps.length < list3.length) {
|
|
592
|
+
const local = [];
|
|
593
|
+
for (const { stack, depends } of list3) {
|
|
594
|
+
if (!deps.includes(stack.name) && depends.filter((dep) => !deps.includes(dep)).length === 0) {
|
|
595
|
+
local.push(stack);
|
|
514
596
|
}
|
|
515
597
|
}
|
|
516
|
-
if (
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
children: []
|
|
520
|
-
}));
|
|
598
|
+
if (limit-- <= 0) {
|
|
599
|
+
const circularNames = names.filter((name) => deps.includes(name));
|
|
600
|
+
throw new Error(`Circular stack dependencies arn't allowed: ${circularNames}`);
|
|
521
601
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
children: findChildren(rests, [...parents, stack.name])
|
|
526
|
-
};
|
|
527
|
-
});
|
|
528
|
-
};
|
|
529
|
-
return findChildren(list3, []);
|
|
530
|
-
};
|
|
531
|
-
var createDeploymentLine = (stacks) => {
|
|
532
|
-
const line = [];
|
|
533
|
-
const walk = (stacks2, level) => {
|
|
534
|
-
stacks2.forEach((node) => {
|
|
535
|
-
if (!line[level]) {
|
|
536
|
-
line[level] = [];
|
|
537
|
-
}
|
|
538
|
-
line[level].push(node.stack);
|
|
539
|
-
walk(node.children, level + 1);
|
|
540
|
-
});
|
|
541
|
-
};
|
|
542
|
-
walk(stacks, 0);
|
|
602
|
+
deps.push(...local.map((stack) => stack.name));
|
|
603
|
+
line.push(local);
|
|
604
|
+
}
|
|
543
605
|
return line;
|
|
544
606
|
};
|
|
545
607
|
|
|
@@ -936,8 +998,12 @@ var RuntimeSchema = z6.enum([
|
|
|
936
998
|
var FunctionSchema = z6.union([
|
|
937
999
|
LocalFileSchema,
|
|
938
1000
|
z6.object({
|
|
939
|
-
/** The file path
|
|
1001
|
+
/** The file path of the function code. */
|
|
940
1002
|
file: LocalFileSchema,
|
|
1003
|
+
/** Put the function inside your global VPC.
|
|
1004
|
+
* @default false
|
|
1005
|
+
*/
|
|
1006
|
+
vpc: z6.boolean().optional(),
|
|
941
1007
|
/** The amount of time that Lambda allows a function to run before stopping it.
|
|
942
1008
|
* You can specify a size value from 1 second to 15 minutes.
|
|
943
1009
|
* @default '10 seconds'
|
|
@@ -987,6 +1053,10 @@ var FunctionSchema = z6.union([
|
|
|
987
1053
|
var schema = z6.object({
|
|
988
1054
|
defaults: z6.object({
|
|
989
1055
|
function: z6.object({
|
|
1056
|
+
/** Put the function inside your global VPC.
|
|
1057
|
+
* @default false
|
|
1058
|
+
*/
|
|
1059
|
+
vpc: z6.boolean().default(false),
|
|
990
1060
|
/** The amount of time that Lambda allows a function to run before stopping it.
|
|
991
1061
|
* You can specify a size value from 1 second to 15 minutes.
|
|
992
1062
|
* @default '10 seconds'
|
|
@@ -1078,12 +1148,36 @@ var toLambdaFunction = (ctx, id, fileOrProps) => {
|
|
|
1078
1148
|
const lambda = new Function(id, {
|
|
1079
1149
|
name: `${config.name}-${stack.name}-${id}`,
|
|
1080
1150
|
code: Code.fromFile(id, props.file),
|
|
1081
|
-
...props
|
|
1151
|
+
...props,
|
|
1152
|
+
vpc: void 0
|
|
1082
1153
|
});
|
|
1083
1154
|
lambda.addEnvironment("APP", config.name).addEnvironment("STAGE", config.stage).addEnvironment("STACK", stack.name);
|
|
1155
|
+
if (props.vpc) {
|
|
1156
|
+
lambda.setVpc({
|
|
1157
|
+
securityGroupIds: [
|
|
1158
|
+
ctx.bootstrap.import(`vpc-security-group-id`)
|
|
1159
|
+
],
|
|
1160
|
+
subnetIds: [
|
|
1161
|
+
ctx.bootstrap.import(`public-subnet-1`),
|
|
1162
|
+
ctx.bootstrap.import(`public-subnet-2`)
|
|
1163
|
+
]
|
|
1164
|
+
}).addPermissions({
|
|
1165
|
+
actions: [
|
|
1166
|
+
"ec2:CreateNetworkInterface",
|
|
1167
|
+
"ec2:DescribeNetworkInterfaces",
|
|
1168
|
+
"ec2:DeleteNetworkInterface",
|
|
1169
|
+
"ec2:AssignPrivateIpAddresses",
|
|
1170
|
+
"ec2:UnassignPrivateIpAddresses"
|
|
1171
|
+
],
|
|
1172
|
+
resources: ["*"]
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1084
1175
|
if (props.runtime.startsWith("nodejs")) {
|
|
1085
1176
|
lambda.addEnvironment("AWS_NODEJS_CONNECTION_REUSE_ENABLED", "1");
|
|
1086
1177
|
}
|
|
1178
|
+
ctx.bind((other) => {
|
|
1179
|
+
other.addPermissions(lambda.permissions);
|
|
1180
|
+
});
|
|
1087
1181
|
return lambda;
|
|
1088
1182
|
};
|
|
1089
1183
|
|
|
@@ -1207,6 +1301,7 @@ var Queue = class extends Resource {
|
|
|
1207
1301
|
super("AWS::SQS::Queue", logicalId);
|
|
1208
1302
|
this.props = props;
|
|
1209
1303
|
this.name = formatName(this.props.name || logicalId);
|
|
1304
|
+
this.tag("name", this.name);
|
|
1210
1305
|
}
|
|
1211
1306
|
name;
|
|
1212
1307
|
setDeadLetter(arn) {
|
|
@@ -1227,7 +1322,13 @@ var Queue = class extends Resource {
|
|
|
1227
1322
|
"sqs:GetQueueUrl",
|
|
1228
1323
|
"sqs:GetQueueAttributes"
|
|
1229
1324
|
],
|
|
1230
|
-
resources: [
|
|
1325
|
+
resources: [
|
|
1326
|
+
formatArn({
|
|
1327
|
+
service: "sqs",
|
|
1328
|
+
resource: "queue",
|
|
1329
|
+
resourceName: this.name
|
|
1330
|
+
})
|
|
1331
|
+
]
|
|
1231
1332
|
};
|
|
1232
1333
|
}
|
|
1233
1334
|
properties() {
|
|
@@ -1454,6 +1555,7 @@ var Table = class extends Resource {
|
|
|
1454
1555
|
this.props = props;
|
|
1455
1556
|
this.name = formatName(this.props.name || logicalId);
|
|
1456
1557
|
this.indexes = { ...this.props.indexes || {} };
|
|
1558
|
+
this.tag("name", this.name);
|
|
1457
1559
|
}
|
|
1458
1560
|
name;
|
|
1459
1561
|
indexes;
|
|
@@ -1486,7 +1588,13 @@ var Table = class extends Resource {
|
|
|
1486
1588
|
"dynamodb:Query",
|
|
1487
1589
|
"dynamodb:Scan"
|
|
1488
1590
|
],
|
|
1489
|
-
resources: [
|
|
1591
|
+
resources: [
|
|
1592
|
+
formatArn({
|
|
1593
|
+
service: "dynamodb",
|
|
1594
|
+
resource: "table",
|
|
1595
|
+
resourceName: this.name
|
|
1596
|
+
})
|
|
1597
|
+
]
|
|
1490
1598
|
};
|
|
1491
1599
|
}
|
|
1492
1600
|
attributeDefinitions() {
|
|
@@ -1720,6 +1828,7 @@ var Bucket = class extends Resource {
|
|
|
1720
1828
|
super("AWS::S3::Bucket", logicalId);
|
|
1721
1829
|
this.props = props;
|
|
1722
1830
|
this.name = formatName(this.props.name || logicalId);
|
|
1831
|
+
this.tag("name", this.name);
|
|
1723
1832
|
}
|
|
1724
1833
|
name;
|
|
1725
1834
|
get arn() {
|
|
@@ -1736,7 +1845,13 @@ var Bucket = class extends Resource {
|
|
|
1736
1845
|
"s3:GetQueueUrl",
|
|
1737
1846
|
"s3:GetQueueAttributes"
|
|
1738
1847
|
],
|
|
1739
|
-
resources: [
|
|
1848
|
+
resources: [
|
|
1849
|
+
formatArn({
|
|
1850
|
+
service: "s3",
|
|
1851
|
+
resource: "bucket",
|
|
1852
|
+
resourceName: this.name
|
|
1853
|
+
})
|
|
1854
|
+
]
|
|
1740
1855
|
};
|
|
1741
1856
|
}
|
|
1742
1857
|
properties() {
|
|
@@ -1789,6 +1904,7 @@ var Topic = class extends Resource {
|
|
|
1789
1904
|
super("AWS::SNS::Topic", logicalId);
|
|
1790
1905
|
this.props = props;
|
|
1791
1906
|
this.name = formatName(this.props.name || logicalId);
|
|
1907
|
+
this.tag("name", this.name);
|
|
1792
1908
|
}
|
|
1793
1909
|
name;
|
|
1794
1910
|
get arn() {
|
|
@@ -1797,7 +1913,13 @@ var Topic = class extends Resource {
|
|
|
1797
1913
|
get permissions() {
|
|
1798
1914
|
return {
|
|
1799
1915
|
actions: ["sns:Publish"],
|
|
1800
|
-
resources: [
|
|
1916
|
+
resources: [
|
|
1917
|
+
formatArn({
|
|
1918
|
+
service: "sns",
|
|
1919
|
+
resource: "topic",
|
|
1920
|
+
resourceName: this.name
|
|
1921
|
+
})
|
|
1922
|
+
]
|
|
1801
1923
|
};
|
|
1802
1924
|
}
|
|
1803
1925
|
properties() {
|
|
@@ -2030,6 +2152,7 @@ var GraphQLApi = class extends Resource {
|
|
|
2030
2152
|
super("AWS::AppSync::GraphQLApi", logicalId);
|
|
2031
2153
|
this.props = props;
|
|
2032
2154
|
this.name = formatName(this.props.name || logicalId);
|
|
2155
|
+
this.tag("name", this.name);
|
|
2033
2156
|
}
|
|
2034
2157
|
name;
|
|
2035
2158
|
lambdaAuthProviders = [];
|
|
@@ -2794,6 +2917,12 @@ var Vpc = class extends Resource {
|
|
|
2794
2917
|
get id() {
|
|
2795
2918
|
return ref(this.logicalId);
|
|
2796
2919
|
}
|
|
2920
|
+
get defaultNetworkAcl() {
|
|
2921
|
+
return getAtt(this.logicalId, "DefaultNetworkAcl");
|
|
2922
|
+
}
|
|
2923
|
+
get defaultSecurityGroup() {
|
|
2924
|
+
return getAtt(this.logicalId, "DefaultSecurityGroup");
|
|
2925
|
+
}
|
|
2797
2926
|
properties() {
|
|
2798
2927
|
return {
|
|
2799
2928
|
CidrBlock: this.props.cidrBlock.ip
|
|
@@ -2805,6 +2934,7 @@ var RouteTable = class extends Resource {
|
|
|
2805
2934
|
super("AWS::EC2::RouteTable", logicalId);
|
|
2806
2935
|
this.props = props;
|
|
2807
2936
|
this.name = formatName(props.name || logicalId);
|
|
2937
|
+
this.tag("name", this.name);
|
|
2808
2938
|
}
|
|
2809
2939
|
name;
|
|
2810
2940
|
get id() {
|
|
@@ -2812,11 +2942,7 @@ var RouteTable = class extends Resource {
|
|
|
2812
2942
|
}
|
|
2813
2943
|
properties() {
|
|
2814
2944
|
return {
|
|
2815
|
-
VpcId: this.props.vpcId
|
|
2816
|
-
Tags: [{
|
|
2817
|
-
Key: "name",
|
|
2818
|
-
Value: this.name
|
|
2819
|
-
}]
|
|
2945
|
+
VpcId: this.props.vpcId
|
|
2820
2946
|
};
|
|
2821
2947
|
}
|
|
2822
2948
|
};
|
|
@@ -2969,6 +3095,7 @@ var vpcPlugin = definePlugin({
|
|
|
2969
3095
|
routeTableId: publicRouteTable.id,
|
|
2970
3096
|
destination: Peer.anyIpv4()
|
|
2971
3097
|
}).dependsOn(gateway, publicRouteTable);
|
|
3098
|
+
bootstrap2.export("vpc-security-group-id", vpc.defaultSecurityGroup);
|
|
2972
3099
|
bootstrap2.export(`vpc-id`, vpc.id);
|
|
2973
3100
|
bootstrap2.add(
|
|
2974
3101
|
vpc,
|
|
@@ -3011,7 +3138,9 @@ var SecurityGroup = class extends Resource {
|
|
|
3011
3138
|
constructor(logicalId, props) {
|
|
3012
3139
|
super("AWS::EC2::SecurityGroup", logicalId);
|
|
3013
3140
|
this.props = props;
|
|
3141
|
+
this.name = formatName(props.name ?? logicalId);
|
|
3014
3142
|
}
|
|
3143
|
+
name;
|
|
3015
3144
|
ingress = [];
|
|
3016
3145
|
egress = [];
|
|
3017
3146
|
get id() {
|
|
@@ -3036,7 +3165,7 @@ var SecurityGroup = class extends Resource {
|
|
|
3036
3165
|
properties() {
|
|
3037
3166
|
return {
|
|
3038
3167
|
VpcId: this.props.vpcId,
|
|
3039
|
-
GroupName: this.
|
|
3168
|
+
GroupName: this.name,
|
|
3040
3169
|
GroupDescription: this.props.description,
|
|
3041
3170
|
SecurityGroupIngress: this.ingress.map((rule) => ({
|
|
3042
3171
|
Description: rule.description || "",
|
|
@@ -3447,6 +3576,7 @@ var Collection = class extends Resource {
|
|
|
3447
3576
|
super("AWS::OpenSearchServerless::Collection", logicalId);
|
|
3448
3577
|
this.props = props;
|
|
3449
3578
|
this.name = this.props.name || logicalId;
|
|
3579
|
+
this.tag("name", this.name);
|
|
3450
3580
|
}
|
|
3451
3581
|
name;
|
|
3452
3582
|
get id() {
|
|
@@ -3458,6 +3588,18 @@ var Collection = class extends Resource {
|
|
|
3458
3588
|
get endpoint() {
|
|
3459
3589
|
return getAtt(this.logicalId, "CollectionEndpoint");
|
|
3460
3590
|
}
|
|
3591
|
+
get permissions() {
|
|
3592
|
+
return {
|
|
3593
|
+
actions: ["aoss:APIAccessAll"],
|
|
3594
|
+
resources: [
|
|
3595
|
+
formatArn({
|
|
3596
|
+
service: "aoss",
|
|
3597
|
+
resource: "collection",
|
|
3598
|
+
resourceName: this.name
|
|
3599
|
+
})
|
|
3600
|
+
]
|
|
3601
|
+
};
|
|
3602
|
+
}
|
|
3461
3603
|
properties() {
|
|
3462
3604
|
return {
|
|
3463
3605
|
Name: this.name,
|
|
@@ -3482,10 +3624,155 @@ var searchPlugin = definePlugin({
|
|
|
3482
3624
|
type: "search"
|
|
3483
3625
|
});
|
|
3484
3626
|
bind((lambda) => {
|
|
3485
|
-
lambda.addPermissions(
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3627
|
+
lambda.addPermissions(collection.permissions);
|
|
3628
|
+
});
|
|
3629
|
+
}
|
|
3630
|
+
}
|
|
3631
|
+
});
|
|
3632
|
+
|
|
3633
|
+
// src/plugins/cache.ts
|
|
3634
|
+
import { z as z19 } from "zod";
|
|
3635
|
+
|
|
3636
|
+
// src/formation/resource/memorydb/cluster.ts
|
|
3637
|
+
var Cluster = class extends Resource {
|
|
3638
|
+
constructor(logicalId, props) {
|
|
3639
|
+
super("AWS::MemoryDB::Cluster", logicalId);
|
|
3640
|
+
this.props = props;
|
|
3641
|
+
this.name = formatName(this.props.name || logicalId);
|
|
3642
|
+
this.tag("name", this.name);
|
|
3643
|
+
}
|
|
3644
|
+
name;
|
|
3645
|
+
get status() {
|
|
3646
|
+
return this.getAtt("Status");
|
|
3647
|
+
}
|
|
3648
|
+
get arn() {
|
|
3649
|
+
return this.getAtt("ARN");
|
|
3650
|
+
}
|
|
3651
|
+
get address() {
|
|
3652
|
+
return this.getAtt("ClusterEndpoint.Address");
|
|
3653
|
+
}
|
|
3654
|
+
get port() {
|
|
3655
|
+
return this.getAtt("ClusterEndpoint.Port");
|
|
3656
|
+
}
|
|
3657
|
+
properties() {
|
|
3658
|
+
return {
|
|
3659
|
+
ClusterName: this.name,
|
|
3660
|
+
ClusterEndpoint: {
|
|
3661
|
+
Port: this.props.port
|
|
3662
|
+
},
|
|
3663
|
+
Port: this.props.port,
|
|
3664
|
+
...this.attr("Description", this.props.description),
|
|
3665
|
+
ACLName: this.props.aclName,
|
|
3666
|
+
EngineVersion: this.props.engine ?? "7.0",
|
|
3667
|
+
...this.attr("SubnetGroupName", this.props.subnetGroupName),
|
|
3668
|
+
...this.attr("SecurityGroupIds", this.props.securityGroupIds),
|
|
3669
|
+
NodeType: "db." + this.props.type,
|
|
3670
|
+
NumReplicasPerShard: this.props.replicasPerShard ?? 1,
|
|
3671
|
+
NumShards: this.props.shards ?? 1,
|
|
3672
|
+
TLSEnabled: this.props.tls ?? false,
|
|
3673
|
+
DataTiering: this.props.dataTiering ? "true" : "false",
|
|
3674
|
+
AutoMinorVersionUpgrade: this.props.autoMinorVersionUpgrade ?? true,
|
|
3675
|
+
MaintenanceWindow: this.props.maintenanceWindow ?? "Sat:02:00-Sat:05:00"
|
|
3676
|
+
};
|
|
3677
|
+
}
|
|
3678
|
+
};
|
|
3679
|
+
|
|
3680
|
+
// src/formation/resource/memorydb/subnet-group.ts
|
|
3681
|
+
var SubnetGroup = class extends Resource {
|
|
3682
|
+
constructor(logicalId, props) {
|
|
3683
|
+
super("AWS::MemoryDB::SubnetGroup", logicalId);
|
|
3684
|
+
this.props = props;
|
|
3685
|
+
this.name = formatName(this.props.name || logicalId);
|
|
3686
|
+
}
|
|
3687
|
+
name;
|
|
3688
|
+
get arn() {
|
|
3689
|
+
return getAtt(this.logicalId, "Arn");
|
|
3690
|
+
}
|
|
3691
|
+
properties() {
|
|
3692
|
+
return {
|
|
3693
|
+
SubnetGroupName: this.name,
|
|
3694
|
+
SubnetIds: this.props.subnetIds,
|
|
3695
|
+
...this.attr("Description", this.props.description)
|
|
3696
|
+
};
|
|
3697
|
+
}
|
|
3698
|
+
};
|
|
3699
|
+
|
|
3700
|
+
// src/plugins/cache.ts
|
|
3701
|
+
var TypeSchema = z19.enum([
|
|
3702
|
+
"t4g.small",
|
|
3703
|
+
"t4g.medium",
|
|
3704
|
+
"r6g.large",
|
|
3705
|
+
"r6g.xlarge",
|
|
3706
|
+
"r6g.2xlarge",
|
|
3707
|
+
"r6g.4xlarge",
|
|
3708
|
+
"r6g.8xlarge",
|
|
3709
|
+
"r6g.12xlarge",
|
|
3710
|
+
"r6g.16xlarge",
|
|
3711
|
+
"r6gd.xlarge",
|
|
3712
|
+
"r6gd.2xlarge",
|
|
3713
|
+
"r6gd.4xlarge",
|
|
3714
|
+
"r6gd.8xlarge"
|
|
3715
|
+
]);
|
|
3716
|
+
var PortSchema = z19.number().int().min(1).max(5e4);
|
|
3717
|
+
var ShardsSchema = z19.number().int().min(0).max(100);
|
|
3718
|
+
var ReplicasPerShardSchema = z19.number().int().min(0).max(5);
|
|
3719
|
+
var EngineSchema = z19.enum(["7.0", "6.2"]);
|
|
3720
|
+
var cachePlugin = definePlugin({
|
|
3721
|
+
name: "cache",
|
|
3722
|
+
schema: z19.object({
|
|
3723
|
+
stacks: z19.object({
|
|
3724
|
+
/** Define the caches in your stack.
|
|
3725
|
+
* For access to the cache put your functions inside the global VPC.
|
|
3726
|
+
* @example
|
|
3727
|
+
* {
|
|
3728
|
+
* caches: {
|
|
3729
|
+
* CACHE_NAME: {
|
|
3730
|
+
* type: 't4g.small'
|
|
3731
|
+
* }
|
|
3732
|
+
* }
|
|
3733
|
+
* }
|
|
3734
|
+
*/
|
|
3735
|
+
caches: z19.record(
|
|
3736
|
+
ResourceIdSchema,
|
|
3737
|
+
z19.object({
|
|
3738
|
+
type: TypeSchema.default("t4g.small"),
|
|
3739
|
+
port: PortSchema.default(6379),
|
|
3740
|
+
shards: ShardsSchema.default(1),
|
|
3741
|
+
replicasPerShard: ReplicasPerShardSchema.default(1),
|
|
3742
|
+
engine: EngineSchema.default("7.0"),
|
|
3743
|
+
dataTiering: z19.boolean().default(false)
|
|
3744
|
+
})
|
|
3745
|
+
).optional()
|
|
3746
|
+
}).array()
|
|
3747
|
+
}),
|
|
3748
|
+
onStack({ config, stack, stackConfig, bootstrap: bootstrap2, bind }) {
|
|
3749
|
+
for (const [id, props] of Object.entries(stackConfig.caches || {})) {
|
|
3750
|
+
const name = `${config.name}-${stack.name}-${id}`;
|
|
3751
|
+
const subnetGroup = new SubnetGroup(id, {
|
|
3752
|
+
name,
|
|
3753
|
+
subnetIds: [
|
|
3754
|
+
bootstrap2.import(`private-subnet-1`),
|
|
3755
|
+
bootstrap2.import(`private-subnet-2`)
|
|
3756
|
+
]
|
|
3757
|
+
});
|
|
3758
|
+
const securityGroup = new SecurityGroup(id, {
|
|
3759
|
+
name,
|
|
3760
|
+
vpcId: bootstrap2.import(`vpc-id`),
|
|
3761
|
+
description: name
|
|
3762
|
+
});
|
|
3763
|
+
const port = Port.tcp(props.port);
|
|
3764
|
+
securityGroup.addIngressRule(Peer.anyIpv4(), port);
|
|
3765
|
+
securityGroup.addIngressRule(Peer.anyIpv6(), port);
|
|
3766
|
+
const cluster = new Cluster(id, {
|
|
3767
|
+
name,
|
|
3768
|
+
aclName: "open-access",
|
|
3769
|
+
securityGroupIds: [securityGroup.id],
|
|
3770
|
+
subnetGroupName: subnetGroup.name,
|
|
3771
|
+
...props
|
|
3772
|
+
}).dependsOn(subnetGroup, securityGroup);
|
|
3773
|
+
stack.add(subnetGroup, securityGroup, cluster);
|
|
3774
|
+
bind((lambda) => {
|
|
3775
|
+
lambda.addEnvironment(`CACHE_${stack.name}_${id}_HOST`, cluster.address).addEnvironment(`CACHE_${stack.name}_${id}_PORT`, props.port.toString());
|
|
3489
3776
|
});
|
|
3490
3777
|
}
|
|
3491
3778
|
}
|
|
@@ -3496,6 +3783,7 @@ var defaultPlugins = [
|
|
|
3496
3783
|
extendPlugin,
|
|
3497
3784
|
vpcPlugin,
|
|
3498
3785
|
functionPlugin,
|
|
3786
|
+
cachePlugin,
|
|
3499
3787
|
cronPlugin,
|
|
3500
3788
|
queuePlugin,
|
|
3501
3789
|
tablePlugin,
|
|
@@ -3677,7 +3965,7 @@ var toApp = async (config, filters) => {
|
|
|
3677
3965
|
config.stacks.filter((stack) => filters.includes(stack.name))
|
|
3678
3966
|
);
|
|
3679
3967
|
for (const stackConfig of filterdStacks) {
|
|
3680
|
-
const { stack } = toStack({
|
|
3968
|
+
const { stack, bindings: bindings2 } = toStack({
|
|
3681
3969
|
config,
|
|
3682
3970
|
stackConfig,
|
|
3683
3971
|
bootstrap: bootstrap2,
|
|
@@ -3686,7 +3974,7 @@ var toApp = async (config, filters) => {
|
|
|
3686
3974
|
app
|
|
3687
3975
|
});
|
|
3688
3976
|
app.add(stack);
|
|
3689
|
-
stacks.push({ stack, config: stackConfig });
|
|
3977
|
+
stacks.push({ stack, config: stackConfig, bindings: bindings2 });
|
|
3690
3978
|
}
|
|
3691
3979
|
for (const plugin of plugins) {
|
|
3692
3980
|
for (const stack of app.stacks) {
|
|
@@ -3708,23 +3996,31 @@ var toApp = async (config, filters) => {
|
|
|
3708
3996
|
bind2(fn);
|
|
3709
3997
|
}
|
|
3710
3998
|
}
|
|
3711
|
-
|
|
3999
|
+
for (const entry of stacks) {
|
|
4000
|
+
for (const dep of entry.config.depends || []) {
|
|
4001
|
+
const depStack = stacks.find((entry2) => entry2.config.name === dep.name);
|
|
4002
|
+
if (!depStack) {
|
|
4003
|
+
throw new Error(`Stack dependency not found: ${dep.name}`);
|
|
4004
|
+
}
|
|
4005
|
+
const functions2 = entry.stack.find(Function);
|
|
4006
|
+
for (const bind2 of depStack.bindings) {
|
|
4007
|
+
for (const fn of functions2) {
|
|
4008
|
+
bind2(fn);
|
|
4009
|
+
}
|
|
4010
|
+
}
|
|
4011
|
+
}
|
|
4012
|
+
}
|
|
4013
|
+
const deploymentLine = createDeploymentLine(stacks);
|
|
3712
4014
|
if (bootstrap2.size > 0) {
|
|
3713
|
-
|
|
3714
|
-
stack: bootstrap2,
|
|
3715
|
-
children: dependencyTree
|
|
3716
|
-
}];
|
|
4015
|
+
deploymentLine.unshift([bootstrap2]);
|
|
3717
4016
|
}
|
|
3718
4017
|
if (usEastBootstrap.size > 0) {
|
|
3719
|
-
|
|
3720
|
-
stack: usEastBootstrap,
|
|
3721
|
-
children: dependencyTree
|
|
3722
|
-
}];
|
|
4018
|
+
deploymentLine.unshift([usEastBootstrap]);
|
|
3723
4019
|
}
|
|
3724
4020
|
return {
|
|
3725
4021
|
app,
|
|
3726
4022
|
plugins,
|
|
3727
|
-
|
|
4023
|
+
deploymentLine
|
|
3728
4024
|
};
|
|
3729
4025
|
};
|
|
3730
4026
|
|
|
@@ -3748,17 +4044,17 @@ var getCredentials = (profile) => {
|
|
|
3748
4044
|
};
|
|
3749
4045
|
|
|
3750
4046
|
// src/schema/app.ts
|
|
3751
|
-
import { z as
|
|
4047
|
+
import { z as z23 } from "zod";
|
|
3752
4048
|
|
|
3753
4049
|
// src/schema/stack.ts
|
|
3754
|
-
import { z as
|
|
3755
|
-
var StackSchema =
|
|
4050
|
+
import { z as z20 } from "zod";
|
|
4051
|
+
var StackSchema = z20.object({
|
|
3756
4052
|
name: ResourceIdSchema,
|
|
3757
|
-
depends:
|
|
4053
|
+
depends: z20.array(z20.lazy(() => StackSchema)).optional()
|
|
3758
4054
|
});
|
|
3759
4055
|
|
|
3760
4056
|
// src/schema/region.ts
|
|
3761
|
-
import { z as
|
|
4057
|
+
import { z as z21 } from "zod";
|
|
3762
4058
|
var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
|
|
3763
4059
|
var AF = ["af-south-1"];
|
|
3764
4060
|
var AP = ["ap-east-1", "ap-south-2", "ap-southeast-3", "ap-southeast-4", "ap-south-1", "ap-northeast-3", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-northeast-1"];
|
|
@@ -3775,47 +4071,49 @@ var regions = [
|
|
|
3775
4071
|
...ME,
|
|
3776
4072
|
...SA
|
|
3777
4073
|
];
|
|
3778
|
-
var RegionSchema =
|
|
4074
|
+
var RegionSchema = z21.enum(regions);
|
|
3779
4075
|
|
|
3780
4076
|
// src/schema/plugin.ts
|
|
3781
|
-
import { z as
|
|
3782
|
-
var PluginSchema =
|
|
3783
|
-
name:
|
|
3784
|
-
schema:
|
|
4077
|
+
import { z as z22 } from "zod";
|
|
4078
|
+
var PluginSchema = z22.object({
|
|
4079
|
+
name: z22.string(),
|
|
4080
|
+
schema: z22.custom().optional(),
|
|
3785
4081
|
// depends: z.array(z.lazy(() => PluginSchema)).optional(),
|
|
3786
|
-
onApp:
|
|
3787
|
-
onStack:
|
|
3788
|
-
onResource:
|
|
4082
|
+
onApp: z22.function().returns(z22.void()).optional(),
|
|
4083
|
+
onStack: z22.function().returns(z22.any()).optional(),
|
|
4084
|
+
onResource: z22.function().returns(z22.any()).optional()
|
|
3789
4085
|
// bind: z.function().optional(),
|
|
3790
4086
|
});
|
|
3791
4087
|
|
|
3792
4088
|
// src/schema/app.ts
|
|
3793
|
-
var AppSchema =
|
|
4089
|
+
var AppSchema = z23.object({
|
|
3794
4090
|
/** App name */
|
|
3795
4091
|
name: ResourceIdSchema,
|
|
3796
4092
|
/** The AWS region to deploy to. */
|
|
3797
4093
|
region: RegionSchema,
|
|
3798
4094
|
/** The AWS profile to deploy to. */
|
|
3799
|
-
profile:
|
|
4095
|
+
profile: z23.string(),
|
|
3800
4096
|
/** The deployment stage.
|
|
3801
4097
|
* @default 'prod'
|
|
3802
4098
|
*/
|
|
3803
|
-
stage:
|
|
4099
|
+
stage: z23.string().regex(/[a-z]+/).default("prod"),
|
|
3804
4100
|
/** Default properties. */
|
|
3805
|
-
defaults:
|
|
4101
|
+
defaults: z23.object({}).default({}),
|
|
3806
4102
|
/** The application stacks. */
|
|
3807
|
-
stacks:
|
|
4103
|
+
stacks: z23.array(StackSchema).min(1).refine((stacks) => {
|
|
3808
4104
|
const unique = new Set(stacks.map((stack) => stack.name));
|
|
3809
4105
|
return unique.size === stacks.length;
|
|
3810
4106
|
}, "Must be an array of unique stacks"),
|
|
3811
4107
|
/** Custom plugins. */
|
|
3812
|
-
plugins:
|
|
4108
|
+
plugins: z23.array(PluginSchema).optional()
|
|
3813
4109
|
});
|
|
3814
4110
|
|
|
3815
4111
|
// src/util/import.ts
|
|
3816
|
-
import {
|
|
4112
|
+
import { rollup as rollup2 } from "rollup";
|
|
4113
|
+
import { swc as swc2 } from "rollup-plugin-swc3";
|
|
4114
|
+
import replace from "rollup-plugin-replace";
|
|
3817
4115
|
import { dirname, join as join2 } from "path";
|
|
3818
|
-
import {
|
|
4116
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
3819
4117
|
|
|
3820
4118
|
// src/util/path.ts
|
|
3821
4119
|
import { lstat } from "fs/promises";
|
|
@@ -3862,54 +4160,25 @@ var fileExist = async (file) => {
|
|
|
3862
4160
|
};
|
|
3863
4161
|
|
|
3864
4162
|
// src/util/import.ts
|
|
3865
|
-
var resolveFileNameExtension = async (path) => {
|
|
3866
|
-
const options = [
|
|
3867
|
-
"",
|
|
3868
|
-
".ts",
|
|
3869
|
-
".js",
|
|
3870
|
-
"/index.ts",
|
|
3871
|
-
"/index.js"
|
|
3872
|
-
];
|
|
3873
|
-
for (const option of options) {
|
|
3874
|
-
const file = path.replace(/\.js$/, "") + option;
|
|
3875
|
-
let stat;
|
|
3876
|
-
try {
|
|
3877
|
-
stat = await lstat2(file);
|
|
3878
|
-
} catch (error) {
|
|
3879
|
-
continue;
|
|
3880
|
-
}
|
|
3881
|
-
if (stat.isFile()) {
|
|
3882
|
-
return file;
|
|
3883
|
-
}
|
|
3884
|
-
}
|
|
3885
|
-
throw new Error(`Failed to load file: ${path}`);
|
|
3886
|
-
};
|
|
3887
|
-
var resolveDir = (path) => {
|
|
3888
|
-
return dirname(path).replace(directories.root + "/", "");
|
|
3889
|
-
};
|
|
3890
4163
|
var importFile = async (path) => {
|
|
3891
|
-
const
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
await Promise.all(matches?.map(async (match) => {
|
|
3903
|
-
const parts = /('|")(\.\.?[\/a-z0-9\_\-\.]+)('|")/ig.exec(match);
|
|
3904
|
-
const from = parts[2];
|
|
3905
|
-
const file2 = await resolveFileNameExtension(join2(path2, from));
|
|
3906
|
-
const result = await load(file2);
|
|
3907
|
-
code2 = code2.replace(match, result);
|
|
3908
|
-
}));
|
|
3909
|
-
return code2;
|
|
3910
|
-
};
|
|
3911
|
-
const code = await load(path);
|
|
4164
|
+
const bundle = await rollup2({
|
|
4165
|
+
input: path,
|
|
4166
|
+
plugins: [
|
|
4167
|
+
replace({
|
|
4168
|
+
__dirname: (id) => `'${dirname(id)}'`
|
|
4169
|
+
}),
|
|
4170
|
+
swc2({
|
|
4171
|
+
minify: false
|
|
4172
|
+
})
|
|
4173
|
+
]
|
|
4174
|
+
});
|
|
3912
4175
|
const outputFile = join2(directories.cache, "config.js");
|
|
4176
|
+
const result = await bundle.generate({
|
|
4177
|
+
format: "esm",
|
|
4178
|
+
exports: "default"
|
|
4179
|
+
});
|
|
4180
|
+
const output = result.output[0];
|
|
4181
|
+
const code = output.code;
|
|
3913
4182
|
await mkdir(directories.cache, { recursive: true });
|
|
3914
4183
|
await writeFile(outputFile, code);
|
|
3915
4184
|
debug("Save config file:", style.info(outputFile));
|
|
@@ -4211,7 +4480,7 @@ var Renderer = class {
|
|
|
4211
4480
|
flushing = false;
|
|
4212
4481
|
screen = [];
|
|
4213
4482
|
width() {
|
|
4214
|
-
return this.output.columns;
|
|
4483
|
+
return this.output.columns - 1;
|
|
4215
4484
|
}
|
|
4216
4485
|
height() {
|
|
4217
4486
|
return this.output.rows;
|
|
@@ -4904,41 +5173,74 @@ var bootstrap = (program2) => {
|
|
|
4904
5173
|
});
|
|
4905
5174
|
};
|
|
4906
5175
|
|
|
4907
|
-
// src/cli/ui/complex/
|
|
4908
|
-
var
|
|
5176
|
+
// src/cli/ui/complex/deployer.ts
|
|
5177
|
+
var stacksDeployer = (deploymentLine) => {
|
|
5178
|
+
const stackNames = deploymentLine.map((line) => line.map((stack) => stack.name)).flat();
|
|
5179
|
+
const stackNameSize = Math.max(...stackNames.map((name) => name.length));
|
|
4909
5180
|
return (term) => {
|
|
4910
|
-
const
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
const more = i < size;
|
|
4918
|
-
const line = flexLine(term, [
|
|
4919
|
-
...parents.map((parent) => {
|
|
4920
|
-
return style.label(
|
|
4921
|
-
parent ? "\u2502".padEnd(3) : " ".repeat(3)
|
|
4922
|
-
);
|
|
4923
|
-
}),
|
|
4924
|
-
style.label(
|
|
4925
|
-
first && size === 0 ? " " : first ? "\u250C\u2500" : last ? "\u2514\u2500" : "\u251C\u2500"
|
|
4926
|
-
),
|
|
5181
|
+
const ui = {};
|
|
5182
|
+
term.out.gap();
|
|
5183
|
+
for (const i in deploymentLine) {
|
|
5184
|
+
const line = flexLine(
|
|
5185
|
+
term,
|
|
5186
|
+
[" "],
|
|
5187
|
+
[
|
|
4927
5188
|
" ",
|
|
4928
|
-
style.
|
|
4929
|
-
" "
|
|
4930
|
-
]
|
|
5189
|
+
style.placeholder(Number(i) + 1),
|
|
5190
|
+
style.placeholder(" \u2500\u2500")
|
|
5191
|
+
]
|
|
5192
|
+
);
|
|
5193
|
+
term.out.write(line);
|
|
5194
|
+
term.out.write(br());
|
|
5195
|
+
for (const stack of deploymentLine[i]) {
|
|
5196
|
+
const icon = new Signal(" ");
|
|
5197
|
+
const name = new Signal(style.label.dim(stack.name));
|
|
5198
|
+
const status2 = new Signal(style.info.dim("waiting"));
|
|
5199
|
+
let stopSpinner;
|
|
5200
|
+
term.out.write([
|
|
5201
|
+
icon,
|
|
5202
|
+
" ",
|
|
5203
|
+
name,
|
|
5204
|
+
" ".repeat(stackNameSize - stack.name.length),
|
|
5205
|
+
" ",
|
|
5206
|
+
style.placeholder(symbol.pointerSmall),
|
|
4931
5207
|
" ",
|
|
4932
5208
|
status2,
|
|
4933
5209
|
br()
|
|
4934
5210
|
]);
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
|
|
5211
|
+
ui[stack.name] = {
|
|
5212
|
+
start: (value) => {
|
|
5213
|
+
const [spinner, stop] = createSpinner();
|
|
5214
|
+
name.set(style.label(stack.name));
|
|
5215
|
+
icon.set(spinner);
|
|
5216
|
+
status2.set(style.warning(value));
|
|
5217
|
+
stopSpinner = stop;
|
|
5218
|
+
},
|
|
5219
|
+
done(value) {
|
|
5220
|
+
stopSpinner();
|
|
5221
|
+
icon.set(style.success(symbol.success));
|
|
5222
|
+
status2.set(style.success(value));
|
|
5223
|
+
},
|
|
5224
|
+
fail(value) {
|
|
5225
|
+
stopSpinner();
|
|
5226
|
+
icon.set(style.error(symbol.error));
|
|
5227
|
+
status2.set(style.error(value));
|
|
5228
|
+
},
|
|
5229
|
+
warn(value) {
|
|
5230
|
+
stopSpinner();
|
|
5231
|
+
icon.set(style.warning(symbol.warning));
|
|
5232
|
+
status2.set(style.warning(value));
|
|
5233
|
+
}
|
|
5234
|
+
};
|
|
5235
|
+
}
|
|
5236
|
+
}
|
|
5237
|
+
term.out.write(flexLine(term, [" "], [
|
|
5238
|
+
" ",
|
|
5239
|
+
style.warning("\u26A1\uFE0F"),
|
|
5240
|
+
style.placeholder("\u2500\u2500")
|
|
5241
|
+
]));
|
|
4941
5242
|
term.out.gap();
|
|
5243
|
+
return ui;
|
|
4942
5244
|
};
|
|
4943
5245
|
};
|
|
4944
5246
|
|
|
@@ -4946,31 +5248,27 @@ var stackTree = (nodes, statuses) => {
|
|
|
4946
5248
|
var status = (program2) => {
|
|
4947
5249
|
program2.command("status").argument("[stacks...]", "Optionally filter stacks to lookup status").description("View the application status").action(async (filters) => {
|
|
4948
5250
|
await layout(async (config, write) => {
|
|
4949
|
-
const { app,
|
|
5251
|
+
const { app, deploymentLine } = await toApp(config, filters);
|
|
4950
5252
|
await cleanUp();
|
|
4951
5253
|
await write(assetBuilder(app));
|
|
4952
5254
|
await write(templateBuilder(app));
|
|
4953
5255
|
const doneLoading = write(loadingDialog("Loading stack information..."));
|
|
4954
5256
|
const client = new StackClient(app, config.account, config.region, config.credentials);
|
|
4955
5257
|
const statuses = [];
|
|
4956
|
-
const
|
|
4957
|
-
for (const stack of app) {
|
|
4958
|
-
stackStatuses[stack.name] = new Signal(style.info("Loading..."));
|
|
4959
|
-
}
|
|
4960
|
-
write(stackTree(dependencyTree, stackStatuses));
|
|
5258
|
+
const ui = write(stacksDeployer(deploymentLine));
|
|
4961
5259
|
debug("Load metadata for all deployed stacks on AWS");
|
|
4962
5260
|
await Promise.all(app.stacks.map(async (stack, i) => {
|
|
5261
|
+
const item = ui[stack.name];
|
|
5262
|
+
item.start("loading");
|
|
4963
5263
|
const info = await client.get(stack.name, stack.region);
|
|
4964
|
-
const signal = stackStatuses[stack.name];
|
|
4965
|
-
await new Promise((resolve) => setTimeout(resolve, i * 1e3));
|
|
4966
5264
|
if (!info) {
|
|
4967
|
-
|
|
5265
|
+
item.fail("NON EXISTENT");
|
|
4968
5266
|
statuses.push("non-existent");
|
|
4969
5267
|
} else if (info.template !== stack.toString()) {
|
|
4970
|
-
|
|
5268
|
+
item.warn("OUT OF DATE");
|
|
4971
5269
|
statuses.push("out-of-date");
|
|
4972
5270
|
} else {
|
|
4973
|
-
|
|
5271
|
+
item.done("UP TO DATE");
|
|
4974
5272
|
statuses.push("up-to-date");
|
|
4975
5273
|
}
|
|
4976
5274
|
}));
|
|
@@ -5054,7 +5352,7 @@ var deploy = (program2) => {
|
|
|
5054
5352
|
program2.command("deploy").argument("[stacks...]", "Optionally filter stacks to deploy").description("Deploy your app to AWS").action(async (filters) => {
|
|
5055
5353
|
await layout(async (config, write) => {
|
|
5056
5354
|
await write(bootstrapDeployer(config));
|
|
5057
|
-
const { app,
|
|
5355
|
+
const { app, deploymentLine } = await toApp(config, filters);
|
|
5058
5356
|
const stackNames = app.stacks.map((stack) => stack.name);
|
|
5059
5357
|
const formattedFilter = stackNames.map((i) => style.info(i)).join(style.placeholder(", "));
|
|
5060
5358
|
debug("Stacks to deploy", formattedFilter);
|
|
@@ -5068,26 +5366,21 @@ var deploy = (program2) => {
|
|
|
5068
5366
|
await write(assetBuilder(app));
|
|
5069
5367
|
await write(assetPublisher(config, app));
|
|
5070
5368
|
await write(templateBuilder(app));
|
|
5071
|
-
const statuses = {};
|
|
5072
|
-
for (const stack of app) {
|
|
5073
|
-
statuses[stack.name] = new Signal(style.info("waiting"));
|
|
5074
|
-
}
|
|
5075
5369
|
const doneDeploying = write(loadingDialog("Deploying stacks to AWS..."));
|
|
5076
|
-
write(stackTree(dependencyTree, statuses));
|
|
5077
5370
|
const client = new StackClient(app, config.account, config.region, config.credentials);
|
|
5078
|
-
const
|
|
5079
|
-
for (const
|
|
5080
|
-
const results = await Promise.allSettled(
|
|
5081
|
-
const
|
|
5082
|
-
|
|
5371
|
+
const ui = write(stacksDeployer(deploymentLine));
|
|
5372
|
+
for (const line of deploymentLine) {
|
|
5373
|
+
const results = await Promise.allSettled(line.map(async (stack) => {
|
|
5374
|
+
const item = ui[stack.name];
|
|
5375
|
+
item.start("deploying");
|
|
5083
5376
|
try {
|
|
5084
5377
|
await client.deploy(stack);
|
|
5085
5378
|
} catch (error) {
|
|
5086
5379
|
debugError(error);
|
|
5087
|
-
|
|
5380
|
+
item.fail("failed");
|
|
5088
5381
|
throw error;
|
|
5089
5382
|
}
|
|
5090
|
-
|
|
5383
|
+
item.done("deployed");
|
|
5091
5384
|
}));
|
|
5092
5385
|
for (const result of results) {
|
|
5093
5386
|
if (result.status === "rejected") {
|