@awsless/awsless 0.0.180 → 0.0.183
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.js +239 -319
- package/package.json +6 -6
package/dist/bin.js
CHANGED
|
@@ -1230,7 +1230,7 @@ var logApp = (app) => {
|
|
|
1230
1230
|
};
|
|
1231
1231
|
|
|
1232
1232
|
// src/cli/ui/error/error.ts
|
|
1233
|
-
import { log as
|
|
1233
|
+
import { log as log5 } from "@clack/prompts";
|
|
1234
1234
|
|
|
1235
1235
|
// src/cli/ui/error/config-error.ts
|
|
1236
1236
|
import * as p from "@clack/prompts";
|
|
@@ -1316,7 +1316,7 @@ var logConfigError = (error) => {
|
|
|
1316
1316
|
};
|
|
1317
1317
|
|
|
1318
1318
|
// src/cli/ui/error/error.ts
|
|
1319
|
-
import { StackError as
|
|
1319
|
+
import { AppError as AppError2, StackError as StackError3 } from "@awsless/formation";
|
|
1320
1320
|
|
|
1321
1321
|
// src/cli/ui/error/stack-error.ts
|
|
1322
1322
|
import { ResourceError } from "@awsless/formation";
|
|
@@ -1375,33 +1375,56 @@ var logFileError = (error) => {
|
|
|
1375
1375
|
);
|
|
1376
1376
|
};
|
|
1377
1377
|
|
|
1378
|
+
// src/cli/ui/error/app-error.ts
|
|
1379
|
+
import { StackError as StackError2 } from "@awsless/formation";
|
|
1380
|
+
import { log as log4 } from "@clack/prompts";
|
|
1381
|
+
var logAppError = (error) => {
|
|
1382
|
+
log4.message(
|
|
1383
|
+
wrap([color.error(error.message), color.dim(`App: ${error.app}`)].join("\n"), {
|
|
1384
|
+
hard: true
|
|
1385
|
+
}),
|
|
1386
|
+
{ symbol: color.error(icon.error) }
|
|
1387
|
+
);
|
|
1388
|
+
for (const issue of error.issues) {
|
|
1389
|
+
if (issue instanceof StackError2) {
|
|
1390
|
+
logStackError(issue);
|
|
1391
|
+
} else if (issue instanceof Error) {
|
|
1392
|
+
log4.message(wrap(color.error(issue.message), { hard: true }), {
|
|
1393
|
+
symbol: color.error(icon.error)
|
|
1394
|
+
});
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
};
|
|
1398
|
+
|
|
1378
1399
|
// src/cli/ui/error/error.ts
|
|
1379
1400
|
var logError = (error) => {
|
|
1380
1401
|
if (error instanceof ConfigError) {
|
|
1381
1402
|
logConfigError(error);
|
|
1382
1403
|
} else if (error instanceof Cancelled) {
|
|
1383
|
-
|
|
1404
|
+
log5.message(color.error("Cancelled."), {
|
|
1384
1405
|
symbol: color.error(icon.error)
|
|
1385
1406
|
});
|
|
1386
|
-
} else if (error instanceof
|
|
1407
|
+
} else if (error instanceof AppError2) {
|
|
1408
|
+
logAppError(error);
|
|
1409
|
+
} else if (error instanceof StackError3) {
|
|
1387
1410
|
logStackError(error);
|
|
1388
1411
|
} else if (error instanceof FileError) {
|
|
1389
1412
|
logFileError(error);
|
|
1390
1413
|
} else if (error instanceof Error) {
|
|
1391
1414
|
const message = `${error.name}: ${error.message}`;
|
|
1392
1415
|
const stack = error.stack ? color.dim(error.stack.replace(message, "")) : "";
|
|
1393
|
-
|
|
1416
|
+
log5.message(
|
|
1394
1417
|
wrap([color.error(message), stack], {
|
|
1395
1418
|
hard: true
|
|
1396
1419
|
}),
|
|
1397
1420
|
{ symbol: color.error(icon.error) }
|
|
1398
1421
|
);
|
|
1399
1422
|
} else if (typeof error === "string") {
|
|
1400
|
-
|
|
1423
|
+
log5.message(wrap(color.error(error)), {
|
|
1401
1424
|
symbol: color.error(icon.error)
|
|
1402
1425
|
});
|
|
1403
1426
|
} else {
|
|
1404
|
-
|
|
1427
|
+
log5.message(wrap(color.error("Unknown error!")), {
|
|
1405
1428
|
symbol: color.error(icon.error)
|
|
1406
1429
|
});
|
|
1407
1430
|
}
|
|
@@ -1438,7 +1461,7 @@ import {
|
|
|
1438
1461
|
ResourceNotFoundException,
|
|
1439
1462
|
ScalarAttributeType
|
|
1440
1463
|
} from "@aws-sdk/client-dynamodb";
|
|
1441
|
-
import { confirm, log as
|
|
1464
|
+
import { confirm, log as log6 } from "@clack/prompts";
|
|
1442
1465
|
var hasStateTable = async (client) => {
|
|
1443
1466
|
try {
|
|
1444
1467
|
const result = await client.send(
|
|
@@ -1478,7 +1501,7 @@ var bootstrapAwsless = async (opts) => {
|
|
|
1478
1501
|
const client = new DynamoDB(opts);
|
|
1479
1502
|
const table2 = await hasStateTable(client);
|
|
1480
1503
|
if (!table2) {
|
|
1481
|
-
|
|
1504
|
+
log6.warn(`Your Awsless hasn't been bootstrapped yet.`);
|
|
1482
1505
|
if (!process.env.SKIP_PROMPT) {
|
|
1483
1506
|
const confirmed = await confirm({
|
|
1484
1507
|
message: "Would you like to bootstrap now?"
|
|
@@ -1492,7 +1515,7 @@ var bootstrapAwsless = async (opts) => {
|
|
|
1492
1515
|
update("Done deploying the bootstrap stack");
|
|
1493
1516
|
});
|
|
1494
1517
|
} else {
|
|
1495
|
-
|
|
1518
|
+
log6.step("Awsless has already been bootstrapped.");
|
|
1496
1519
|
}
|
|
1497
1520
|
};
|
|
1498
1521
|
|
|
@@ -1689,32 +1712,31 @@ var cacheFeature = defineFeature({
|
|
|
1689
1712
|
},
|
|
1690
1713
|
onStack(ctx) {
|
|
1691
1714
|
for (const [id, props] of Object.entries(ctx.stackConfig.caches ?? {})) {
|
|
1692
|
-
const group = new Node(this.name, id);
|
|
1693
|
-
ctx.stack.add(group);
|
|
1715
|
+
const group = new Node(ctx.stack, this.name, id);
|
|
1694
1716
|
const name = formatLocalResourceName(ctx.appConfig.name, ctx.stack.name, this.name, id, "-");
|
|
1695
|
-
const subnetGroup = new aws.memorydb.SubnetGroup("subnets", {
|
|
1717
|
+
const subnetGroup = new aws.memorydb.SubnetGroup(group, "subnets", {
|
|
1696
1718
|
name,
|
|
1697
1719
|
subnetIds: [
|
|
1698
|
-
|
|
1699
|
-
ctx.
|
|
1720
|
+
//
|
|
1721
|
+
ctx.shared.get("vpc-private-subnet-id-1"),
|
|
1722
|
+
ctx.shared.get("vpc-private-subnet-id-2")
|
|
1700
1723
|
]
|
|
1701
1724
|
});
|
|
1702
|
-
const securityGroup = new aws.ec2.SecurityGroup("security", {
|
|
1725
|
+
const securityGroup = new aws.ec2.SecurityGroup(group, "security", {
|
|
1703
1726
|
name,
|
|
1704
|
-
vpcId: ctx.
|
|
1727
|
+
vpcId: ctx.shared.get(`vpc-id`),
|
|
1705
1728
|
description: name
|
|
1706
1729
|
});
|
|
1707
1730
|
const port = aws.ec2.Port.tcp(props.port);
|
|
1708
1731
|
securityGroup.addIngressRule({ port, peer: aws.ec2.Peer.anyIpv4() });
|
|
1709
1732
|
securityGroup.addIngressRule({ port, peer: aws.ec2.Peer.anyIpv6() });
|
|
1710
|
-
const cluster = new aws.memorydb.Cluster("cluster", {
|
|
1733
|
+
const cluster = new aws.memorydb.Cluster(group, "cluster", {
|
|
1711
1734
|
name,
|
|
1712
1735
|
aclName: "open-access",
|
|
1713
1736
|
securityGroupIds: [securityGroup.id],
|
|
1714
1737
|
subnetGroupName: subnetGroup.name,
|
|
1715
1738
|
...props
|
|
1716
1739
|
});
|
|
1717
|
-
group.add(subnetGroup, securityGroup, cluster);
|
|
1718
1740
|
ctx.onFunction(({ lambda }) => {
|
|
1719
1741
|
lambda.addEnvironment(
|
|
1720
1742
|
`CACHE_${constantCase2(ctx.stack.name)}_${constantCase2(id)}_HOST`,
|
|
@@ -1992,18 +2014,16 @@ var createLambdaFunction = (group, ctx, ns, id, local) => {
|
|
|
1992
2014
|
};
|
|
1993
2015
|
});
|
|
1994
2016
|
});
|
|
1995
|
-
const code = new aws2.s3.BucketObject("code", {
|
|
1996
|
-
bucket:
|
|
2017
|
+
const code = new aws2.s3.BucketObject(group, "code", {
|
|
2018
|
+
bucket: ctx.shared.get("function-bucket-name"),
|
|
1997
2019
|
key: `/lambda/${name}.zip`,
|
|
1998
2020
|
body: Asset.fromFile(getBuildPath("function", name, "bundle.zip"))
|
|
1999
2021
|
});
|
|
2000
|
-
|
|
2001
|
-
const role = new aws2.iam.Role("role", {
|
|
2022
|
+
const role = new aws2.iam.Role(group, "role", {
|
|
2002
2023
|
name,
|
|
2003
2024
|
assumedBy: "lambda.amazonaws.com"
|
|
2004
2025
|
});
|
|
2005
|
-
|
|
2006
|
-
const policy = new aws2.iam.RolePolicy("policy", {
|
|
2026
|
+
const policy = new aws2.iam.RolePolicy(group, "policy", {
|
|
2007
2027
|
role: role.name,
|
|
2008
2028
|
name: "lambda-policy",
|
|
2009
2029
|
version: "2012-10-17",
|
|
@@ -2015,8 +2035,7 @@ var createLambdaFunction = (group, ctx, ns, id, local) => {
|
|
|
2015
2035
|
}
|
|
2016
2036
|
]
|
|
2017
2037
|
});
|
|
2018
|
-
|
|
2019
|
-
const lambda = new aws2.lambda.Function(`function`, {
|
|
2038
|
+
const lambda = new aws2.lambda.Function(group, `function`, {
|
|
2020
2039
|
...props,
|
|
2021
2040
|
name,
|
|
2022
2041
|
code,
|
|
@@ -2025,24 +2044,21 @@ var createLambdaFunction = (group, ctx, ns, id, local) => {
|
|
|
2025
2044
|
vpc: void 0,
|
|
2026
2045
|
log: props.log
|
|
2027
2046
|
});
|
|
2028
|
-
group.add(lambda);
|
|
2029
2047
|
ctx.registerFunction(lambda, policy);
|
|
2030
2048
|
lambda.addEnvironment("APP", ctx.appConfig.name);
|
|
2031
2049
|
if ("stackConfig" in ctx) {
|
|
2032
2050
|
lambda.addEnvironment("STACK", ctx.stackConfig.name);
|
|
2033
2051
|
}
|
|
2034
|
-
|
|
2052
|
+
new aws2.lambda.EventInvokeConfig(group, "async", {
|
|
2035
2053
|
functionArn: lambda.arn,
|
|
2036
2054
|
retryAttempts: props.retryAttempts
|
|
2037
2055
|
// onFailure: getGlobalOnFailure(ctx),
|
|
2038
2056
|
});
|
|
2039
|
-
group.add(invoke);
|
|
2040
2057
|
if (props.log.retention.value > 0n) {
|
|
2041
|
-
const logGroup = new aws2.cloudWatch.LogGroup("log", {
|
|
2058
|
+
const logGroup = new aws2.cloudWatch.LogGroup(group, "log", {
|
|
2042
2059
|
name: lambda.name.apply((name2) => `/aws/lambda/${name2}`),
|
|
2043
2060
|
retention: props.log.retention
|
|
2044
2061
|
});
|
|
2045
|
-
group.add(logGroup);
|
|
2046
2062
|
policy.addStatement(
|
|
2047
2063
|
{
|
|
2048
2064
|
actions: ["logs:CreateLogStream"],
|
|
@@ -2061,7 +2077,7 @@ var createLambdaFunction = (group, ctx, ns, id, local) => {
|
|
|
2061
2077
|
policy.addStatement(...local.permissions);
|
|
2062
2078
|
}
|
|
2063
2079
|
if (props.warm) {
|
|
2064
|
-
const rule = new aws2.events.Rule("warm", {
|
|
2080
|
+
const rule = new aws2.events.Rule(group, "warm", {
|
|
2065
2081
|
name: `${name}--warm`,
|
|
2066
2082
|
schedule: "rate(5 minutes)",
|
|
2067
2083
|
enabled: true,
|
|
@@ -2076,21 +2092,19 @@ var createLambdaFunction = (group, ctx, ns, id, local) => {
|
|
|
2076
2092
|
}
|
|
2077
2093
|
]
|
|
2078
2094
|
});
|
|
2079
|
-
|
|
2080
|
-
const permission = new aws2.lambda.Permission(`warm`, {
|
|
2095
|
+
new aws2.lambda.Permission(group, `warm`, {
|
|
2081
2096
|
action: "lambda:InvokeFunction",
|
|
2082
2097
|
principal: "events.amazonaws.com",
|
|
2083
2098
|
functionArn: lambda.arn,
|
|
2084
2099
|
sourceArn: rule.arn
|
|
2085
2100
|
});
|
|
2086
|
-
group.add(permission);
|
|
2087
2101
|
}
|
|
2088
2102
|
if (props.vpc) {
|
|
2089
2103
|
lambda.setVpc({
|
|
2090
|
-
securityGroupIds: [ctx.
|
|
2104
|
+
securityGroupIds: [ctx.shared.get(`vpc-security-group-id`)],
|
|
2091
2105
|
subnetIds: [
|
|
2092
|
-
ctx.
|
|
2093
|
-
ctx.
|
|
2106
|
+
ctx.shared.get(`vpc-public-subnet-1`),
|
|
2107
|
+
ctx.shared.get(`vpc-public-subnet-2`)
|
|
2094
2108
|
]
|
|
2095
2109
|
});
|
|
2096
2110
|
policy.addStatement({
|
|
@@ -2116,10 +2130,9 @@ var cronFeature = defineFeature({
|
|
|
2116
2130
|
name: "cron",
|
|
2117
2131
|
onStack(ctx) {
|
|
2118
2132
|
for (const [id, props] of Object.entries(ctx.stackConfig.crons ?? {})) {
|
|
2119
|
-
const group = new Node3("cron", id);
|
|
2120
|
-
ctx.stack.add(group);
|
|
2133
|
+
const group = new Node3(ctx.stack, "cron", id);
|
|
2121
2134
|
const { lambda } = createLambdaFunction(group, ctx, this.name, id, props.consumer);
|
|
2122
|
-
const rule = new aws3.events.Rule("rule", {
|
|
2135
|
+
const rule = new aws3.events.Rule(group, "rule", {
|
|
2123
2136
|
name: formatLocalResourceName(ctx.app.name, ctx.stack.name, this.name, id),
|
|
2124
2137
|
schedule: props.schedule,
|
|
2125
2138
|
enabled: props.enabled,
|
|
@@ -2131,13 +2144,12 @@ var cronFeature = defineFeature({
|
|
|
2131
2144
|
}
|
|
2132
2145
|
]
|
|
2133
2146
|
});
|
|
2134
|
-
|
|
2147
|
+
new aws3.lambda.Permission(group, "permission", {
|
|
2135
2148
|
action: "lambda:InvokeFunction",
|
|
2136
2149
|
principal: "events.amazonaws.com",
|
|
2137
2150
|
functionArn: lambda.arn,
|
|
2138
2151
|
sourceArn: rule.arn
|
|
2139
2152
|
});
|
|
2140
|
-
group.add(rule, permission);
|
|
2141
2153
|
}
|
|
2142
2154
|
}
|
|
2143
2155
|
});
|
|
@@ -2152,104 +2164,92 @@ var domainFeature = defineFeature({
|
|
|
2152
2164
|
if (domains.length === 0) {
|
|
2153
2165
|
return;
|
|
2154
2166
|
}
|
|
2155
|
-
const group = new Node4("domain", "mail");
|
|
2156
|
-
|
|
2157
|
-
const configurationSet = new aws4.ses.ConfigurationSet("config", {
|
|
2167
|
+
const group = new Node4(ctx.base, "domain", "mail");
|
|
2168
|
+
const configurationSet = new aws4.ses.ConfigurationSet(group, "config", {
|
|
2158
2169
|
name: ctx.app.name,
|
|
2159
2170
|
engagementMetrics: true,
|
|
2160
2171
|
reputationMetrics: true
|
|
2161
2172
|
});
|
|
2162
|
-
ctx.
|
|
2163
|
-
group.add(configurationSet);
|
|
2173
|
+
ctx.shared.set(`mail-configuration-set`, configurationSet.name);
|
|
2164
2174
|
for (const [id, props] of domains) {
|
|
2165
|
-
const group2 = new Node4("domain", id);
|
|
2166
|
-
|
|
2167
|
-
const hostedZone = new aws4.route53.HostedZone("zone", {
|
|
2175
|
+
const group2 = new Node4(ctx.base, "domain", id);
|
|
2176
|
+
const hostedZone = new aws4.route53.HostedZone(group2, "zone", {
|
|
2168
2177
|
name: props.domain
|
|
2169
2178
|
});
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
const certificate = new aws4.acm.Certificate("local", {
|
|
2179
|
+
ctx.shared.set(`hosted-zone-${id}-id`, hostedZone.id);
|
|
2180
|
+
const certificate = new aws4.acm.Certificate(group2, "local", {
|
|
2173
2181
|
domainName: props.domain,
|
|
2174
2182
|
alternativeNames: [`*.${props.domain}`]
|
|
2175
2183
|
});
|
|
2176
|
-
group2.add(certificate);
|
|
2177
2184
|
hostedZone.addRecord("local-cert-1", certificate.validationRecord(0));
|
|
2178
2185
|
hostedZone.addRecord("local-cert-2", certificate.validationRecord(1));
|
|
2179
|
-
const validation = new aws4.acm.CertificateValidation("local", {
|
|
2186
|
+
const validation = new aws4.acm.CertificateValidation(group2, "local", {
|
|
2180
2187
|
certificateArn: certificate.arn
|
|
2181
2188
|
});
|
|
2182
|
-
|
|
2183
|
-
ctx.base.export(`local-certificate-${id}-arn`, validation.arn);
|
|
2189
|
+
ctx.shared.set(`local-certificate-${id}-arn`, validation.arn);
|
|
2184
2190
|
if (ctx.appConfig.region !== "us-east-1") {
|
|
2185
|
-
const globalCertificate = new aws4.acm.Certificate("global", {
|
|
2191
|
+
const globalCertificate = new aws4.acm.Certificate(group2, "global", {
|
|
2186
2192
|
domainName: props.domain,
|
|
2187
2193
|
alternativeNames: [`*.${props.domain}`],
|
|
2188
2194
|
region: "us-east-1"
|
|
2189
2195
|
});
|
|
2190
|
-
group2.add(globalCertificate);
|
|
2191
2196
|
hostedZone.addRecord("global-cert-1", globalCertificate.validationRecord(0));
|
|
2192
2197
|
hostedZone.addRecord("global-cert-2", globalCertificate.validationRecord(1));
|
|
2193
|
-
const globalValidation = new aws4.acm.CertificateValidation("global", {
|
|
2198
|
+
const globalValidation = new aws4.acm.CertificateValidation(group2, "global", {
|
|
2194
2199
|
certificateArn: globalCertificate.arn,
|
|
2195
2200
|
region: "us-east-1"
|
|
2196
2201
|
});
|
|
2197
|
-
|
|
2198
|
-
ctx.base.export(`global-certificate-${id}-arn`, globalValidation.arn);
|
|
2202
|
+
ctx.shared.set(`global-certificate-${id}-arn`, globalValidation.arn);
|
|
2199
2203
|
} else {
|
|
2200
|
-
ctx.
|
|
2204
|
+
ctx.shared.set(`global-certificate-${id}-arn`, validation.arn);
|
|
2201
2205
|
}
|
|
2202
|
-
const emailIdentity = new aws4.ses.EmailIdentity("mail", {
|
|
2206
|
+
const emailIdentity = new aws4.ses.EmailIdentity(group2, "mail", {
|
|
2203
2207
|
emailIdentity: props.domain,
|
|
2204
2208
|
mailFromDomain: `mail.${props.domain}`,
|
|
2205
2209
|
configurationSetName: configurationSet.name,
|
|
2206
2210
|
feedback: true,
|
|
2207
2211
|
rejectOnMxFailure: true
|
|
2208
2212
|
});
|
|
2209
|
-
group2.add(emailIdentity);
|
|
2210
2213
|
let i = 0;
|
|
2211
2214
|
for (const record of emailIdentity.dkimRecords) {
|
|
2212
|
-
|
|
2215
|
+
new aws4.route53.RecordSet(group2, `dkim-${++i}`, {
|
|
2213
2216
|
hostedZoneId: hostedZone.id,
|
|
2214
2217
|
...record
|
|
2215
2218
|
});
|
|
2216
|
-
group2.add(recordSet);
|
|
2217
2219
|
}
|
|
2218
|
-
|
|
2220
|
+
new aws4.route53.RecordSet(group2, `MX`, {
|
|
2219
2221
|
hostedZoneId: hostedZone.id,
|
|
2220
2222
|
name: `mail.${props.domain}`,
|
|
2221
2223
|
type: "MX",
|
|
2222
2224
|
ttl: minutes3(5),
|
|
2223
2225
|
records: [`10 feedback-smtp.${ctx.appConfig.region}.amazonses.com`]
|
|
2224
2226
|
});
|
|
2225
|
-
|
|
2227
|
+
new aws4.route53.RecordSet(group2, `SPF`, {
|
|
2226
2228
|
hostedZoneId: hostedZone.id,
|
|
2227
2229
|
name: `mail.${props.domain}`,
|
|
2228
2230
|
type: "TXT",
|
|
2229
2231
|
ttl: minutes3(5),
|
|
2230
2232
|
records: ['"v=spf1 include:amazonses.com -all"']
|
|
2231
2233
|
});
|
|
2232
|
-
|
|
2234
|
+
new aws4.route53.RecordSet(group2, `DMARC`, {
|
|
2233
2235
|
hostedZoneId: hostedZone.id,
|
|
2234
2236
|
name: `_dmarc.${props.domain}`,
|
|
2235
2237
|
type: "TXT",
|
|
2236
2238
|
ttl: minutes3(5),
|
|
2237
2239
|
records: ['"v=DMARC1; p=none;"']
|
|
2238
2240
|
});
|
|
2239
|
-
group2.add(record1, record2, record3);
|
|
2240
2241
|
const mailIdentityArn = emailIdentity.output(() => {
|
|
2241
2242
|
return `arn:aws:ses:${ctx.appConfig.region}:${ctx.accountId}:identity/${props.domain}`;
|
|
2242
2243
|
});
|
|
2243
|
-
ctx.
|
|
2244
|
-
ctx.
|
|
2244
|
+
ctx.shared.set(`mail-${id}-arn`, mailIdentityArn);
|
|
2245
|
+
ctx.shared.set(`mail-${props.domain}-arn`, mailIdentityArn);
|
|
2245
2246
|
for (const record of props.dns ?? []) {
|
|
2246
2247
|
const name = record.name ?? props.domain;
|
|
2247
|
-
|
|
2248
|
+
new aws4.route53.RecordSet(group2, `${name}-${record.type}`, {
|
|
2248
2249
|
hostedZoneId: hostedZone.id,
|
|
2249
2250
|
name,
|
|
2250
2251
|
...record
|
|
2251
2252
|
});
|
|
2252
|
-
group2.add(recordSet);
|
|
2253
2253
|
}
|
|
2254
2254
|
}
|
|
2255
2255
|
ctx.onFunction(
|
|
@@ -2456,20 +2456,18 @@ var functionFeature = defineFeature({
|
|
|
2456
2456
|
await ctx.write("function.d.ts", types2, true);
|
|
2457
2457
|
},
|
|
2458
2458
|
onApp(ctx) {
|
|
2459
|
-
const group = new Node5("function", "asset");
|
|
2460
|
-
|
|
2461
|
-
const bucket = new aws5.s3.Bucket("bucket", {
|
|
2459
|
+
const group = new Node5(ctx.base, "function", "asset");
|
|
2460
|
+
const bucket = new aws5.s3.Bucket(group, "bucket", {
|
|
2462
2461
|
name: formatGlobalResourceName(ctx.appConfig.name, "function", "assets"),
|
|
2463
2462
|
versioning: true,
|
|
2464
2463
|
forceDelete: true
|
|
2465
2464
|
});
|
|
2466
|
-
|
|
2465
|
+
ctx.shared.set("function-bucket-name", bucket.name);
|
|
2467
2466
|
},
|
|
2468
2467
|
onStack(ctx) {
|
|
2469
2468
|
for (const [id, props] of Object.entries(ctx.stackConfig.functions || {})) {
|
|
2470
|
-
const group = new Node5("function", id);
|
|
2469
|
+
const group = new Node5(ctx.stack, "function", id);
|
|
2471
2470
|
createLambdaFunction(group, ctx, "function", id, props);
|
|
2472
|
-
ctx.stack.add(group);
|
|
2473
2471
|
}
|
|
2474
2472
|
}
|
|
2475
2473
|
});
|
|
@@ -2702,9 +2700,8 @@ var graphqlFeature = defineFeature({
|
|
|
2702
2700
|
},
|
|
2703
2701
|
onApp(ctx) {
|
|
2704
2702
|
for (const [id, props] of Object.entries(ctx.appConfig.defaults.graphql ?? {})) {
|
|
2705
|
-
const group = new Node6("graphql", id);
|
|
2706
|
-
|
|
2707
|
-
const role = new aws6.iam.Role("role", {
|
|
2703
|
+
const group = new Node6(ctx.base, "graphql", id);
|
|
2704
|
+
const role = new aws6.iam.Role(group, "role", {
|
|
2708
2705
|
assumedBy: "appsync.amazonaws.com",
|
|
2709
2706
|
policies: [
|
|
2710
2707
|
{
|
|
@@ -2722,8 +2719,7 @@ var graphqlFeature = defineFeature({
|
|
|
2722
2719
|
}
|
|
2723
2720
|
]
|
|
2724
2721
|
});
|
|
2725
|
-
|
|
2726
|
-
const api = new aws6.appsync.GraphQLApi("api", {
|
|
2722
|
+
const api = new aws6.appsync.GraphQLApi(group, "api", {
|
|
2727
2723
|
name: formatGlobalResourceName(ctx.app.name, "graphql", id),
|
|
2728
2724
|
type: "merged",
|
|
2729
2725
|
role: role.arn,
|
|
@@ -2731,14 +2727,13 @@ var graphqlFeature = defineFeature({
|
|
|
2731
2727
|
default: props.auth ? {
|
|
2732
2728
|
type: "cognito",
|
|
2733
2729
|
region: ctx.appConfig.region,
|
|
2734
|
-
userPoolId: ctx.
|
|
2730
|
+
userPoolId: ctx.shared.get(`auth-${props.auth}-user-pool-id`)
|
|
2735
2731
|
} : {
|
|
2736
2732
|
type: "iam"
|
|
2737
2733
|
}
|
|
2738
2734
|
}
|
|
2739
2735
|
});
|
|
2740
|
-
|
|
2741
|
-
ctx.base.export(`graphql-${id}-id`, api.id);
|
|
2736
|
+
ctx.shared.set(`graphql-${id}-id`, api.id);
|
|
2742
2737
|
if (props.resolver) {
|
|
2743
2738
|
ctx.registerBuild("graphql-resolver", id, async (build3) => {
|
|
2744
2739
|
const resolver = props.resolver;
|
|
@@ -2757,20 +2752,17 @@ var graphqlFeature = defineFeature({
|
|
|
2757
2752
|
}
|
|
2758
2753
|
if (props.domain) {
|
|
2759
2754
|
const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
|
|
2760
|
-
const domainGroup = new Node6("domain", domainName);
|
|
2761
|
-
|
|
2762
|
-
const domain = new aws6.appsync.DomainName("domain", {
|
|
2755
|
+
const domainGroup = new Node6(group, "domain", domainName);
|
|
2756
|
+
const domain = new aws6.appsync.DomainName(domainGroup, "domain", {
|
|
2763
2757
|
domainName,
|
|
2764
|
-
certificateArn: ctx.
|
|
2758
|
+
certificateArn: ctx.shared.get(`global-certificate-${props.domain}-arn`)
|
|
2765
2759
|
});
|
|
2766
|
-
|
|
2767
|
-
const association = new aws6.appsync.DomainNameApiAssociation("association", {
|
|
2760
|
+
new aws6.appsync.DomainNameApiAssociation(domainGroup, "association", {
|
|
2768
2761
|
apiId: api.id,
|
|
2769
2762
|
domainName: domain.domainName
|
|
2770
2763
|
});
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
hostedZoneId: ctx.base.import(`hosted-zone-${props.domain}-id`),
|
|
2764
|
+
new aws6.route53.RecordSet(domainGroup, "record", {
|
|
2765
|
+
hostedZoneId: ctx.shared.get(`hosted-zone-${props.domain}-id`),
|
|
2774
2766
|
type: "A",
|
|
2775
2767
|
name: domainName,
|
|
2776
2768
|
alias: {
|
|
@@ -2779,7 +2771,6 @@ var graphqlFeature = defineFeature({
|
|
|
2779
2771
|
evaluateTargetHealth: false
|
|
2780
2772
|
}
|
|
2781
2773
|
});
|
|
2782
|
-
domainGroup.add(record);
|
|
2783
2774
|
}
|
|
2784
2775
|
}
|
|
2785
2776
|
},
|
|
@@ -2792,9 +2783,8 @@ var graphqlFeature = defineFeature({
|
|
|
2792
2783
|
`GraphQL definition is not defined on app level for "${id}"`
|
|
2793
2784
|
);
|
|
2794
2785
|
}
|
|
2795
|
-
const group = new Node6("graphql", id);
|
|
2796
|
-
|
|
2797
|
-
const api = new aws6.appsync.GraphQLApi("api", {
|
|
2786
|
+
const group = new Node6(ctx.stack, "graphql", id);
|
|
2787
|
+
const api = new aws6.appsync.GraphQLApi(group, "api", {
|
|
2798
2788
|
name: formatLocalResourceName(ctx.app.name, ctx.stack.name, "graphql", id),
|
|
2799
2789
|
// visibility: false,
|
|
2800
2790
|
auth: {
|
|
@@ -2803,29 +2793,25 @@ var graphqlFeature = defineFeature({
|
|
|
2803
2793
|
}
|
|
2804
2794
|
}
|
|
2805
2795
|
});
|
|
2806
|
-
|
|
2807
|
-
const schema = new aws6.appsync.GraphQLSchema("schema", {
|
|
2796
|
+
const schema = new aws6.appsync.GraphQLSchema(group, "schema", {
|
|
2808
2797
|
apiId: api.id,
|
|
2809
2798
|
definition: Asset2.fromFile(props.schema)
|
|
2810
2799
|
});
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
mergedApiId: ctx.app.import("base", `graphql-${id}-id`),
|
|
2800
|
+
const association = new aws6.appsync.SourceApiAssociation(group, "association", {
|
|
2801
|
+
mergedApiId: ctx.shared.get(`graphql-${id}-id`),
|
|
2814
2802
|
sourceApiId: api.id
|
|
2815
2803
|
});
|
|
2816
2804
|
association.dependsOn(schema);
|
|
2817
|
-
group.add(association);
|
|
2818
2805
|
for (const [typeName, fields] of Object.entries(props.resolvers ?? {})) {
|
|
2819
2806
|
for (const [fieldName, props2] of Object.entries(fields ?? {})) {
|
|
2820
2807
|
const name = `${typeName}__${fieldName}`;
|
|
2821
|
-
const resolverGroup = new Node6("resolver", name);
|
|
2822
|
-
group.add(resolverGroup);
|
|
2808
|
+
const resolverGroup = new Node6(group, "resolver", name);
|
|
2823
2809
|
const entryId = paramCase5(`${id}-${typeName}-${fieldName}`);
|
|
2824
2810
|
const { lambda } = createLambdaFunction(resolverGroup, ctx, `graphql`, entryId, {
|
|
2825
2811
|
...props2.consumer,
|
|
2826
2812
|
description: `${id} ${typeName}.${fieldName}`
|
|
2827
2813
|
});
|
|
2828
|
-
const role = new aws6.iam.Role("source-role", {
|
|
2814
|
+
const role = new aws6.iam.Role(resolverGroup, "source-role", {
|
|
2829
2815
|
assumedBy: "appsync.amazonaws.com",
|
|
2830
2816
|
policies: [
|
|
2831
2817
|
{
|
|
@@ -2839,36 +2825,32 @@ var graphqlFeature = defineFeature({
|
|
|
2839
2825
|
}
|
|
2840
2826
|
]
|
|
2841
2827
|
});
|
|
2842
|
-
|
|
2843
|
-
const source = new aws6.appsync.DataSource("source", {
|
|
2828
|
+
const source = new aws6.appsync.DataSource(resolverGroup, "source", {
|
|
2844
2829
|
apiId: api.id,
|
|
2845
2830
|
type: "lambda",
|
|
2846
2831
|
name,
|
|
2847
2832
|
role: role.arn,
|
|
2848
2833
|
functionArn: lambda.arn
|
|
2849
2834
|
});
|
|
2850
|
-
resolverGroup.add(source);
|
|
2851
2835
|
let code = Asset2.fromString(defaultResolver);
|
|
2852
2836
|
if ("resolver" in props2 && props2.resolver) {
|
|
2853
2837
|
code = Asset2.fromFile(props2.resolver);
|
|
2854
2838
|
} else if (defaultProps.resolver) {
|
|
2855
2839
|
code = Asset2.fromFile(getBuildPath("graphql-resolver", id, "resolver.js"));
|
|
2856
2840
|
}
|
|
2857
|
-
const config2 = new aws6.appsync.FunctionConfiguration("config", {
|
|
2841
|
+
const config2 = new aws6.appsync.FunctionConfiguration(resolverGroup, "config", {
|
|
2858
2842
|
apiId: api.id,
|
|
2859
2843
|
name,
|
|
2860
2844
|
code,
|
|
2861
2845
|
dataSourceName: source.name
|
|
2862
2846
|
});
|
|
2863
|
-
|
|
2864
|
-
const resolver = new aws6.appsync.Resolver("resolver", {
|
|
2847
|
+
new aws6.appsync.Resolver(resolverGroup, "resolver", {
|
|
2865
2848
|
apiId: api.id,
|
|
2866
2849
|
typeName,
|
|
2867
2850
|
fieldName,
|
|
2868
2851
|
functions: [config2.id],
|
|
2869
2852
|
code
|
|
2870
2853
|
});
|
|
2871
|
-
resolverGroup.add(resolver);
|
|
2872
2854
|
}
|
|
2873
2855
|
}
|
|
2874
2856
|
}
|
|
@@ -2877,7 +2859,7 @@ var graphqlFeature = defineFeature({
|
|
|
2877
2859
|
|
|
2878
2860
|
// src/feature/on-failure/util.ts
|
|
2879
2861
|
var getGlobalOnFailure = (ctx) => {
|
|
2880
|
-
return hasOnFailure(ctx.stackConfigs) ? ctx.
|
|
2862
|
+
return hasOnFailure(ctx.stackConfigs) ? ctx.shared.get("on-failure-queue-arn") : void 0;
|
|
2881
2863
|
};
|
|
2882
2864
|
var hasOnFailure = (stacks) => {
|
|
2883
2865
|
const onFailure = stacks.find((stack) => {
|
|
@@ -2898,27 +2880,24 @@ var onFailureFeature = defineFeature({
|
|
|
2898
2880
|
if (count > 1) {
|
|
2899
2881
|
throw new TypeError("Only 1 onFailure configuration is allowed in your app.");
|
|
2900
2882
|
}
|
|
2901
|
-
const queue2 = new aws7.sqs.Queue("on-failure", {
|
|
2883
|
+
const queue2 = new aws7.sqs.Queue(ctx.base, "on-failure", {
|
|
2902
2884
|
name: formatGlobalResourceName(ctx.appConfig.name, "on-failure", "failure")
|
|
2903
2885
|
});
|
|
2904
|
-
ctx.
|
|
2905
|
-
ctx.base.export("on-failure-queue-arn", queue2.arn);
|
|
2886
|
+
ctx.shared.set("on-failure-queue-arn", queue2.arn);
|
|
2906
2887
|
},
|
|
2907
2888
|
onStack(ctx) {
|
|
2908
2889
|
const onFailure = ctx.stackConfig.onFailure;
|
|
2909
2890
|
if (!onFailure) {
|
|
2910
2891
|
return;
|
|
2911
2892
|
}
|
|
2912
|
-
const queueArn = ctx.
|
|
2913
|
-
const group = new Node7("on-failure", "failure");
|
|
2914
|
-
ctx.stack.add(group);
|
|
2893
|
+
const queueArn = ctx.shared.get("on-failure-queue-arn");
|
|
2894
|
+
const group = new Node7(ctx.stack, "on-failure", "failure");
|
|
2915
2895
|
const { lambda, policy } = createLambdaFunction(group, ctx, "on-failure", "failure", onFailure);
|
|
2916
|
-
|
|
2896
|
+
new aws7.lambda.EventSourceMapping(group, "on-failure", {
|
|
2917
2897
|
functionArn: lambda.arn,
|
|
2918
2898
|
sourceArn: queueArn,
|
|
2919
2899
|
batchSize: 10
|
|
2920
2900
|
});
|
|
2921
|
-
group.add(source);
|
|
2922
2901
|
policy.addStatement({
|
|
2923
2902
|
actions: [
|
|
2924
2903
|
"sqs:SendMessage",
|
|
@@ -2946,22 +2925,20 @@ var pubsubFeature = defineFeature({
|
|
|
2946
2925
|
},
|
|
2947
2926
|
onStack(ctx) {
|
|
2948
2927
|
for (const [id, props] of Object.entries(ctx.stackConfig.pubsub ?? {})) {
|
|
2949
|
-
const group = new Node8("pubsub", id);
|
|
2950
|
-
ctx.stack.add(group);
|
|
2928
|
+
const group = new Node8(ctx.stack, "pubsub", id);
|
|
2951
2929
|
const { lambda } = createLambdaFunction(group, ctx, `pubsub`, "function", props.consumer);
|
|
2952
|
-
const topic = new aws8.iot.TopicRule("rule", {
|
|
2930
|
+
const topic = new aws8.iot.TopicRule(group, "rule", {
|
|
2953
2931
|
name: formatLocalResourceName(ctx.app.name, ctx.stack.name, "pubsub", id).replaceAll("-", "_"),
|
|
2954
2932
|
sql: props.sql,
|
|
2955
2933
|
sqlVersion: props.sqlVersion,
|
|
2956
2934
|
actions: [{ lambda: { functionArn: lambda.arn } }]
|
|
2957
2935
|
});
|
|
2958
|
-
|
|
2936
|
+
new aws8.lambda.Permission(group, "permission", {
|
|
2959
2937
|
action: "lambda:InvokeFunction",
|
|
2960
2938
|
principal: "iot.amazonaws.com",
|
|
2961
2939
|
functionArn: lambda.arn,
|
|
2962
2940
|
sourceArn: topic.arn
|
|
2963
2941
|
});
|
|
2964
|
-
group.add(topic, permission);
|
|
2965
2942
|
}
|
|
2966
2943
|
}
|
|
2967
2944
|
});
|
|
@@ -3022,23 +2999,20 @@ var queueFeature = defineFeature({
|
|
|
3022
2999
|
onStack(ctx) {
|
|
3023
3000
|
for (const [id, local] of Object.entries(ctx.stackConfig.queues || {})) {
|
|
3024
3001
|
const props = deepmerge2(ctx.appConfig.defaults.queue, local);
|
|
3025
|
-
const group = new Node9("queue", id);
|
|
3026
|
-
|
|
3027
|
-
const queue2 = new aws9.sqs.Queue("queue", {
|
|
3002
|
+
const group = new Node9(ctx.stack, "queue", id);
|
|
3003
|
+
const queue2 = new aws9.sqs.Queue(group, "queue", {
|
|
3028
3004
|
name: formatLocalResourceName(ctx.appConfig.name, ctx.stack.name, "queue", id),
|
|
3029
3005
|
deadLetterArn: getGlobalOnFailure(ctx),
|
|
3030
3006
|
...props
|
|
3031
3007
|
});
|
|
3032
|
-
group.add(queue2);
|
|
3033
3008
|
const { lambda, policy } = createLambdaFunction(group, ctx, `queue`, id, props.consumer);
|
|
3034
|
-
|
|
3009
|
+
new aws9.lambda.EventSourceMapping(group, "event", {
|
|
3035
3010
|
functionArn: lambda.arn,
|
|
3036
3011
|
sourceArn: queue2.arn,
|
|
3037
3012
|
batchSize: props.batchSize,
|
|
3038
3013
|
maxBatchingWindow: props.maxBatchingWindow,
|
|
3039
3014
|
maxConcurrency: props.maxConcurrency
|
|
3040
3015
|
}).dependsOn(policy);
|
|
3041
|
-
group.add(source);
|
|
3042
3016
|
policy.addStatement({
|
|
3043
3017
|
actions: ["sqs:ReceiveMessage", "sqs:DeleteMessage", "sqs:GetQueueAttributes"],
|
|
3044
3018
|
resources: [queue2.arn]
|
|
@@ -3082,9 +3056,8 @@ var storeFeature = defineFeature({
|
|
|
3082
3056
|
},
|
|
3083
3057
|
onStack(ctx) {
|
|
3084
3058
|
for (const id of ctx.stackConfig.stores || []) {
|
|
3085
|
-
const group = new Node10("store", id);
|
|
3086
|
-
|
|
3087
|
-
const bucket = new aws10.s3.Bucket("store", {
|
|
3059
|
+
const group = new Node10(ctx.stack, "store", id);
|
|
3060
|
+
const bucket = new aws10.s3.Bucket(group, "store", {
|
|
3088
3061
|
name: formatLocalResourceName(ctx.appConfig.name, ctx.stack.name, "store", id),
|
|
3089
3062
|
cors: [
|
|
3090
3063
|
// ---------------------------------------------
|
|
@@ -3097,7 +3070,6 @@ var storeFeature = defineFeature({
|
|
|
3097
3070
|
// ---------------------------------------------
|
|
3098
3071
|
]
|
|
3099
3072
|
});
|
|
3100
|
-
group.add(bucket);
|
|
3101
3073
|
ctx.onFunction(({ policy }) => {
|
|
3102
3074
|
policy.addStatement(bucket.permissions);
|
|
3103
3075
|
});
|
|
@@ -3125,17 +3097,15 @@ var tableFeature = defineFeature({
|
|
|
3125
3097
|
},
|
|
3126
3098
|
onStack(ctx) {
|
|
3127
3099
|
for (const [id, props] of Object.entries(ctx.stackConfig.tables ?? {})) {
|
|
3128
|
-
const group = new Node11("table", id);
|
|
3129
|
-
|
|
3130
|
-
const table2 = new aws11.dynamodb.Table("table", {
|
|
3100
|
+
const group = new Node11(ctx.stack, "table", id);
|
|
3101
|
+
const table2 = new aws11.dynamodb.Table(group, "table", {
|
|
3131
3102
|
...props,
|
|
3132
3103
|
name: formatLocalResourceName(ctx.appConfig.name, ctx.stackConfig.name, "table", id),
|
|
3133
3104
|
stream: props.stream?.type
|
|
3134
3105
|
});
|
|
3135
|
-
group.add(table2);
|
|
3136
3106
|
if (props.stream) {
|
|
3137
3107
|
const { lambda, policy } = createLambdaFunction(group, ctx, "table", id, props.stream.consumer);
|
|
3138
|
-
|
|
3108
|
+
new aws11.lambda.EventSourceMapping(group, id, {
|
|
3139
3109
|
functionArn: lambda.arn,
|
|
3140
3110
|
sourceArn: table2.streamArn,
|
|
3141
3111
|
batchSize: 100,
|
|
@@ -3145,7 +3115,6 @@ var tableFeature = defineFeature({
|
|
|
3145
3115
|
startingPosition: "latest",
|
|
3146
3116
|
onFailure: getGlobalOnFailure(ctx)
|
|
3147
3117
|
});
|
|
3148
|
-
group.add(source);
|
|
3149
3118
|
policy.addStatement(table2.streamPermissions);
|
|
3150
3119
|
}
|
|
3151
3120
|
ctx.onFunction(({ policy }) => {
|
|
@@ -3203,13 +3172,11 @@ var topicFeature = defineFeature({
|
|
|
3203
3172
|
onApp(ctx) {
|
|
3204
3173
|
for (const stack of ctx.stackConfigs) {
|
|
3205
3174
|
for (const id of stack.topics ?? []) {
|
|
3206
|
-
const group = new Node12("topic", id);
|
|
3207
|
-
|
|
3208
|
-
const topic = new aws12.sns.Topic("topic", {
|
|
3175
|
+
const group = new Node12(ctx.base, "topic", id);
|
|
3176
|
+
const topic = new aws12.sns.Topic(group, "topic", {
|
|
3209
3177
|
name: formatGlobalResourceName(ctx.appConfig.name, "topic", id)
|
|
3210
3178
|
});
|
|
3211
|
-
|
|
3212
|
-
ctx.base.export(`topic-${id}-arn`, topic.arn);
|
|
3179
|
+
ctx.shared.set(`topic-${id}-arn`, topic.arn);
|
|
3213
3180
|
}
|
|
3214
3181
|
}
|
|
3215
3182
|
},
|
|
@@ -3218,35 +3185,32 @@ var topicFeature = defineFeature({
|
|
|
3218
3185
|
ctx.onFunction(({ policy }) => {
|
|
3219
3186
|
policy.addStatement({
|
|
3220
3187
|
actions: ["sns:Publish"],
|
|
3221
|
-
resources: [ctx.
|
|
3188
|
+
resources: [ctx.shared.get(`topic-${id}-arn`)]
|
|
3222
3189
|
});
|
|
3223
3190
|
});
|
|
3224
3191
|
}
|
|
3225
3192
|
for (const [id, props] of Object.entries(ctx.stackConfig.subscribers ?? {})) {
|
|
3226
|
-
const group = new Node12("topic", id);
|
|
3227
|
-
ctx.
|
|
3228
|
-
const topicArn = ctx.app.import("base", `topic-${id}-arn`);
|
|
3193
|
+
const group = new Node12(ctx.stack, "topic", id);
|
|
3194
|
+
const topicArn = ctx.shared.get(`topic-${id}-arn`);
|
|
3229
3195
|
if (typeof props === "string" && isEmail(props)) {
|
|
3230
|
-
|
|
3196
|
+
new aws12.sns.Subscription(group, id, {
|
|
3231
3197
|
topicArn,
|
|
3232
3198
|
protocol: "email",
|
|
3233
3199
|
endpoint: props
|
|
3234
3200
|
});
|
|
3235
|
-
group.add(subscription);
|
|
3236
3201
|
} else if (typeof props === "object") {
|
|
3237
3202
|
const { lambda } = createLambdaFunction(group, ctx, `topic`, id, props);
|
|
3238
|
-
|
|
3203
|
+
new aws12.sns.Subscription(group, id, {
|
|
3239
3204
|
topicArn,
|
|
3240
3205
|
protocol: "lambda",
|
|
3241
3206
|
endpoint: lambda.arn
|
|
3242
3207
|
});
|
|
3243
|
-
|
|
3208
|
+
new aws12.lambda.Permission(group, id, {
|
|
3244
3209
|
action: "lambda:InvokeFunction",
|
|
3245
3210
|
principal: "sns.amazonaws.com",
|
|
3246
3211
|
functionArn: lambda.arn,
|
|
3247
3212
|
sourceArn: topicArn
|
|
3248
3213
|
});
|
|
3249
|
-
group.add(topic, permission);
|
|
3250
3214
|
}
|
|
3251
3215
|
}
|
|
3252
3216
|
}
|
|
@@ -3257,37 +3221,35 @@ import { Node as Node13, all, aws as aws13 } from "@awsless/formation";
|
|
|
3257
3221
|
var vpcFeature = defineFeature({
|
|
3258
3222
|
name: "vpc",
|
|
3259
3223
|
onApp(ctx) {
|
|
3260
|
-
const
|
|
3224
|
+
const group = new Node13(ctx.base, "vpc", "main");
|
|
3225
|
+
const vpc = new aws13.ec2.Vpc(group, "vpc", {
|
|
3261
3226
|
name: ctx.app.name,
|
|
3262
3227
|
cidrBlock: aws13.ec2.Peer.ipv4("10.0.0.0/16")
|
|
3263
3228
|
});
|
|
3264
|
-
const privateRouteTable = new aws13.ec2.RouteTable("private", {
|
|
3229
|
+
const privateRouteTable = new aws13.ec2.RouteTable(group, "private", {
|
|
3265
3230
|
vpcId: vpc.id,
|
|
3266
3231
|
name: "private"
|
|
3267
3232
|
});
|
|
3268
|
-
const publicRouteTable = new aws13.ec2.RouteTable("public", {
|
|
3233
|
+
const publicRouteTable = new aws13.ec2.RouteTable(group, "public", {
|
|
3269
3234
|
vpcId: vpc.id,
|
|
3270
3235
|
name: "public"
|
|
3271
3236
|
});
|
|
3272
|
-
const gateway = new aws13.ec2.InternetGateway("gateway");
|
|
3273
|
-
const attachment = new aws13.ec2.VPCGatewayAttachment("attachment", {
|
|
3237
|
+
const gateway = new aws13.ec2.InternetGateway(group, "gateway");
|
|
3238
|
+
const attachment = new aws13.ec2.VPCGatewayAttachment(group, "attachment", {
|
|
3274
3239
|
vpcId: vpc.id,
|
|
3275
3240
|
internetGatewayId: gateway.id
|
|
3276
3241
|
});
|
|
3277
|
-
|
|
3242
|
+
new aws13.ec2.Route(group, "route", {
|
|
3278
3243
|
gatewayId: gateway.id,
|
|
3279
3244
|
routeTableId: publicRouteTable.id,
|
|
3280
3245
|
destination: aws13.ec2.Peer.anyIpv4()
|
|
3281
3246
|
});
|
|
3282
|
-
ctx.
|
|
3247
|
+
ctx.shared.set(
|
|
3283
3248
|
"vpc-id",
|
|
3284
3249
|
// Some resources require the internet gateway to be attached.
|
|
3285
3250
|
all([vpc.id, attachment.internetGatewayId]).apply(([id]) => id)
|
|
3286
3251
|
);
|
|
3287
|
-
ctx.
|
|
3288
|
-
const group = new Node13("vpc", "main");
|
|
3289
|
-
group.add(vpc, privateRouteTable, publicRouteTable, gateway, attachment, route);
|
|
3290
|
-
ctx.base.add(group);
|
|
3252
|
+
ctx.shared.set("vpc-security-group-id", vpc.defaultSecurityGroup);
|
|
3291
3253
|
const zones = ["a", "b"];
|
|
3292
3254
|
const tables = [privateRouteTable, publicRouteTable];
|
|
3293
3255
|
let block = 0;
|
|
@@ -3295,17 +3257,16 @@ var vpcFeature = defineFeature({
|
|
|
3295
3257
|
for (const i in zones) {
|
|
3296
3258
|
const index = Number(i) + 1;
|
|
3297
3259
|
const id = `${table2.identifier}-${index}`;
|
|
3298
|
-
const subnet = new aws13.ec2.Subnet(id, {
|
|
3260
|
+
const subnet = new aws13.ec2.Subnet(group, id, {
|
|
3299
3261
|
vpcId: vpc.id,
|
|
3300
3262
|
cidrBlock: aws13.ec2.Peer.ipv4(`10.0.${block++}.0/24`),
|
|
3301
3263
|
availabilityZone: ctx.appConfig.region + zones[i]
|
|
3302
3264
|
});
|
|
3303
|
-
|
|
3265
|
+
new aws13.ec2.SubnetRouteTableAssociation(group, id, {
|
|
3304
3266
|
routeTableId: table2.id,
|
|
3305
3267
|
subnetId: subnet.id
|
|
3306
3268
|
});
|
|
3307
|
-
ctx.
|
|
3308
|
-
group.add(subnet, association);
|
|
3269
|
+
ctx.shared.set(`vpc-${table2.identifier}-subnet-id-${index}`, subnet.id);
|
|
3309
3270
|
}
|
|
3310
3271
|
}
|
|
3311
3272
|
}
|
|
@@ -3320,7 +3281,7 @@ var authFeature = defineFeature({
|
|
|
3320
3281
|
const gen = new TypeFile("@awsless/awsless");
|
|
3321
3282
|
const resources = new TypeObject(1);
|
|
3322
3283
|
for (const name of Object.keys(ctx.appConfig.defaults.auth)) {
|
|
3323
|
-
const authName = formatGlobalResourceName(ctx.appConfig.name,
|
|
3284
|
+
const authName = formatGlobalResourceName(ctx.appConfig.name, "auth", name);
|
|
3324
3285
|
resources.addType(
|
|
3325
3286
|
name,
|
|
3326
3287
|
`{ readonly name: '${authName}', readonly userPoolId: string, readonly clientId: string }`
|
|
@@ -3331,16 +3292,14 @@ var authFeature = defineFeature({
|
|
|
3331
3292
|
},
|
|
3332
3293
|
onStack(ctx) {
|
|
3333
3294
|
for (const [id, props] of Object.entries(ctx.stackConfig.auth ?? {})) {
|
|
3334
|
-
const group = new Node14(
|
|
3335
|
-
ctx.
|
|
3336
|
-
const
|
|
3337
|
-
const
|
|
3338
|
-
const clientId = ctx.app.import("base", `auth-${id}-client-id`);
|
|
3295
|
+
const group = new Node14(ctx.stack, "auth", id);
|
|
3296
|
+
const userPoolId = ctx.shared.get(`auth-${id}-user-pool-id`);
|
|
3297
|
+
const userPoolArn = ctx.shared.get(`auth-${id}-user-pool-arn`);
|
|
3298
|
+
const clientId = ctx.shared.get(`auth-${id}-client-id`);
|
|
3339
3299
|
const triggers = {};
|
|
3340
3300
|
const list4 = {};
|
|
3341
3301
|
for (const [trigger, triggerProps] of Object.entries(props.triggers ?? {})) {
|
|
3342
|
-
const triggerGroup = new Node14("trigger", trigger);
|
|
3343
|
-
group.add(triggerGroup);
|
|
3302
|
+
const triggerGroup = new Node14(group, "trigger", trigger);
|
|
3344
3303
|
const { lambda, policy } = createLambdaFunction(
|
|
3345
3304
|
triggerGroup,
|
|
3346
3305
|
ctx,
|
|
@@ -3356,19 +3315,17 @@ var authFeature = defineFeature({
|
|
|
3356
3315
|
policy
|
|
3357
3316
|
};
|
|
3358
3317
|
}
|
|
3359
|
-
|
|
3318
|
+
new aws14.cognito.LambdaTriggers(group, "lambda-triggers", {
|
|
3360
3319
|
userPoolId,
|
|
3361
3320
|
triggers
|
|
3362
3321
|
});
|
|
3363
|
-
group.add(lambdaTriggers);
|
|
3364
3322
|
for (const item of Object.values(list4)) {
|
|
3365
|
-
|
|
3323
|
+
new aws14.lambda.Permission(item.group, `permission`, {
|
|
3366
3324
|
action: "lambda:InvokeFunction",
|
|
3367
3325
|
principal: "cognito-idp.amazonaws.com",
|
|
3368
3326
|
functionArn: item.lambda.arn,
|
|
3369
3327
|
sourceArn: userPoolArn
|
|
3370
3328
|
});
|
|
3371
|
-
item.group.add(permission);
|
|
3372
3329
|
item.lambda.addEnvironment(`AUTH_${constantCase4(id)}_USER_POOL_ID`, userPoolId);
|
|
3373
3330
|
item.lambda.addEnvironment(`AUTH_${constantCase4(id)}_CLIENT_ID`, clientId);
|
|
3374
3331
|
item.policy.addStatement({
|
|
@@ -3389,21 +3346,20 @@ var authFeature = defineFeature({
|
|
|
3389
3346
|
},
|
|
3390
3347
|
onApp(ctx) {
|
|
3391
3348
|
for (const [id, props] of Object.entries(ctx.appConfig.defaults.auth ?? {})) {
|
|
3392
|
-
const group = new Node14(
|
|
3393
|
-
ctx.base.add(group);
|
|
3349
|
+
const group = new Node14(ctx.base, "auth", id);
|
|
3394
3350
|
let emailConfig;
|
|
3395
3351
|
if (props.messaging) {
|
|
3396
3352
|
const [_, domainName] = props.messaging.fromEmail.split("@");
|
|
3397
3353
|
emailConfig = {
|
|
3398
3354
|
type: "developer",
|
|
3399
3355
|
replyTo: props.messaging.replyTo,
|
|
3400
|
-
sourceArn: ctx.
|
|
3401
|
-
configurationSet: ctx.
|
|
3356
|
+
sourceArn: ctx.shared.get(`mail-${domainName}-arn`),
|
|
3357
|
+
configurationSet: ctx.shared.get("mail-configuration-set"),
|
|
3402
3358
|
from: props.messaging.fromName ? `${props.messaging.fromName} <${props.messaging.fromEmail}>` : props.messaging.fromEmail
|
|
3403
3359
|
};
|
|
3404
3360
|
}
|
|
3405
|
-
const name = formatGlobalResourceName(ctx.appConfig.name,
|
|
3406
|
-
const userPool = new aws14.cognito.UserPool("user-pool", {
|
|
3361
|
+
const name = formatGlobalResourceName(ctx.appConfig.name, "auth", id);
|
|
3362
|
+
const userPool = new aws14.cognito.UserPool(group, "user-pool", {
|
|
3407
3363
|
name,
|
|
3408
3364
|
// deletionProtection: true,
|
|
3409
3365
|
allowUserRegistration: props.allowUserRegistration,
|
|
@@ -3411,8 +3367,7 @@ var authFeature = defineFeature({
|
|
|
3411
3367
|
password: props.password,
|
|
3412
3368
|
email: emailConfig
|
|
3413
3369
|
});
|
|
3414
|
-
|
|
3415
|
-
const client = new aws14.cognito.UserPoolClient("client", {
|
|
3370
|
+
const client = new aws14.cognito.UserPoolClient(group, "client", {
|
|
3416
3371
|
userPoolId: userPool.id,
|
|
3417
3372
|
name,
|
|
3418
3373
|
validity: props.validity,
|
|
@@ -3421,10 +3376,9 @@ var authFeature = defineFeature({
|
|
|
3421
3376
|
userSrp: true
|
|
3422
3377
|
}
|
|
3423
3378
|
});
|
|
3424
|
-
|
|
3425
|
-
ctx.
|
|
3426
|
-
ctx.
|
|
3427
|
-
ctx.base.export(`auth-${id}-client-id`, client.id);
|
|
3379
|
+
ctx.shared.set(`auth-${id}-user-pool-arn`, userPool.arn);
|
|
3380
|
+
ctx.shared.set(`auth-${id}-user-pool-id`, userPool.id);
|
|
3381
|
+
ctx.shared.set(`auth-${id}-client-id`, client.id);
|
|
3428
3382
|
}
|
|
3429
3383
|
}
|
|
3430
3384
|
});
|
|
@@ -3513,32 +3467,32 @@ var httpFeature = defineFeature({
|
|
|
3513
3467
|
if (Object.keys(ctx.appConfig.defaults?.http ?? {}).length === 0) {
|
|
3514
3468
|
return;
|
|
3515
3469
|
}
|
|
3516
|
-
const group = new Node15("http", "main");
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
vpcId: ctx.base.import(`vpc-id`),
|
|
3470
|
+
const group = new Node15(ctx.base, "http", "main");
|
|
3471
|
+
const securityGroup = new aws15.ec2.SecurityGroup(group, "http", {
|
|
3472
|
+
vpcId: ctx.shared.get(`vpc-id`),
|
|
3520
3473
|
name: formatGlobalResourceName(ctx.app.name, "http", "http"),
|
|
3521
3474
|
description: `Global security group for HTTP api.`
|
|
3522
3475
|
});
|
|
3523
3476
|
const port = aws15.ec2.Port.tcp(443);
|
|
3524
3477
|
securityGroup.addIngressRule({ port, peer: aws15.ec2.Peer.anyIpv4() });
|
|
3525
3478
|
securityGroup.addIngressRule({ port, peer: aws15.ec2.Peer.anyIpv6() });
|
|
3526
|
-
group.add(securityGroup);
|
|
3527
3479
|
for (const [id, props] of Object.entries(ctx.appConfig.defaults?.http ?? {})) {
|
|
3528
|
-
const group2 = new Node15("http", id);
|
|
3529
|
-
|
|
3530
|
-
const loadBalancer = new aws15.elb.LoadBalancer("balancer", {
|
|
3480
|
+
const group2 = new Node15(ctx.base, "http", id);
|
|
3481
|
+
const loadBalancer = new aws15.elb.LoadBalancer(group2, "balancer", {
|
|
3531
3482
|
name: formatGlobalResourceName(ctx.app.name, "http", id),
|
|
3532
3483
|
type: "application",
|
|
3533
3484
|
securityGroups: [securityGroup.id],
|
|
3534
|
-
subnets: [
|
|
3485
|
+
subnets: [
|
|
3486
|
+
//
|
|
3487
|
+
ctx.shared.get(`vpc-public-subnet-id-1`),
|
|
3488
|
+
ctx.shared.get(`vpc-public-subnet-id-2`)
|
|
3489
|
+
]
|
|
3535
3490
|
});
|
|
3536
|
-
|
|
3537
|
-
const listener = new aws15.elb.Listener("listener", {
|
|
3491
|
+
const listener = new aws15.elb.Listener(group2, "listener", {
|
|
3538
3492
|
loadBalancerArn: loadBalancer.arn,
|
|
3539
3493
|
port: 443,
|
|
3540
3494
|
protocol: "https",
|
|
3541
|
-
certificates: [ctx.
|
|
3495
|
+
certificates: [ctx.shared.get(`local-certificate-${props.domain}-arn`)],
|
|
3542
3496
|
defaultActions: [
|
|
3543
3497
|
aws15.elb.ListenerAction.fixedResponse({
|
|
3544
3498
|
statusCode: 404,
|
|
@@ -3549,10 +3503,9 @@ var httpFeature = defineFeature({
|
|
|
3549
3503
|
})
|
|
3550
3504
|
]
|
|
3551
3505
|
});
|
|
3552
|
-
group2.add(listener);
|
|
3553
3506
|
const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
|
|
3554
|
-
|
|
3555
|
-
hostedZoneId: ctx.
|
|
3507
|
+
new aws15.route53.RecordSet(group2, domainName, {
|
|
3508
|
+
hostedZoneId: ctx.shared.get(`hosted-zone-${props.domain}-id`),
|
|
3556
3509
|
name: domainName,
|
|
3557
3510
|
type: "A",
|
|
3558
3511
|
alias: {
|
|
@@ -3561,8 +3514,7 @@ var httpFeature = defineFeature({
|
|
|
3561
3514
|
dnsName: loadBalancer.dnsName
|
|
3562
3515
|
}
|
|
3563
3516
|
});
|
|
3564
|
-
|
|
3565
|
-
ctx.base.export(`http-${id}-listener-arn`, listener.arn);
|
|
3517
|
+
ctx.shared.set(`http-${id}-listener-arn`, listener.arn);
|
|
3566
3518
|
}
|
|
3567
3519
|
},
|
|
3568
3520
|
onStack(ctx) {
|
|
@@ -3571,11 +3523,9 @@ var httpFeature = defineFeature({
|
|
|
3571
3523
|
if (!props) {
|
|
3572
3524
|
throw new Error(`Http definition is not defined on app level for "${id}"`);
|
|
3573
3525
|
}
|
|
3574
|
-
const group = new Node15("http", id);
|
|
3575
|
-
ctx.stack.add(group);
|
|
3526
|
+
const group = new Node15(ctx.stack, "http", id);
|
|
3576
3527
|
for (const [routeKey, routeProps] of Object.entries(routes)) {
|
|
3577
|
-
const routeGroup = new Node15("route", routeKey);
|
|
3578
|
-
group.add(routeGroup);
|
|
3528
|
+
const routeGroup = new Node15(group, "route", routeKey);
|
|
3579
3529
|
const { method, path } = parseRoute(routeKey);
|
|
3580
3530
|
const routeId = shortId(routeKey);
|
|
3581
3531
|
const { lambda } = createLambdaFunction(routeGroup, ctx, "http", `${id}-${routeId}`, {
|
|
@@ -3583,21 +3533,19 @@ var httpFeature = defineFeature({
|
|
|
3583
3533
|
description: routeKey
|
|
3584
3534
|
});
|
|
3585
3535
|
const name = formatLocalResourceName(ctx.app.name, ctx.stack.name, "http", routeId);
|
|
3586
|
-
const permission = new aws15.lambda.Permission(id, {
|
|
3536
|
+
const permission = new aws15.lambda.Permission(routeGroup, id, {
|
|
3587
3537
|
action: "lambda:InvokeFunction",
|
|
3588
3538
|
principal: "elasticloadbalancing.amazonaws.com",
|
|
3589
3539
|
functionArn: lambda.arn
|
|
3590
3540
|
// sourceArn: `arn:aws:elasticloadbalancing:${ctx.appConfig.region}:*:targetgroup/${name}/*`,
|
|
3591
3541
|
});
|
|
3592
|
-
|
|
3593
|
-
const target = new aws15.elb.TargetGroup(id, {
|
|
3542
|
+
const target = new aws15.elb.TargetGroup(routeGroup, id, {
|
|
3594
3543
|
name,
|
|
3595
3544
|
type: "lambda",
|
|
3596
3545
|
targets: [lambda.arn]
|
|
3597
3546
|
}).dependsOn(permission);
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
listenerArn: ctx.app.import("base", `http-${id}-listener-arn`),
|
|
3547
|
+
new aws15.elb.ListenerRule(routeGroup, id, {
|
|
3548
|
+
listenerArn: ctx.shared.get(`http-${id}-listener-arn`),
|
|
3601
3549
|
priority: generatePriority(ctx.stackConfig.name, routeKey),
|
|
3602
3550
|
conditions: [
|
|
3603
3551
|
aws15.elb.ListenerCondition.httpRequestMethods([method]),
|
|
@@ -3605,7 +3553,6 @@ var httpFeature = defineFeature({
|
|
|
3605
3553
|
],
|
|
3606
3554
|
actions: [aws15.elb.ListenerAction.forward([target.arn])]
|
|
3607
3555
|
}).dependsOn(target);
|
|
3608
|
-
routeGroup.add(rule);
|
|
3609
3556
|
}
|
|
3610
3557
|
}
|
|
3611
3558
|
}
|
|
@@ -3631,9 +3578,8 @@ var searchFeature = defineFeature({
|
|
|
3631
3578
|
},
|
|
3632
3579
|
onStack(ctx) {
|
|
3633
3580
|
for (const [id, props] of Object.entries(ctx.stackConfig.searchs ?? {})) {
|
|
3634
|
-
const group = new Node16("search", id);
|
|
3635
|
-
|
|
3636
|
-
const domain = new aws16.openSearch.Domain("domain", {
|
|
3581
|
+
const group = new Node16(ctx.stack, "search", id);
|
|
3582
|
+
const domain = new aws16.openSearch.Domain(group, "domain", {
|
|
3637
3583
|
// name: formatLocalResourceName(ctx.app.name, ctx.stack.name, this.name, id),
|
|
3638
3584
|
version: props.version,
|
|
3639
3585
|
storageSize: props.storage,
|
|
@@ -3652,11 +3598,13 @@ var searchFeature = defineFeature({
|
|
|
3652
3598
|
});
|
|
3653
3599
|
if (props.vpc) {
|
|
3654
3600
|
domain.setVpc({
|
|
3655
|
-
securityGroupIds: [ctx.
|
|
3656
|
-
subnetIds: [
|
|
3601
|
+
securityGroupIds: [ctx.shared.get(`vpc-security-group-id`)],
|
|
3602
|
+
subnetIds: [
|
|
3603
|
+
ctx.shared.get("vpc-private-subnet-id-1"),
|
|
3604
|
+
ctx.shared.get("vpc-private-subnet-id-2")
|
|
3605
|
+
]
|
|
3657
3606
|
});
|
|
3658
3607
|
}
|
|
3659
|
-
group.add(domain);
|
|
3660
3608
|
ctx.onFunction(({ policy }) => {
|
|
3661
3609
|
policy.addStatement({
|
|
3662
3610
|
actions: ["es:*"],
|
|
@@ -3698,8 +3646,7 @@ var siteFeature = defineFeature({
|
|
|
3698
3646
|
name: "site",
|
|
3699
3647
|
onStack(ctx) {
|
|
3700
3648
|
for (const [id, props] of Object.entries(ctx.stackConfig.sites ?? {})) {
|
|
3701
|
-
const group = new Node17("site", id);
|
|
3702
|
-
ctx.stack.add(group);
|
|
3649
|
+
const group = new Node17(ctx.stack, "site", id);
|
|
3703
3650
|
const name = formatLocalResourceName(ctx.app.name, ctx.stack.name, "site", id);
|
|
3704
3651
|
const origins = [];
|
|
3705
3652
|
const originGroups = [];
|
|
@@ -3708,7 +3655,7 @@ var siteFeature = defineFeature({
|
|
|
3708
3655
|
if (props.ssr) {
|
|
3709
3656
|
const { lambda, code } = createLambdaFunction(group, ctx, `site`, id, props.ssr);
|
|
3710
3657
|
versions.push(code.version);
|
|
3711
|
-
|
|
3658
|
+
new aws17.lambda.Permission(group, "permission", {
|
|
3712
3659
|
principal: "*",
|
|
3713
3660
|
// principal: 'cloudfront.amazonaws.com',
|
|
3714
3661
|
action: "lambda:InvokeFunctionUrl",
|
|
@@ -3717,13 +3664,11 @@ var siteFeature = defineFeature({
|
|
|
3717
3664
|
// urlAuthType: 'aws-iam',
|
|
3718
3665
|
// sourceArn: distribution.arn,
|
|
3719
3666
|
});
|
|
3720
|
-
|
|
3721
|
-
const url = new aws17.lambda.Url("url", {
|
|
3667
|
+
const url = new aws17.lambda.Url(group, "url", {
|
|
3722
3668
|
targetArn: lambda.arn,
|
|
3723
3669
|
authType: "none"
|
|
3724
3670
|
// authType: 'aws-iam',
|
|
3725
3671
|
});
|
|
3726
|
-
group.add(url);
|
|
3727
3672
|
origins.push({
|
|
3728
3673
|
id: "ssr",
|
|
3729
3674
|
domainName: url.url.apply((url2) => url2.split("/")[2]),
|
|
@@ -3731,7 +3676,7 @@ var siteFeature = defineFeature({
|
|
|
3731
3676
|
});
|
|
3732
3677
|
}
|
|
3733
3678
|
if (props.static) {
|
|
3734
|
-
bucket = new aws17.s3.Bucket("bucket", {
|
|
3679
|
+
bucket = new aws17.s3.Bucket(group, "bucket", {
|
|
3735
3680
|
name,
|
|
3736
3681
|
forceDelete: true,
|
|
3737
3682
|
website: {
|
|
@@ -3748,28 +3693,25 @@ var siteFeature = defineFeature({
|
|
|
3748
3693
|
]
|
|
3749
3694
|
});
|
|
3750
3695
|
bucket.deletionPolicy = "after-deployment";
|
|
3751
|
-
|
|
3752
|
-
const accessControl = new aws17.cloudFront.OriginAccessControl(`access`, {
|
|
3696
|
+
const accessControl = new aws17.cloudFront.OriginAccessControl(group, `access`, {
|
|
3753
3697
|
name,
|
|
3754
3698
|
type: "s3",
|
|
3755
3699
|
behavior: "always",
|
|
3756
3700
|
protocol: "sigv4"
|
|
3757
3701
|
});
|
|
3758
3702
|
accessControl.deletionPolicy = "after-deployment";
|
|
3759
|
-
group.add(accessControl);
|
|
3760
3703
|
const files = glob2.sync("**", {
|
|
3761
3704
|
cwd: props.static,
|
|
3762
3705
|
nodir: true
|
|
3763
3706
|
});
|
|
3764
3707
|
for (const file of files) {
|
|
3765
|
-
const object = new aws17.s3.BucketObject(file, {
|
|
3708
|
+
const object = new aws17.s3.BucketObject(group, file, {
|
|
3766
3709
|
bucket: bucket.name,
|
|
3767
3710
|
key: file,
|
|
3768
3711
|
body: Asset3.fromFile(join8(props.static, file)),
|
|
3769
3712
|
cacheControl: getCacheControl(file),
|
|
3770
3713
|
contentType: getContentType(file)
|
|
3771
3714
|
});
|
|
3772
|
-
group.add(object);
|
|
3773
3715
|
versions.push(object.key);
|
|
3774
3716
|
versions.push(object.etag);
|
|
3775
3717
|
}
|
|
@@ -3786,24 +3728,22 @@ var siteFeature = defineFeature({
|
|
|
3786
3728
|
statusCodes: [403, 404]
|
|
3787
3729
|
});
|
|
3788
3730
|
}
|
|
3789
|
-
const cache = new aws17.cloudFront.CachePolicy("cache", {
|
|
3731
|
+
const cache = new aws17.cloudFront.CachePolicy(group, "cache", {
|
|
3790
3732
|
name,
|
|
3791
3733
|
minTtl: seconds3(1),
|
|
3792
3734
|
maxTtl: days3(365),
|
|
3793
3735
|
defaultTtl: days3(1),
|
|
3794
3736
|
...props.cache
|
|
3795
3737
|
});
|
|
3796
|
-
|
|
3797
|
-
const originRequest = new aws17.cloudFront.OriginRequestPolicy("request", {
|
|
3738
|
+
const originRequest = new aws17.cloudFront.OriginRequestPolicy(group, "request", {
|
|
3798
3739
|
name,
|
|
3799
3740
|
header: {
|
|
3800
3741
|
behavior: "all-except",
|
|
3801
3742
|
values: ["host", "authorization"]
|
|
3802
3743
|
}
|
|
3803
3744
|
});
|
|
3804
|
-
group.add(originRequest);
|
|
3805
3745
|
const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
|
|
3806
|
-
const responseHeaders = new aws17.cloudFront.ResponseHeadersPolicy("response", {
|
|
3746
|
+
const responseHeaders = new aws17.cloudFront.ResponseHeadersPolicy(group, "response", {
|
|
3807
3747
|
name,
|
|
3808
3748
|
cors: props.cors,
|
|
3809
3749
|
remove: ["server"]
|
|
@@ -3811,10 +3751,9 @@ var siteFeature = defineFeature({
|
|
|
3811
3751
|
// override: true,
|
|
3812
3752
|
// },
|
|
3813
3753
|
});
|
|
3814
|
-
|
|
3815
|
-
const distribution = new aws17.cloudFront.Distribution("distribution", {
|
|
3754
|
+
const distribution = new aws17.cloudFront.Distribution(group, "distribution", {
|
|
3816
3755
|
name,
|
|
3817
|
-
certificateArn: ctx.
|
|
3756
|
+
certificateArn: ctx.shared.get(`global-certificate-${props.domain}-arn`),
|
|
3818
3757
|
compress: true,
|
|
3819
3758
|
aliases: [domainName],
|
|
3820
3759
|
origins,
|
|
@@ -3840,15 +3779,13 @@ var siteFeature = defineFeature({
|
|
|
3840
3779
|
};
|
|
3841
3780
|
})
|
|
3842
3781
|
});
|
|
3843
|
-
|
|
3844
|
-
const invalidate = new aws17.cloudFront.InvalidateCache("invalidate", {
|
|
3782
|
+
new aws17.cloudFront.InvalidateCache(group, "invalidate", {
|
|
3845
3783
|
distributionId: distribution.id,
|
|
3846
3784
|
paths: ["/*"],
|
|
3847
3785
|
versions
|
|
3848
3786
|
});
|
|
3849
|
-
group.add(invalidate);
|
|
3850
3787
|
if (props.static) {
|
|
3851
|
-
|
|
3788
|
+
new aws17.s3.BucketPolicy(group, `policy`, {
|
|
3852
3789
|
bucketName: bucket.name,
|
|
3853
3790
|
statements: [
|
|
3854
3791
|
{
|
|
@@ -3873,10 +3810,9 @@ var siteFeature = defineFeature({
|
|
|
3873
3810
|
// }
|
|
3874
3811
|
]
|
|
3875
3812
|
});
|
|
3876
|
-
group.add(bucketPolicy);
|
|
3877
3813
|
}
|
|
3878
|
-
|
|
3879
|
-
hostedZoneId: ctx.
|
|
3814
|
+
new aws17.route53.RecordSet(group, `record`, {
|
|
3815
|
+
hostedZoneId: ctx.shared.get(`hosted-zone-${props.domain}-id`),
|
|
3880
3816
|
type: "A",
|
|
3881
3817
|
name: domainName,
|
|
3882
3818
|
alias: {
|
|
@@ -3885,7 +3821,6 @@ var siteFeature = defineFeature({
|
|
|
3885
3821
|
evaluateTargetHealth: false
|
|
3886
3822
|
}
|
|
3887
3823
|
});
|
|
3888
|
-
group.add(record);
|
|
3889
3824
|
}
|
|
3890
3825
|
}
|
|
3891
3826
|
});
|
|
@@ -3915,6 +3850,18 @@ var features = [
|
|
|
3915
3850
|
siteFeature
|
|
3916
3851
|
];
|
|
3917
3852
|
|
|
3853
|
+
// src/shared.ts
|
|
3854
|
+
var SharedData = class {
|
|
3855
|
+
data = {};
|
|
3856
|
+
get(key) {
|
|
3857
|
+
return this.data[key];
|
|
3858
|
+
}
|
|
3859
|
+
set(key, value) {
|
|
3860
|
+
this.data[key] = value;
|
|
3861
|
+
return this;
|
|
3862
|
+
}
|
|
3863
|
+
};
|
|
3864
|
+
|
|
3918
3865
|
// src/app.ts
|
|
3919
3866
|
var getFiltersWithDeps = (stacks, filters) => {
|
|
3920
3867
|
const list4 = [];
|
|
@@ -3936,7 +3883,8 @@ var getFiltersWithDeps = (stacks, filters) => {
|
|
|
3936
3883
|
};
|
|
3937
3884
|
var createApp = (props, filters = []) => {
|
|
3938
3885
|
const app = new App(props.appConfig.name);
|
|
3939
|
-
const base = new Stack("base");
|
|
3886
|
+
const base = new Stack(app, "base");
|
|
3887
|
+
const shared = new SharedData();
|
|
3940
3888
|
const tests = [];
|
|
3941
3889
|
const builders = [];
|
|
3942
3890
|
const allFunctions = [];
|
|
@@ -3946,6 +3894,7 @@ var createApp = (props, filters = []) => {
|
|
|
3946
3894
|
...props,
|
|
3947
3895
|
app,
|
|
3948
3896
|
base,
|
|
3897
|
+
shared,
|
|
3949
3898
|
onFunction(callback) {
|
|
3950
3899
|
globalListeners.push(callback);
|
|
3951
3900
|
},
|
|
@@ -3968,8 +3917,7 @@ var createApp = (props, filters = []) => {
|
|
|
3968
3917
|
for (const stackConfig of filterdStacks) {
|
|
3969
3918
|
const localListeners = [];
|
|
3970
3919
|
const localFunctions = [];
|
|
3971
|
-
const stack = new Stack(stackConfig.name);
|
|
3972
|
-
app.add(stack);
|
|
3920
|
+
const stack = new Stack(app, stackConfig.name);
|
|
3973
3921
|
for (const feature of features) {
|
|
3974
3922
|
feature.onStack?.({
|
|
3975
3923
|
...props,
|
|
@@ -3977,6 +3925,7 @@ var createApp = (props, filters = []) => {
|
|
|
3977
3925
|
app,
|
|
3978
3926
|
base,
|
|
3979
3927
|
stack,
|
|
3928
|
+
shared,
|
|
3980
3929
|
onFunction(callback) {
|
|
3981
3930
|
localListeners.push(callback);
|
|
3982
3931
|
},
|
|
@@ -3998,9 +3947,6 @@ var createApp = (props, filters = []) => {
|
|
|
3998
3947
|
}
|
|
3999
3948
|
}
|
|
4000
3949
|
}
|
|
4001
|
-
if (base.resources.length > 0) {
|
|
4002
|
-
app.add(base);
|
|
4003
|
-
}
|
|
4004
3950
|
for (const listener of globalListeners) {
|
|
4005
3951
|
for (const fn of allFunctions) {
|
|
4006
3952
|
listener(fn);
|
|
@@ -4133,7 +4079,7 @@ var del = (program2) => {
|
|
|
4133
4079
|
};
|
|
4134
4080
|
|
|
4135
4081
|
// src/cli/command/config/list.ts
|
|
4136
|
-
import { log as
|
|
4082
|
+
import { log as log7, spinner as spinner5 } from "@clack/prompts";
|
|
4137
4083
|
import chalk5 from "chalk";
|
|
4138
4084
|
var list2 = (program2) => {
|
|
4139
4085
|
program2.command("list").description(`List all config value's`).action(async () => {
|
|
@@ -4155,7 +4101,7 @@ var list2 = (program2) => {
|
|
|
4155
4101
|
})
|
|
4156
4102
|
);
|
|
4157
4103
|
} else {
|
|
4158
|
-
|
|
4104
|
+
log7.warning("No config parameters found.");
|
|
4159
4105
|
}
|
|
4160
4106
|
});
|
|
4161
4107
|
});
|
|
@@ -4175,7 +4121,7 @@ var config = (program2) => {
|
|
|
4175
4121
|
};
|
|
4176
4122
|
|
|
4177
4123
|
// src/cli/command/delete.ts
|
|
4178
|
-
import { confirm as confirm3
|
|
4124
|
+
import { confirm as confirm3 } from "@clack/prompts";
|
|
4179
4125
|
import { WorkSpace, aws as aws18 } from "@awsless/formation";
|
|
4180
4126
|
import { minutes as minutes4 } from "@awsless/duration";
|
|
4181
4127
|
var del2 = (program2) => {
|
|
@@ -4201,7 +4147,7 @@ var del2 = (program2) => {
|
|
|
4201
4147
|
}
|
|
4202
4148
|
}
|
|
4203
4149
|
const workspace = new WorkSpace({
|
|
4204
|
-
stateProvider: new aws18.dynamodb.
|
|
4150
|
+
stateProvider: new aws18.dynamodb.StateProvider({
|
|
4205
4151
|
credentials,
|
|
4206
4152
|
region,
|
|
4207
4153
|
tableName: "awsless-state"
|
|
@@ -4212,18 +4158,11 @@ var del2 = (program2) => {
|
|
|
4212
4158
|
timeout: minutes4(30)
|
|
4213
4159
|
})
|
|
4214
4160
|
});
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
} catch (error) {
|
|
4221
|
-
debugError(error);
|
|
4222
|
-
spin.stop("Failed.", 2);
|
|
4223
|
-
throw error;
|
|
4224
|
-
}
|
|
4225
|
-
spin.stop(`Done deleting the ${color.info(stack.name)} stack from AWS`);
|
|
4226
|
-
}
|
|
4161
|
+
await task("Deleting the stacks to AWS", async (update) => {
|
|
4162
|
+
await workspace.deleteApp(app);
|
|
4163
|
+
update("Done deleting the stacks to AWS.");
|
|
4164
|
+
});
|
|
4165
|
+
return "Your app has been deleted!";
|
|
4227
4166
|
});
|
|
4228
4167
|
});
|
|
4229
4168
|
};
|
|
@@ -4231,7 +4170,6 @@ var del2 = (program2) => {
|
|
|
4231
4170
|
// src/cli/command/deploy.ts
|
|
4232
4171
|
import { WorkSpace as WorkSpace2, aws as aws19 } from "@awsless/formation";
|
|
4233
4172
|
import { confirm as confirm4 } from "@clack/prompts";
|
|
4234
|
-
import { run } from "promise-dag";
|
|
4235
4173
|
|
|
4236
4174
|
// src/cli/ui/complex/run-tests.ts
|
|
4237
4175
|
import { join as join9 } from "path";
|
|
@@ -4292,14 +4230,14 @@ var CustomReporter = class {
|
|
|
4292
4230
|
this.cache = cache;
|
|
4293
4231
|
}
|
|
4294
4232
|
}
|
|
4295
|
-
onUserConsoleLog(
|
|
4296
|
-
if (
|
|
4297
|
-
const test2 = this.ctx?.state.idMap.get(
|
|
4233
|
+
onUserConsoleLog(log10) {
|
|
4234
|
+
if (log10.taskId) {
|
|
4235
|
+
const test2 = this.ctx?.state.idMap.get(log10.taskId);
|
|
4298
4236
|
if (test2) {
|
|
4299
4237
|
test2.name;
|
|
4300
4238
|
}
|
|
4301
4239
|
}
|
|
4302
|
-
this.logs.push(
|
|
4240
|
+
this.logs.push(log10.content.trimEnd());
|
|
4303
4241
|
}
|
|
4304
4242
|
runningTask(tasks) {
|
|
4305
4243
|
return tasks.find((t) => t.result?.state === "run");
|
|
@@ -4363,7 +4301,7 @@ var startTest = async (props) => {
|
|
|
4363
4301
|
};
|
|
4364
4302
|
|
|
4365
4303
|
// src/cli/ui/complex/run-tests.ts
|
|
4366
|
-
import { log as
|
|
4304
|
+
import { log as log8 } from "@clack/prompts";
|
|
4367
4305
|
import chalk6 from "chalk";
|
|
4368
4306
|
var formatResult = (props) => {
|
|
4369
4307
|
const line = [`Test ${chalk6.magenta(props.stack)}`];
|
|
@@ -4380,10 +4318,10 @@ var formatResult = (props) => {
|
|
|
4380
4318
|
};
|
|
4381
4319
|
var logTestLogs = (event) => {
|
|
4382
4320
|
if (event.logs.length > 0) {
|
|
4383
|
-
|
|
4321
|
+
log8.message(color.info.bold.inverse(" LOGS "), {
|
|
4384
4322
|
symbol: color.dim(icon.dot)
|
|
4385
4323
|
});
|
|
4386
|
-
|
|
4324
|
+
log8.message(event.logs.map((log10) => wrap(log10, { hard: true })).join("\n"));
|
|
4387
4325
|
}
|
|
4388
4326
|
};
|
|
4389
4327
|
var logTestErrors = (event) => {
|
|
@@ -4394,7 +4332,7 @@ var logTestErrors = (event) => {
|
|
|
4394
4332
|
message,
|
|
4395
4333
|
comment.length > 0 ? color.dim(`//${comment}`) : ""
|
|
4396
4334
|
].join(" ");
|
|
4397
|
-
|
|
4335
|
+
log8.message(
|
|
4398
4336
|
[
|
|
4399
4337
|
//
|
|
4400
4338
|
color.error.inverse.bold(` FAIL `),
|
|
@@ -4427,7 +4365,7 @@ var runTest = async (stack, dir, filters) => {
|
|
|
4427
4365
|
const raw = await readFile6(file, { encoding: "utf8" });
|
|
4428
4366
|
const data = JSON.parse(raw);
|
|
4429
4367
|
if (data.fingerprint === fingerprint) {
|
|
4430
|
-
|
|
4368
|
+
log8.step(
|
|
4431
4369
|
formatResult({
|
|
4432
4370
|
stack,
|
|
4433
4371
|
cached: true,
|
|
@@ -4515,7 +4453,7 @@ var deploy = (program2) => {
|
|
|
4515
4453
|
}
|
|
4516
4454
|
await buildAssets(builders);
|
|
4517
4455
|
const workspace = new WorkSpace2({
|
|
4518
|
-
stateProvider: new aws19.dynamodb.
|
|
4456
|
+
stateProvider: new aws19.dynamodb.StateProvider({
|
|
4519
4457
|
credentials,
|
|
4520
4458
|
region,
|
|
4521
4459
|
tableName: "awsless-state"
|
|
@@ -4526,26 +4464,8 @@ var deploy = (program2) => {
|
|
|
4526
4464
|
timeout: minutes5(60)
|
|
4527
4465
|
})
|
|
4528
4466
|
});
|
|
4529
|
-
const graph = {};
|
|
4530
|
-
for (const stack of app.stacks) {
|
|
4531
|
-
const deps = [];
|
|
4532
|
-
if (stack.name !== "base") {
|
|
4533
|
-
deps.push("base");
|
|
4534
|
-
}
|
|
4535
|
-
graph[stack.name] = [
|
|
4536
|
-
...deps,
|
|
4537
|
-
async () => {
|
|
4538
|
-
await workspace.deployStack(stack);
|
|
4539
|
-
}
|
|
4540
|
-
];
|
|
4541
|
-
}
|
|
4542
4467
|
await task("Deploying the stacks to AWS", async (update) => {
|
|
4543
|
-
|
|
4544
|
-
for (const result of results) {
|
|
4545
|
-
if (result.status === "rejected") {
|
|
4546
|
-
throw result.reason;
|
|
4547
|
-
}
|
|
4548
|
-
}
|
|
4468
|
+
await workspace.deployApp(app);
|
|
4549
4469
|
update("Done deploying the stacks to AWS.");
|
|
4550
4470
|
});
|
|
4551
4471
|
return "Your app is ready!";
|
|
@@ -4623,7 +4543,7 @@ var diff = (program2) => {
|
|
|
4623
4543
|
};
|
|
4624
4544
|
|
|
4625
4545
|
// src/cli/ui/complex/build-types.ts
|
|
4626
|
-
import { log as
|
|
4546
|
+
import { log as log9 } from "@clack/prompts";
|
|
4627
4547
|
|
|
4628
4548
|
// src/type-gen/generate.ts
|
|
4629
4549
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
@@ -4657,7 +4577,7 @@ var generateTypes = async (props) => {
|
|
|
4657
4577
|
// src/cli/ui/complex/build-types.ts
|
|
4658
4578
|
var buildTypes = async (props) => {
|
|
4659
4579
|
await generateTypes(props);
|
|
4660
|
-
|
|
4580
|
+
log9.step("Done generating type definition files.");
|
|
4661
4581
|
};
|
|
4662
4582
|
|
|
4663
4583
|
// src/cli/command/types.ts
|