@awsless/cli 0.0.46-next.2 → 0.0.46-next.4
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 +145 -109
- package/package.json +9 -9
package/dist/bin.js
CHANGED
|
@@ -173,7 +173,7 @@ import { DynamoDBClient as DynamoDBClient2, migrate } from "@awsless/dynamodb";
|
|
|
173
173
|
// src/util/deployment.ts
|
|
174
174
|
import { CloudFrontClient as CloudFrontClient2 } from "@aws-sdk/client-cloudfront";
|
|
175
175
|
import { CloudFrontKeyValueStoreClient as CloudFrontKeyValueStoreClient2 } from "@aws-sdk/client-cloudfront-keyvaluestore";
|
|
176
|
-
import { GetFunctionCommand, LambdaClient as LambdaClient3 } from "@aws-sdk/client-lambda";
|
|
176
|
+
import { DeleteFunctionCommand, GetFunctionCommand, LambdaClient as LambdaClient3 } from "@aws-sdk/client-lambda";
|
|
177
177
|
import {
|
|
178
178
|
define,
|
|
179
179
|
deleteItem,
|
|
@@ -366,6 +366,7 @@ import {
|
|
|
366
366
|
DeleteFunctionUrlConfigCommand,
|
|
367
367
|
GetAliasCommand,
|
|
368
368
|
LambdaClient,
|
|
369
|
+
ListAliasesCommand,
|
|
369
370
|
UpdateAliasCommand,
|
|
370
371
|
UpdateFunctionCodeCommand
|
|
371
372
|
} from "@aws-sdk/client-lambda";
|
|
@@ -386,6 +387,22 @@ var getLambdaAlias = async (lambda, functionName, name) => {
|
|
|
386
387
|
return;
|
|
387
388
|
}
|
|
388
389
|
};
|
|
390
|
+
var listLambdaAliases = async (lambda, functionName, functionVersion) => {
|
|
391
|
+
const aliases = [];
|
|
392
|
+
let marker;
|
|
393
|
+
do {
|
|
394
|
+
const result = await lambda.send(
|
|
395
|
+
new ListAliasesCommand({
|
|
396
|
+
FunctionName: functionName,
|
|
397
|
+
FunctionVersion: functionVersion,
|
|
398
|
+
Marker: marker
|
|
399
|
+
})
|
|
400
|
+
);
|
|
401
|
+
aliases.push(...result.Aliases ?? []);
|
|
402
|
+
marker = result.NextMarker;
|
|
403
|
+
} while (marker);
|
|
404
|
+
return aliases;
|
|
405
|
+
};
|
|
389
406
|
var upsertLambdaAlias = async (lambda, props) => {
|
|
390
407
|
const input = {
|
|
391
408
|
FunctionName: props.functionName,
|
|
@@ -809,17 +826,18 @@ var createLambdaProvider = ({ credentials, region }) => {
|
|
|
809
826
|
await configureVersion(proposed);
|
|
810
827
|
const url = await createDeploymentUrl(proposed.functionName, deploymentAlias, proposed.sourceAccount);
|
|
811
828
|
if (proposed.sourceAccount && prior.sourceAccount !== proposed.sourceAccount) {
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
829
|
+
for (const name of deploymentAliases) {
|
|
830
|
+
if (name === deploymentAlias) {
|
|
831
|
+
continue;
|
|
832
|
+
}
|
|
833
|
+
try {
|
|
834
|
+
await createDeploymentUrl(proposed.functionName, name, proposed.sourceAccount);
|
|
835
|
+
} catch (error) {
|
|
836
|
+
if (!isError(error, "ResourceNotFoundException")) {
|
|
837
|
+
throw error;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
823
841
|
}
|
|
824
842
|
return {
|
|
825
843
|
...proposed,
|
|
@@ -1310,6 +1328,60 @@ var markPromoted = async (client, appId, id) => {
|
|
|
1310
1328
|
var removeDeployment = async (client, appId, id) => {
|
|
1311
1329
|
await deleteItem(table, { appId, id }, { client });
|
|
1312
1330
|
};
|
|
1331
|
+
var selectPrunableDeployments = (items, liveId, options) => {
|
|
1332
|
+
const rollbackTarget = items.filter((item) => item.promotedAt && item.id !== liveId).sort((a, b) => b.promotedAt.localeCompare(a.promotedAt))[0];
|
|
1333
|
+
const keep = Math.max(1, Number(options.keep) || 10);
|
|
1334
|
+
const mainSlug = slugifyBranch(options.main);
|
|
1335
|
+
const keptMain = new Set(
|
|
1336
|
+
items.filter((item) => item.branch === mainSlug && item.functionVersion).map((item) => item.seq).sort((a, b) => b - a).slice(0, keep)
|
|
1337
|
+
);
|
|
1338
|
+
const dayAgo = new Date(Date.now() - 24 * 60 * 60 * 1e3).toISOString();
|
|
1339
|
+
return items.filter((item) => {
|
|
1340
|
+
if (item.id === liveId || item.id === rollbackTarget?.id) {
|
|
1341
|
+
return false;
|
|
1342
|
+
}
|
|
1343
|
+
if (options.branch) {
|
|
1344
|
+
return item.branch === slugifyBranch(options.branch);
|
|
1345
|
+
}
|
|
1346
|
+
if (!item.functionVersion) {
|
|
1347
|
+
return item.createdAt < dayAgo;
|
|
1348
|
+
}
|
|
1349
|
+
if (item.branch === mainSlug) {
|
|
1350
|
+
return !keptMain.has(item.seq);
|
|
1351
|
+
}
|
|
1352
|
+
return item.commit ? isCommitMerged(item.commit, options.main) : false;
|
|
1353
|
+
});
|
|
1354
|
+
};
|
|
1355
|
+
var pruneFunctionVersion = async (lambda, functionName, version) => {
|
|
1356
|
+
for (const alias of await listLambdaAliases(lambda, functionName, version)) {
|
|
1357
|
+
if (alias.Name && alias.Name !== LIVE_LAMBDA_ALIAS) {
|
|
1358
|
+
await deleteLambdaAlias(lambda, functionName, alias.Name);
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
try {
|
|
1362
|
+
await lambda.send(
|
|
1363
|
+
new DeleteFunctionCommand({
|
|
1364
|
+
FunctionName: functionName,
|
|
1365
|
+
Qualifier: version
|
|
1366
|
+
})
|
|
1367
|
+
);
|
|
1368
|
+
} catch (error) {
|
|
1369
|
+
if (!isError(error, "ResourceNotFoundException")) {
|
|
1370
|
+
throw error;
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
};
|
|
1374
|
+
var selectPrunableVersions = async (props) => {
|
|
1375
|
+
const surviving = props.items.filter((item) => !props.prunable.includes(item));
|
|
1376
|
+
const kept = new Set(surviving.map((item) => item.functionVersion));
|
|
1377
|
+
const live = await getLambdaAlias(props.lambda, props.functionName, LIVE_LAMBDA_ALIAS);
|
|
1378
|
+
if (live?.FunctionVersion) {
|
|
1379
|
+
kept.add(live.FunctionVersion);
|
|
1380
|
+
}
|
|
1381
|
+
return new Set(
|
|
1382
|
+
props.prunable.map((item) => item.functionVersion).filter((version) => Boolean(version && !kept.has(version)))
|
|
1383
|
+
);
|
|
1384
|
+
};
|
|
1313
1385
|
var readLiveDeploymentId = async (lambda, functionName) => {
|
|
1314
1386
|
return (await getLambdaAlias(lambda, functionName, LIVE_LAMBDA_ALIAS))?.Description || void 0;
|
|
1315
1387
|
};
|
|
@@ -1326,17 +1398,21 @@ var readDeployedFunctionVersion = (state2) => {
|
|
|
1326
1398
|
return;
|
|
1327
1399
|
};
|
|
1328
1400
|
var formatDeploymentSummary = (props) => {
|
|
1329
|
-
|
|
1401
|
+
const previewUrls = /* @__PURE__ */ new Map();
|
|
1330
1402
|
for (const [urn, node] of readStateNodes(props.state)) {
|
|
1331
1403
|
if (node.type === "aws_cloudfront_distribution" && urn.endsWith(":{preview}")) {
|
|
1332
|
-
|
|
1404
|
+
const router = urn.match(/router:\{([^}]+)\}/)?.[1];
|
|
1405
|
+
if (router) {
|
|
1406
|
+
previewUrls.set(router, `https://${node.output.domainName}`);
|
|
1407
|
+
}
|
|
1333
1408
|
}
|
|
1334
1409
|
}
|
|
1335
|
-
return Object.keys(props.appConfig.defaults.router ?? {}).map((routerId
|
|
1410
|
+
return Object.keys(props.appConfig.defaults.router ?? {}).map((routerId) => {
|
|
1411
|
+
const previewUrl = previewUrls.get(routerId);
|
|
1336
1412
|
return [
|
|
1337
1413
|
`${routerId}: deployment #${props.id}`,
|
|
1338
|
-
|
|
1339
|
-
|
|
1414
|
+
previewUrl,
|
|
1415
|
+
previewUrl ? `${previewUrl}/?awsless-deployment=${props.id}` : void 0
|
|
1340
1416
|
].filter(Boolean).join("\n");
|
|
1341
1417
|
});
|
|
1342
1418
|
};
|
|
@@ -3900,25 +3976,10 @@ var bundleTypeScriptWithRolldown = async ({
|
|
|
3900
3976
|
return importee.startsWith("@aws-sdk") || importee.startsWith("aws-sdk") || external?.includes(importee);
|
|
3901
3977
|
},
|
|
3902
3978
|
treeshake: {
|
|
3903
|
-
//
|
|
3904
|
-
//
|
|
3905
|
-
//
|
|
3906
|
-
|
|
3907
|
-
// side-effect free prunes those unused chains from production
|
|
3908
|
-
// bundles, while every other dependency keeps its import side
|
|
3909
|
-
// effects, like the fs patching of graceful-fs.
|
|
3910
|
-
moduleSideEffects: (id, isExternal) => {
|
|
3911
|
-
if (isExternal) {
|
|
3912
|
-
return external?.includes(id) === true;
|
|
3913
|
-
}
|
|
3914
|
-
if (id.includes("/node_modules/@awsless/")) {
|
|
3915
|
-
return false;
|
|
3916
|
-
}
|
|
3917
|
-
if (id.includes("/node_modules/")) {
|
|
3918
|
-
return true;
|
|
3919
|
-
}
|
|
3920
|
-
return id.startsWith(`${directories.root}/`);
|
|
3921
|
-
}
|
|
3979
|
+
// Dependencies are treated as side-effect free, so unused imports
|
|
3980
|
+
// like the local test servers never reach the production bundle.
|
|
3981
|
+
// The bundle guard below fails the build if one slips through.
|
|
3982
|
+
moduleSideEffects: (id, isExternal) => isExternal ? external?.includes(id) === true : id.startsWith(`${directories.root}/`) && !id.includes("/node_modules/")
|
|
3922
3983
|
},
|
|
3923
3984
|
onwarn: (error) => {
|
|
3924
3985
|
debugError(error.message);
|
|
@@ -4119,6 +4180,11 @@ var bundleFeature = defineFeature({
|
|
|
4119
4180
|
const addLayer = (layer) => {
|
|
4120
4181
|
layers.push(layer);
|
|
4121
4182
|
};
|
|
4183
|
+
const layerIds = Object.keys(ctx.appConfig.defaults.layers ?? {});
|
|
4184
|
+
const layerPackages = layerIds.flatMap((id) => ctx.shared.entry("layer", "packages", id));
|
|
4185
|
+
for (const id of layerIds) {
|
|
4186
|
+
addLayer(ctx.shared.entry("layer", "arn", id));
|
|
4187
|
+
}
|
|
4122
4188
|
const name = getBundleFunctionName(ctx.app.name);
|
|
4123
4189
|
const shortName = formatGlobalResourceName({
|
|
4124
4190
|
appName: ctx.app.name,
|
|
@@ -4132,7 +4198,7 @@ var bundleFeature = defineFeature({
|
|
|
4132
4198
|
name,
|
|
4133
4199
|
handlers,
|
|
4134
4200
|
minify: defaults.minify,
|
|
4135
|
-
external: defaults.external
|
|
4201
|
+
external: [...defaults.external ?? [], ...layerPackages]
|
|
4136
4202
|
})
|
|
4137
4203
|
);
|
|
4138
4204
|
const sourceHash = new Output3(envDeps, async (resolve2) => {
|
|
@@ -7004,14 +7070,15 @@ var siteFeature = defineFeature({
|
|
|
7004
7070
|
env,
|
|
7005
7071
|
stdout: "pipe",
|
|
7006
7072
|
stderr: "pipe"
|
|
7007
|
-
// stdout: 'ignore',
|
|
7008
|
-
// stderr: ''
|
|
7009
|
-
// stdout: 'inherit',
|
|
7010
|
-
// stderr: 'inherit',
|
|
7011
7073
|
});
|
|
7012
|
-
await
|
|
7074
|
+
const [output, errors] = await Promise.all([
|
|
7075
|
+
new Response(instance.stdout).text(),
|
|
7076
|
+
new Response(instance.stderr).text(),
|
|
7077
|
+
instance.exited
|
|
7078
|
+
]);
|
|
7013
7079
|
if (instance.exitCode !== null && instance.exitCode > 0) {
|
|
7014
|
-
throw new
|
|
7080
|
+
throw new ExpectedError(`Site build failed:
|
|
7081
|
+
${(errors.trim() || output.trim()).slice(-2e3)}`);
|
|
7015
7082
|
}
|
|
7016
7083
|
await write("HASH", fingerprint);
|
|
7017
7084
|
return {
|
|
@@ -9254,7 +9321,7 @@ var PASSWORD_AUTH_CHECK = (password) => `
|
|
|
9254
9321
|
authMethods.push('Password realm="Protected"');
|
|
9255
9322
|
|
|
9256
9323
|
if(!isAuthorized) {
|
|
9257
|
-
if(authHeader && authHeader.startsWith('Password ') && authHeader.slice(9) ===
|
|
9324
|
+
if(authHeader && authHeader.startsWith('Password ') && authHeader.slice(9) === ${JSON.stringify(password)}) {
|
|
9258
9325
|
isAuthorized = true;
|
|
9259
9326
|
}
|
|
9260
9327
|
}
|
|
@@ -9280,7 +9347,7 @@ try {
|
|
|
9280
9347
|
: { statusCode: 503, statusDescription: 'Service Unavailable' };
|
|
9281
9348
|
}
|
|
9282
9349
|
|
|
9283
|
-
if (request.querystring['awsless-deployment']) {
|
|
9350
|
+
if (deployment && request.querystring['awsless-deployment']) {
|
|
9284
9351
|
delete request.querystring['awsless-deployment'];
|
|
9285
9352
|
|
|
9286
9353
|
const query = [];
|
|
@@ -9289,8 +9356,9 @@ if (request.querystring['awsless-deployment']) {
|
|
|
9289
9356
|
const entry = request.querystring[key];
|
|
9290
9357
|
|
|
9291
9358
|
if (entry.multiValue) {
|
|
9292
|
-
|
|
9293
|
-
|
|
9359
|
+
// The CloudFront js runtime doesn't support for...of.
|
|
9360
|
+
for (const i in entry.multiValue) {
|
|
9361
|
+
query.push(key + '=' + entry.multiValue[i].value);
|
|
9294
9362
|
}
|
|
9295
9363
|
} else {
|
|
9296
9364
|
query.push(key + '=' + entry.value);
|
|
@@ -9584,7 +9652,6 @@ var routerFeature = defineFeature({
|
|
|
9584
9652
|
const distributionIds = [];
|
|
9585
9653
|
let hasLambdaRoutes = false;
|
|
9586
9654
|
let routeStore;
|
|
9587
|
-
let previewDistribution;
|
|
9588
9655
|
for (const [id, props] of routers) {
|
|
9589
9656
|
const group = new Group29(ctx.base, "router", id);
|
|
9590
9657
|
const name = formatGlobalResourceName({
|
|
@@ -9921,7 +9988,7 @@ var routerFeature = defineFeature({
|
|
|
9921
9988
|
],
|
|
9922
9989
|
webAclId: waf?.arn
|
|
9923
9990
|
});
|
|
9924
|
-
|
|
9991
|
+
{
|
|
9925
9992
|
const previewFunction = new aws30.cloudfront.Function(group, "preview-function", {
|
|
9926
9993
|
name: `${name.slice(0, 55)}--preview`,
|
|
9927
9994
|
runtime: "cloudfront-js-2.0",
|
|
@@ -9934,7 +10001,7 @@ var routerFeature = defineFeature({
|
|
|
9934
10001
|
publish: true,
|
|
9935
10002
|
keyValueStoreAssociations: [routeStore.arn]
|
|
9936
10003
|
});
|
|
9937
|
-
previewDistribution = new aws30.cloudfront.Distribution(group, "preview", {
|
|
10004
|
+
const previewDistribution = new aws30.cloudfront.Distribution(group, "preview", {
|
|
9938
10005
|
tags: {
|
|
9939
10006
|
name: `${name}-preview`
|
|
9940
10007
|
},
|
|
@@ -9998,6 +10065,9 @@ var routerFeature = defineFeature({
|
|
|
9998
10065
|
webAclId: waf?.arn
|
|
9999
10066
|
});
|
|
10000
10067
|
distributionIds.push(previewDistribution.id);
|
|
10068
|
+
ctx.shared.add("router", "preview-id", id, previewDistribution.id);
|
|
10069
|
+
}
|
|
10070
|
+
if (id === defaultRouter) {
|
|
10001
10071
|
ctx.onReadyLast(() => {
|
|
10002
10072
|
const bundle = ctx.shared.get("bundle", "main");
|
|
10003
10073
|
let lambdaUrlHost;
|
|
@@ -10039,7 +10109,6 @@ var routerFeature = defineFeature({
|
|
|
10039
10109
|
});
|
|
10040
10110
|
}
|
|
10041
10111
|
ctx.shared.add("router", "id", id, distribution.id);
|
|
10042
|
-
ctx.shared.add("router", "preview-id", id, previewDistribution.id);
|
|
10043
10112
|
distributionIds.push(distribution.id);
|
|
10044
10113
|
if (props.domain) {
|
|
10045
10114
|
const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
|
|
@@ -10783,6 +10852,7 @@ var buildAssets = async (builders, stackFilters, showResult = false) => {
|
|
|
10783
10852
|
if (filteredBuilders.length === 0) {
|
|
10784
10853
|
return;
|
|
10785
10854
|
}
|
|
10855
|
+
filteredBuilders.sort((a, b) => Number(a.type === "bundle") - Number(b.type === "bundle"));
|
|
10786
10856
|
const results = [];
|
|
10787
10857
|
await log10.task({
|
|
10788
10858
|
initialMessage: `Building assets...`,
|
|
@@ -11602,9 +11672,10 @@ var deploy = (program2) => {
|
|
|
11602
11672
|
}
|
|
11603
11673
|
});
|
|
11604
11674
|
playSuccessSound();
|
|
11605
|
-
const
|
|
11606
|
-
|
|
11607
|
-
|
|
11675
|
+
for (const summary of deployments2) {
|
|
11676
|
+
log20.message(summary);
|
|
11677
|
+
}
|
|
11678
|
+
return `Deployment #${deployment.id} is live.`;
|
|
11608
11679
|
});
|
|
11609
11680
|
});
|
|
11610
11681
|
};
|
|
@@ -12095,7 +12166,7 @@ var bind = (program2) => {
|
|
|
12095
12166
|
stderr: "inherit"
|
|
12096
12167
|
});
|
|
12097
12168
|
await instance.exited;
|
|
12098
|
-
process.exit(
|
|
12169
|
+
process.exit(instance.exitCode ?? 1);
|
|
12099
12170
|
});
|
|
12100
12171
|
});
|
|
12101
12172
|
};
|
|
@@ -12215,7 +12286,7 @@ var resources = (program2) => {
|
|
|
12215
12286
|
return `${color.dim("{")}${color.warning(v)}${color.dim("}")}`;
|
|
12216
12287
|
}).replaceAll(":", color.dim(":"));
|
|
12217
12288
|
};
|
|
12218
|
-
const
|
|
12289
|
+
const formatStatus2 = (status) => {
|
|
12219
12290
|
if (status === "created") {
|
|
12220
12291
|
return color.success(status);
|
|
12221
12292
|
}
|
|
@@ -12240,7 +12311,7 @@ var resources = (program2) => {
|
|
|
12240
12311
|
stack.resources.map((r) => {
|
|
12241
12312
|
return [
|
|
12242
12313
|
//
|
|
12243
|
-
|
|
12314
|
+
formatStatus2(r.status),
|
|
12244
12315
|
color.dim(icon.arrow.right),
|
|
12245
12316
|
formatResource(stack.urn, r.urn)
|
|
12246
12317
|
].join(" ");
|
|
@@ -13166,7 +13237,7 @@ var activity = (program2) => {
|
|
|
13166
13237
|
// src/cli/command/deployment.ts
|
|
13167
13238
|
import { CloudFrontClient as CloudFrontClient6 } from "@aws-sdk/client-cloudfront";
|
|
13168
13239
|
import { CloudFrontKeyValueStoreClient as CloudFrontKeyValueStoreClient3 } from "@aws-sdk/client-cloudfront-keyvaluestore";
|
|
13169
|
-
import {
|
|
13240
|
+
import { LambdaClient as LambdaClient7 } from "@aws-sdk/client-lambda";
|
|
13170
13241
|
import { log as log35, prompt as prompt19 } from "@awsless/clui";
|
|
13171
13242
|
import { DynamoDBClient as DynamoDBClient6 } from "@awsless/dynamodb";
|
|
13172
13243
|
var createClients = async (appConfig) => {
|
|
@@ -13189,6 +13260,12 @@ var formatAge = (iso) => {
|
|
|
13189
13260
|
if (minutes8 < 60 * 24) return `${Math.floor(minutes8 / 60)}h ago`;
|
|
13190
13261
|
return `${Math.floor(minutes8 / (60 * 24))}d ago`;
|
|
13191
13262
|
};
|
|
13263
|
+
var formatStatus = (item, liveId) => {
|
|
13264
|
+
if (item.id === liveId) return color.success("live ");
|
|
13265
|
+
if (item.promotedAt) return "promoted";
|
|
13266
|
+
if (item.functionVersion) return color.info("staged ");
|
|
13267
|
+
return color.dim("pending ");
|
|
13268
|
+
};
|
|
13192
13269
|
var deployments = (program2) => {
|
|
13193
13270
|
program2.command("deployments").description("List the deployment history of your app").action(async () => {
|
|
13194
13271
|
await layout("deployments", async ({ appConfig }) => {
|
|
@@ -13202,17 +13279,16 @@ var deployments = (program2) => {
|
|
|
13202
13279
|
}
|
|
13203
13280
|
const idWidth = Math.max(...items.map((item) => item.id.length));
|
|
13204
13281
|
log35.message(
|
|
13205
|
-
items.map(
|
|
13206
|
-
|
|
13207
|
-
return [
|
|
13282
|
+
items.map(
|
|
13283
|
+
(item) => [
|
|
13208
13284
|
color.label(item.id.padEnd(idWidth)),
|
|
13209
|
-
|
|
13285
|
+
formatStatus(item, liveId),
|
|
13210
13286
|
formatAge(item.createdAt).padEnd(8),
|
|
13211
13287
|
color.dim(item.commit?.slice(0, 7) ?? "-------"),
|
|
13212
13288
|
(item.message ?? "").slice(0, 50).padEnd(50),
|
|
13213
13289
|
color.dim(item.user ?? "")
|
|
13214
|
-
].join(" ")
|
|
13215
|
-
|
|
13290
|
+
].join(" ")
|
|
13291
|
+
).join("\n")
|
|
13216
13292
|
);
|
|
13217
13293
|
return `Found ${items.length} deployments.`;
|
|
13218
13294
|
});
|
|
@@ -13226,28 +13302,7 @@ var prune = (program2) => {
|
|
|
13226
13302
|
listDeployments(dynamo, appId),
|
|
13227
13303
|
readLiveDeploymentId(lambda, functionName)
|
|
13228
13304
|
]);
|
|
13229
|
-
const
|
|
13230
|
-
const keep = Math.max(1, Number(options.keep) || 10);
|
|
13231
|
-
const mainSlug = slugifyBranch(options.main);
|
|
13232
|
-
const keptMain = new Set(
|
|
13233
|
-
items.filter((item) => item.branch === mainSlug && item.functionVersion).map((item) => item.seq).sort((a, b) => b - a).slice(0, keep)
|
|
13234
|
-
);
|
|
13235
|
-
const dayAgo = new Date(Date.now() - 24 * 60 * 60 * 1e3).toISOString();
|
|
13236
|
-
const prunable = items.filter((item) => {
|
|
13237
|
-
if (item.id === liveId || item.id === rollbackTarget?.id) {
|
|
13238
|
-
return false;
|
|
13239
|
-
}
|
|
13240
|
-
if (options.branch) {
|
|
13241
|
-
return item.branch === slugifyBranch(options.branch);
|
|
13242
|
-
}
|
|
13243
|
-
if (!item.functionVersion) {
|
|
13244
|
-
return item.createdAt < dayAgo;
|
|
13245
|
-
}
|
|
13246
|
-
if (item.branch === mainSlug) {
|
|
13247
|
-
return !keptMain.has(item.seq);
|
|
13248
|
-
}
|
|
13249
|
-
return item.commit ? isCommitMerged(item.commit, options.main) : false;
|
|
13250
|
-
});
|
|
13305
|
+
const prunable = selectPrunableDeployments(items, liveId, options);
|
|
13251
13306
|
if (prunable.length === 0) {
|
|
13252
13307
|
return `Nothing to prune.`;
|
|
13253
13308
|
}
|
|
@@ -13267,28 +13322,9 @@ var prune = (program2) => {
|
|
|
13267
13322
|
for (const item of prunable) {
|
|
13268
13323
|
await deleteLambdaAlias(lambda, functionName, getDeploymentLambdaAliasName(item.id));
|
|
13269
13324
|
}
|
|
13270
|
-
const
|
|
13271
|
-
const keepVersions = new Set(surviving.map((item) => item.functionVersion));
|
|
13272
|
-
const live = await getLambdaAlias(lambda, functionName, LIVE_LAMBDA_ALIAS);
|
|
13273
|
-
if (live?.FunctionVersion) {
|
|
13274
|
-
keepVersions.add(live.FunctionVersion);
|
|
13275
|
-
}
|
|
13276
|
-
const versions = new Set(
|
|
13277
|
-
prunable.map((item) => item.functionVersion).filter((version) => version && !keepVersions.has(version))
|
|
13278
|
-
);
|
|
13325
|
+
const versions = await selectPrunableVersions({ lambda, functionName, items, prunable });
|
|
13279
13326
|
for (const version of versions) {
|
|
13280
|
-
|
|
13281
|
-
await lambda.send(
|
|
13282
|
-
new DeleteFunctionCommand({
|
|
13283
|
-
FunctionName: functionName,
|
|
13284
|
-
Qualifier: version
|
|
13285
|
-
})
|
|
13286
|
-
);
|
|
13287
|
-
} catch (error) {
|
|
13288
|
-
if (!isError(error, "ResourceNotFoundException") && !isError(error, "ResourceConflictException")) {
|
|
13289
|
-
throw error;
|
|
13290
|
-
}
|
|
13291
|
-
}
|
|
13327
|
+
await pruneFunctionVersion(lambda, functionName, version);
|
|
13292
13328
|
}
|
|
13293
13329
|
const storeArn = await getRouteStoreArn(
|
|
13294
13330
|
cloudfront,
|
|
@@ -13374,8 +13410,8 @@ program.option("--stage <string>", "The stage to use");
|
|
|
13374
13410
|
program.option("-c --no-cache", "Always build & test without the cache");
|
|
13375
13411
|
program.option("-s --skip-prompt", "Skip prompts");
|
|
13376
13412
|
program.option("-v --verbose", "Print verbose logs");
|
|
13377
|
-
program.exitOverride(() => {
|
|
13378
|
-
process.exit(
|
|
13413
|
+
program.exitOverride((error) => {
|
|
13414
|
+
process.exit(error.exitCode);
|
|
13379
13415
|
});
|
|
13380
13416
|
program.on("option:verbose", () => {
|
|
13381
13417
|
process.env.VERBOSE = program.opts().verbose ? "1" : void 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awsless/cli",
|
|
3
|
-
"version": "0.0.46-next.
|
|
3
|
+
"version": "0.0.46-next.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -83,23 +83,23 @@
|
|
|
83
83
|
"zod": "^3.24.2",
|
|
84
84
|
"zod-to-json-schema": "^3.24.3",
|
|
85
85
|
"@awsless/big-float": "^0.1.7",
|
|
86
|
+
"@awsless/clui": "^0.0.9",
|
|
86
87
|
"@awsless/cloudwatch": "^0.0.1",
|
|
87
|
-
"@awsless/duration": "^0.0.4",
|
|
88
|
-
"@awsless/clui": "^0.0.8",
|
|
89
88
|
"@awsless/dynamodb": "^0.3.21",
|
|
90
89
|
"@awsless/iot": "^0.0.5",
|
|
91
90
|
"@awsless/json": "^0.0.11",
|
|
92
|
-
"@awsless/s3": "^0.0.21",
|
|
93
91
|
"@awsless/lambda": "^0.0.45",
|
|
94
92
|
"@awsless/redis": "^0.1.13",
|
|
95
93
|
"@awsless/scheduler": "^0.0.4",
|
|
96
|
-
"@awsless/
|
|
97
|
-
"@awsless/
|
|
94
|
+
"@awsless/s3": "^0.0.21",
|
|
95
|
+
"@awsless/size": "^0.0.2",
|
|
98
96
|
"@awsless/ts-file-cache": "^0.0.16",
|
|
99
|
-
"@awsless/
|
|
100
|
-
"@awsless/weak-cache": "^0.0.1",
|
|
97
|
+
"@awsless/sqs": "^0.0.24",
|
|
101
98
|
"awsless": "^0.0.15-next.0",
|
|
102
|
-
"@awsless/
|
|
99
|
+
"@awsless/weak-cache": "^0.0.1",
|
|
100
|
+
"@awsless/sns": "^0.0.10",
|
|
101
|
+
"@awsless/validate": "^0.1.7",
|
|
102
|
+
"@awsless/duration": "^0.0.4"
|
|
103
103
|
},
|
|
104
104
|
"devDependencies": {
|
|
105
105
|
"@hono/node-server": "1.19.9",
|