@awsless/cli 0.1.14 → 0.1.15
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 +98 -83
- package/package.json +13 -13
package/dist/bin.js
CHANGED
|
@@ -149982,6 +149982,7 @@ var preflightDeployment = async (props) => {
|
|
|
149982
149982
|
}
|
|
149983
149983
|
};
|
|
149984
149984
|
var promoteDeployment = async (props) => {
|
|
149985
|
+
const stores = props.stores ?? [];
|
|
149985
149986
|
const deployment = await getDeployment(props.dynamo, props.appId, props.id);
|
|
149986
149987
|
const functionVersion = deployment?.functionVersion;
|
|
149987
149988
|
if (!deployment) {
|
|
@@ -149990,13 +149991,19 @@ var promoteDeployment = async (props) => {
|
|
|
149990
149991
|
if (!functionVersion) {
|
|
149991
149992
|
throw new ExpectedError(`Deployment "${props.id}" hasn't finished deploying.`);
|
|
149992
149993
|
}
|
|
149993
|
-
|
|
149994
|
-
|
|
149994
|
+
for (const store of stores) {
|
|
149995
|
+
if (store.deployment.functionVersion !== functionVersion) {
|
|
149996
|
+
throw new ExpectedError(`The routes don't share the deployed function version.`);
|
|
149997
|
+
}
|
|
149995
149998
|
}
|
|
149996
149999
|
const alias = await getLambdaAlias(props.lambda, props.functionName, LIVE_LAMBDA_ALIAS);
|
|
149997
150000
|
const liveId = alias?.Description || undefined;
|
|
149998
|
-
const
|
|
149999
|
-
const
|
|
150001
|
+
const activeRoutes = new Map;
|
|
150002
|
+
for (const store of stores) {
|
|
150003
|
+
const activeId = await readActiveDeploymentId(props.kvs, store.arn);
|
|
150004
|
+
const active = activeId !== undefined ? await readRouteDeployment(props.kvs, store.arn, activeId) : undefined;
|
|
150005
|
+
activeRoutes.set(store.arn, active);
|
|
150006
|
+
}
|
|
150000
150007
|
if (props.rejectStale && liveId && liveId !== props.id) {
|
|
150001
150008
|
const live = await getDeployment(props.dynamo, props.appId, liveId);
|
|
150002
150009
|
if (live?.promotedAt && live.promotedAt > deployment.createdAt) {
|
|
@@ -150014,8 +150021,8 @@ var promoteDeployment = async (props) => {
|
|
|
150014
150021
|
}
|
|
150015
150022
|
throw error3;
|
|
150016
150023
|
}
|
|
150017
|
-
let routesUpdateStarted = false;
|
|
150018
150024
|
let aliasUpdateStarted = false;
|
|
150025
|
+
const flippedStores = [];
|
|
150019
150026
|
const flipped = [];
|
|
150020
150027
|
try {
|
|
150021
150028
|
for (const name of await listLambdaFunctions(props.lambda, getAppNamePrefix(props.appName))) {
|
|
@@ -150042,9 +150049,11 @@ var promoteDeployment = async (props) => {
|
|
|
150042
150049
|
description: props.id
|
|
150043
150050
|
});
|
|
150044
150051
|
}
|
|
150045
|
-
|
|
150046
|
-
|
|
150047
|
-
|
|
150052
|
+
for (const store of stores) {
|
|
150053
|
+
if (activeRoutes.get(store.arn)?.id !== store.deployment.id) {
|
|
150054
|
+
flippedStores.push(store);
|
|
150055
|
+
await setActiveRouteDeployment(props.kvs, store.arn, store.deployment);
|
|
150056
|
+
}
|
|
150048
150057
|
}
|
|
150049
150058
|
if (alias?.FunctionVersion !== functionVersion || alias?.Description !== props.id) {
|
|
150050
150059
|
aliasUpdateStarted = true;
|
|
@@ -150058,7 +150067,7 @@ var promoteDeployment = async (props) => {
|
|
|
150058
150067
|
await markPromoted(props.dynamo, props.appId, props.id);
|
|
150059
150068
|
} catch (error3) {
|
|
150060
150069
|
const rollback = [
|
|
150061
|
-
...
|
|
150070
|
+
...flippedStores.map((store) => setActiveRouteDeployment(props.kvs, store.arn, activeRoutes.get(store.arn))),
|
|
150062
150071
|
...aliasUpdateStarted && alias?.FunctionVersion ? [
|
|
150063
150072
|
upsertLambdaAlias(props.lambda, {
|
|
150064
150073
|
functionName: props.functionName,
|
|
@@ -150092,21 +150101,21 @@ var activateDeployment = async (props) => {
|
|
|
150092
150101
|
const dynamo = new DynamoDBClient({ credentials: credentials2, region });
|
|
150093
150102
|
const functionName = getBundleFunctionName(props.appConfig.name);
|
|
150094
150103
|
const id = props.id ?? await previousDeploymentId({ lambda, dynamo, appId, functionName });
|
|
150095
|
-
|
|
150096
|
-
|
|
150104
|
+
const stores = [];
|
|
150105
|
+
for (const routerId of Object.keys(props.appConfig.router ?? {})) {
|
|
150097
150106
|
const storeArn = await getRouteStoreArn(cloudfront, formatGlobalResourceName({
|
|
150098
150107
|
appName: props.appConfig.name,
|
|
150099
150108
|
resourceType: "router",
|
|
150100
|
-
resourceName:
|
|
150109
|
+
resourceName: routerId
|
|
150101
150110
|
}));
|
|
150102
150111
|
if (!storeArn) {
|
|
150103
|
-
throw new ExpectedError(`The router hasn't been deployed yet. Run "awsless deploy" first.`);
|
|
150112
|
+
throw new ExpectedError(`The "${routerId}" router hasn't been deployed yet. Run "awsless deploy" first.`);
|
|
150104
150113
|
}
|
|
150105
150114
|
const routes = await readRouteDeployment(kvs, storeArn, id);
|
|
150106
150115
|
if (!routes) {
|
|
150107
|
-
throw new ExpectedError(`Deployment "${id}" doesn't exist.`);
|
|
150116
|
+
throw new ExpectedError(`Deployment "${id}" doesn't exist for the "${routerId}" router.`);
|
|
150108
150117
|
}
|
|
150109
|
-
|
|
150118
|
+
stores.push({ arn: storeArn, deployment: routes });
|
|
150110
150119
|
}
|
|
150111
150120
|
await promoteDeployment({
|
|
150112
150121
|
kvs,
|
|
@@ -150116,7 +150125,7 @@ var activateDeployment = async (props) => {
|
|
|
150116
150125
|
appName: props.appConfig.name,
|
|
150117
150126
|
functionName,
|
|
150118
150127
|
id,
|
|
150119
|
-
|
|
150128
|
+
stores,
|
|
150120
150129
|
rejectStale: props.rejectStale
|
|
150121
150130
|
});
|
|
150122
150131
|
return id;
|
|
@@ -162683,39 +162692,30 @@ var routerFeature = defineFeature({
|
|
|
162683
162692
|
name: "router",
|
|
162684
162693
|
onApp(ctx) {
|
|
162685
162694
|
const routers = Object.entries(ctx.appConfig.router ?? {});
|
|
162686
|
-
const defaultRouter = routers[0]?.[0];
|
|
162687
162695
|
const routes = {};
|
|
162688
|
-
const routeDependencies =
|
|
162696
|
+
const routeDependencies = {};
|
|
162697
|
+
const routeStores = {};
|
|
162698
|
+
const routerGroups = {};
|
|
162689
162699
|
const distributionIds = [];
|
|
162690
162700
|
let hasLambdaRoutes = false;
|
|
162691
|
-
let routeStore;
|
|
162692
|
-
let sharedGroup;
|
|
162693
|
-
if (routers.length > 0) {
|
|
162694
|
-
const storeName = formatGlobalResourceName({
|
|
162695
|
-
appName: ctx.app.name,
|
|
162696
|
-
resourceType: "router",
|
|
162697
|
-
resourceName: "store"
|
|
162698
|
-
});
|
|
162699
|
-
sharedGroup = new Group(ctx.base, "router", "shared");
|
|
162700
|
-
routeStore = new aws2.cloudfront.KeyValueStore(sharedGroup, "routes", {
|
|
162701
|
-
name: storeName,
|
|
162702
|
-
comment: "Store for routes"
|
|
162703
|
-
}, {
|
|
162704
|
-
replaceOnChanges: ["name"],
|
|
162705
|
-
createBeforeReplace: true,
|
|
162706
|
-
import: ctx.import ? storeName : undefined
|
|
162707
|
-
});
|
|
162708
|
-
}
|
|
162709
162701
|
for (const [id, props] of routers) {
|
|
162710
162702
|
const group4 = new Group(ctx.base, "router", id);
|
|
162703
|
+
routerGroups[id] = group4;
|
|
162704
|
+
routes[id] = {};
|
|
162705
|
+
routeDependencies[id] = new Set;
|
|
162711
162706
|
const name = formatGlobalResourceName({
|
|
162712
162707
|
appName: ctx.app.name,
|
|
162713
162708
|
resourceType: "router",
|
|
162714
162709
|
resourceName: id
|
|
162715
162710
|
});
|
|
162716
|
-
const
|
|
162717
|
-
|
|
162718
|
-
|
|
162711
|
+
const routeStore = new aws2.cloudfront.KeyValueStore(group4, "routes", { name }, {
|
|
162712
|
+
replaceOnChanges: ["name"],
|
|
162713
|
+
createBeforeReplace: true,
|
|
162714
|
+
import: ctx.import ? name : undefined
|
|
162715
|
+
});
|
|
162716
|
+
routeStores[id] = routeStore;
|
|
162717
|
+
const cfFunction = new aws2.cloudfront.Function(group4, "function", {
|
|
162718
|
+
name,
|
|
162719
162719
|
runtime: "cloudfront-js-2.0",
|
|
162720
162720
|
code: getViewerRequestFunctionCode({
|
|
162721
162721
|
router: id,
|
|
@@ -162727,18 +162727,19 @@ var routerFeature = defineFeature({
|
|
|
162727
162727
|
publish: true,
|
|
162728
162728
|
keyValueStoreAssociations: [routeStore.arn]
|
|
162729
162729
|
}, {
|
|
162730
|
-
import: ctx.import ?
|
|
162730
|
+
import: ctx.import ? name : undefined
|
|
162731
162731
|
});
|
|
162732
162732
|
ctx.shared.add("router", "addRoutes", id, (newRoutes, options) => {
|
|
162733
|
+
const routerRoutes = routes[id];
|
|
162733
162734
|
for (const [key, route] of Object.entries(newRoutes)) {
|
|
162734
|
-
if (Object.hasOwn(
|
|
162735
|
+
if (Object.hasOwn(routerRoutes, `${id}:${key}`)) {
|
|
162735
162736
|
throw new ExpectedError(`Duplicate route key: ${key} in the "${id}" router`);
|
|
162736
162737
|
}
|
|
162737
162738
|
assertRouteValueSize(`${id}:${key}`, route);
|
|
162738
|
-
|
|
162739
|
+
routerRoutes[`${id}:${key}`] = route;
|
|
162739
162740
|
}
|
|
162740
162741
|
for (const dependency of options?.dependsOn ?? []) {
|
|
162741
|
-
routeDependencies.add(dependency);
|
|
162742
|
+
routeDependencies[id].add(dependency);
|
|
162742
162743
|
}
|
|
162743
162744
|
if (Object.values(newRoutes).flat().some((route) => route.type === "lambda" && !route.domainName)) {
|
|
162744
162745
|
hasLambdaRoutes = true;
|
|
@@ -163001,7 +163002,7 @@ var routerFeature = defineFeature({
|
|
|
163001
163002
|
functionAssociation: [
|
|
163002
163003
|
{
|
|
163003
163004
|
eventType: "viewer-request",
|
|
163004
|
-
functionArn:
|
|
163005
|
+
functionArn: cfFunction.arn
|
|
163005
163006
|
}
|
|
163006
163007
|
],
|
|
163007
163008
|
originRequestPolicyId: originRequest.id,
|
|
@@ -163018,38 +163019,6 @@ var routerFeature = defineFeature({
|
|
|
163018
163019
|
],
|
|
163019
163020
|
webAclId: waf?.arn
|
|
163020
163021
|
});
|
|
163021
|
-
if (id === defaultRouter) {
|
|
163022
|
-
ctx.onReadyLast(() => {
|
|
163023
|
-
const bundle = ctx.shared.get("bundle", "main");
|
|
163024
|
-
let lambdaUrlHost;
|
|
163025
|
-
if (hasLambdaRoutes) {
|
|
163026
|
-
const deployment = new FunctionDeployment(sharedGroup, "function-deployment", {
|
|
163027
|
-
functionName: bundle.lambda.functionName,
|
|
163028
|
-
id: ctx.deploymentId ?? "local-0",
|
|
163029
|
-
sourceArns: distributionIds.map((distributionId) => distributionId.pipe((id2) => `arn:aws:cloudfront::${ctx.accountId}:distribution/${id2}`))
|
|
163030
|
-
}, {
|
|
163031
|
-
dependsOn: [bundle.deployment]
|
|
163032
|
-
});
|
|
163033
|
-
lambdaUrlHost = deployment.url.pipe((url) => url.split("/")[2]);
|
|
163034
|
-
routeDependencies.add(bundle.policy);
|
|
163035
|
-
routeDependencies.add(bundle.alias);
|
|
163036
|
-
routeDependencies.add(deployment);
|
|
163037
|
-
}
|
|
163038
|
-
new RouteDeployment(sharedGroup, "deployment", {
|
|
163039
|
-
deploymentId: ctx.deploymentId ?? "local-0",
|
|
163040
|
-
storeArn: routeStore.arn,
|
|
163041
|
-
functionVersion: bundle.lambda.version,
|
|
163042
|
-
routes: $resolve([routes, lambdaUrlHost], (routes2, lambdaUrlHost2) => {
|
|
163043
|
-
const withOrigin = (route) => {
|
|
163044
|
-
return route.type === "lambda" && !route.domainName ? { ...route, domainName: lambdaUrlHost2 } : route;
|
|
163045
|
-
};
|
|
163046
|
-
return Object.entries(routes2).flatMap(([key, route]) => createRouteStoreEntries(key, Array.isArray(route) ? route.map(withOrigin) : withOrigin(route)));
|
|
163047
|
-
})
|
|
163048
|
-
}, {
|
|
163049
|
-
dependsOn: Array.from(routeDependencies)
|
|
163050
|
-
});
|
|
163051
|
-
});
|
|
163052
|
-
}
|
|
163053
163022
|
ctx.shared.add("router", "id", id, distribution.id);
|
|
163054
163023
|
distributionIds.push(distribution.id);
|
|
163055
163024
|
if (props.domain) {
|
|
@@ -163105,6 +163074,44 @@ var routerFeature = defineFeature({
|
|
|
163105
163074
|
ctx.shared.add("router", "endpoint", id, domainName);
|
|
163106
163075
|
}
|
|
163107
163076
|
}
|
|
163077
|
+
if (routers.length > 0) {
|
|
163078
|
+
ctx.onReadyLast(() => {
|
|
163079
|
+
const bundle = ctx.shared.get("bundle", "main");
|
|
163080
|
+
const sharedDependencies = [];
|
|
163081
|
+
let lambdaUrlHost;
|
|
163082
|
+
if (hasLambdaRoutes) {
|
|
163083
|
+
const sharedGroup = new Group(ctx.base, "router", "shared");
|
|
163084
|
+
const deployment = new FunctionDeployment(sharedGroup, "function-deployment", {
|
|
163085
|
+
functionName: bundle.lambda.functionName,
|
|
163086
|
+
id: ctx.deploymentId ?? "local-0",
|
|
163087
|
+
sourceArns: distributionIds.map((distributionId) => distributionId.pipe((id) => `arn:aws:cloudfront::${ctx.accountId}:distribution/${id}`))
|
|
163088
|
+
}, {
|
|
163089
|
+
dependsOn: [bundle.deployment]
|
|
163090
|
+
});
|
|
163091
|
+
lambdaUrlHost = deployment.url.pipe((url) => url.split("/")[2]);
|
|
163092
|
+
sharedDependencies.push(bundle.policy, bundle.alias, deployment);
|
|
163093
|
+
}
|
|
163094
|
+
for (const [id] of routers) {
|
|
163095
|
+
const dependencies = routeDependencies[id];
|
|
163096
|
+
for (const dependency of sharedDependencies) {
|
|
163097
|
+
dependencies.add(dependency);
|
|
163098
|
+
}
|
|
163099
|
+
new RouteDeployment(routerGroups[id], "deployment", {
|
|
163100
|
+
deploymentId: ctx.deploymentId ?? "local-0",
|
|
163101
|
+
storeArn: routeStores[id].arn,
|
|
163102
|
+
functionVersion: bundle.lambda.version,
|
|
163103
|
+
routes: $resolve([routes[id], lambdaUrlHost], (routes2, lambdaUrlHost2) => {
|
|
163104
|
+
const withOrigin = (route) => {
|
|
163105
|
+
return route.type === "lambda" && !route.domainName ? { ...route, domainName: lambdaUrlHost2 } : route;
|
|
163106
|
+
};
|
|
163107
|
+
return Object.entries(routes2).flatMap(([key, route]) => createRouteStoreEntries(key, Array.isArray(route) ? route.map(withOrigin) : withOrigin(route)));
|
|
163108
|
+
})
|
|
163109
|
+
}, {
|
|
163110
|
+
dependsOn: Array.from(dependencies)
|
|
163111
|
+
});
|
|
163112
|
+
}
|
|
163113
|
+
});
|
|
163114
|
+
}
|
|
163108
163115
|
},
|
|
163109
163116
|
onStack(ctx) {
|
|
163110
163117
|
for (const [id, patterns] of Object.entries(ctx.stackConfig.routes ?? {})) {
|
|
@@ -187353,13 +187360,21 @@ var prune = (program3) => {
|
|
|
187353
187360
|
await pruneFunctionVersion(lambda, name, version2);
|
|
187354
187361
|
}
|
|
187355
187362
|
}
|
|
187356
|
-
const
|
|
187357
|
-
|
|
187358
|
-
|
|
187359
|
-
|
|
187360
|
-
|
|
187361
|
-
|
|
187362
|
-
|
|
187363
|
+
const survivingRoutes = [];
|
|
187364
|
+
let sweptStores = false;
|
|
187365
|
+
for (const routerId of Object.keys(appConfig.router ?? {})) {
|
|
187366
|
+
const storeArn = await getRouteStoreArn(cloudfront, formatGlobalResourceName({
|
|
187367
|
+
appName: appConfig.name,
|
|
187368
|
+
resourceType: "router",
|
|
187369
|
+
resourceName: routerId
|
|
187370
|
+
}));
|
|
187371
|
+
if (!storeArn) {
|
|
187372
|
+
continue;
|
|
187373
|
+
}
|
|
187374
|
+
sweptStores = true;
|
|
187375
|
+
survivingRoutes.push(...await pruneStoreDeployments(kvs, storeArn, prune2.map((item) => item.id)));
|
|
187376
|
+
}
|
|
187377
|
+
if (sweptStores) {
|
|
187363
187378
|
await pruneSiteVersions({
|
|
187364
187379
|
s3,
|
|
187365
187380
|
bucket: formatGlobalResourceName({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awsless/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -43,14 +43,14 @@
|
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"@awsless/big-float": "^0.1.7",
|
|
46
|
+
"@awsless/json": "^0.0.11",
|
|
46
47
|
"@awsless/duration": "^0.0.4",
|
|
47
48
|
"@awsless/dynamodb": "^0.3.25",
|
|
48
|
-
"@awsless/json": "^0.0.11",
|
|
49
49
|
"@awsless/lambda": "^0.0.48",
|
|
50
|
-
"@awsless/
|
|
50
|
+
"@awsless/s3": "^0.0.22",
|
|
51
51
|
"@awsless/weak-cache": "^0.0.1",
|
|
52
|
-
"awsless": "^0.
|
|
53
|
-
"
|
|
52
|
+
"@awsless/validate": "^0.2.0",
|
|
53
|
+
"awsless": "^0.1.4"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@aws-sdk/client-cloudformation": "^3.369.0",
|
|
@@ -110,23 +110,23 @@
|
|
|
110
110
|
"zod-to-json-schema": "^3.24.3",
|
|
111
111
|
"@awsless/cloudwatch": "^0.0.1",
|
|
112
112
|
"@awsless/big-float": "^0.1.7",
|
|
113
|
-
"@awsless/clui": "^0.0.9",
|
|
114
|
-
"@awsless/duration": "^0.0.4",
|
|
115
113
|
"@awsless/dynamodb": "^0.3.25",
|
|
116
|
-
"@awsless/iot": "^0.0.5",
|
|
117
114
|
"@awsless/json": "^0.0.11",
|
|
118
115
|
"@awsless/lambda": "^0.0.48",
|
|
119
|
-
"@awsless/
|
|
116
|
+
"@awsless/iot": "^0.0.5",
|
|
117
|
+
"@awsless/duration": "^0.0.4",
|
|
120
118
|
"@awsless/redis": "^0.1.13",
|
|
119
|
+
"@awsless/clui": "^0.0.9",
|
|
121
120
|
"@awsless/s3": "^0.0.22",
|
|
122
121
|
"@awsless/scheduler": "^0.0.5",
|
|
123
122
|
"@awsless/size": "^0.0.2",
|
|
124
|
-
"@awsless/sns": "^0.0.11",
|
|
125
|
-
"@awsless/ssm": "^0.0.8",
|
|
126
|
-
"@awsless/weak-cache": "^0.0.1",
|
|
127
123
|
"@awsless/sqs": "^0.0.24",
|
|
124
|
+
"@awsless/open-search": "^0.0.28",
|
|
125
|
+
"@awsless/validate": "^0.2.0",
|
|
126
|
+
"@awsless/ssm": "^0.0.8",
|
|
127
|
+
"@awsless/sns": "^0.0.11",
|
|
128
128
|
"awsless": "^0.1.4",
|
|
129
|
-
"@awsless/
|
|
129
|
+
"@awsless/weak-cache": "^0.0.1"
|
|
130
130
|
},
|
|
131
131
|
"scripts": {
|
|
132
132
|
"test": "bun cli/build-handlers.ts && pnpm vitest",
|