cdk-nuxt 2.4.0 → 2.5.0
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/README.md +133 -46
- package/lib/cli/deploy-server.js +9 -2
- package/lib/cli/destroy-server.js +8 -1
- package/lib/functions/access-logs-analysis/group-by-date/package.json +20 -19
- package/lib/functions/access-logs-analysis/group-by-date/pnpm-lock.yaml +1385 -0
- package/lib/functions/access-logs-analysis/partitioning/package.json +20 -19
- package/lib/functions/access-logs-analysis/partitioning/pnpm-lock.yaml +1122 -0
- package/lib/functions/assets-cleanup/package.json +19 -18
- package/lib/functions/assets-cleanup/pnpm-lock.yaml +1377 -0
- package/lib/stack/access-logs-analysis/AccessLogsAnalysis.js +19 -4
- package/lib/stack/access-logs-analysis/AccessLogsAnalysis.ts +23 -5
- package/lib/stack/server/NuxtServerAppStack.d.ts +18 -3
- package/lib/stack/server/NuxtServerAppStack.js +56 -20
- package/lib/stack/server/NuxtServerAppStack.ts +76 -24
- package/lib/stack/server/NuxtServerAppStackProps.d.ts +73 -0
- package/lib/stack/server/NuxtServerAppStackProps.js +1 -1
- package/lib/stack/server/NuxtServerAppStackProps.ts +80 -0
- package/lib/templates/stack-index-server.ts +60 -24
- package/package.json +44 -42
- package/lib/functions/access-logs-analysis/group-by-date/.gitignore +0 -2
- package/lib/functions/access-logs-analysis/group-by-date/build/app/index.d.ts +0 -2
- package/lib/functions/access-logs-analysis/group-by-date/build/app/index.js +0 -57
- package/lib/functions/access-logs-analysis/group-by-date/build/app/index.js.map +0 -1
- package/lib/functions/access-logs-analysis/group-by-date/yarn.lock +0 -1253
- package/lib/functions/access-logs-analysis/partitioning/.gitignore +0 -2
- package/lib/functions/access-logs-analysis/partitioning/build/app/create-partition.d.ts +0 -1
- package/lib/functions/access-logs-analysis/partitioning/build/app/create-partition.js +0 -57
- package/lib/functions/access-logs-analysis/partitioning/build/app/create-partition.js.map +0 -1
- package/lib/functions/access-logs-analysis/partitioning/build/app/transform-partition.d.ts +0 -2
- package/lib/functions/access-logs-analysis/partitioning/build/app/transform-partition.js +0 -72
- package/lib/functions/access-logs-analysis/partitioning/build/app/transform-partition.js.map +0 -1
- package/lib/functions/access-logs-analysis/partitioning/build/app/types.d.ts +0 -7
- package/lib/functions/access-logs-analysis/partitioning/build/app/types.js +0 -3
- package/lib/functions/access-logs-analysis/partitioning/build/app/types.js.map +0 -1
- package/lib/functions/access-logs-analysis/partitioning/build/app/util.d.ts +0 -9
- package/lib/functions/access-logs-analysis/partitioning/build/app/util.js +0 -44
- package/lib/functions/access-logs-analysis/partitioning/build/app/util.js.map +0 -1
- package/lib/functions/access-logs-analysis/partitioning/yarn.lock +0 -1009
- package/lib/functions/assets-cleanup/.gitignore +0 -2
- package/lib/functions/assets-cleanup/build/app/index.d.ts +0 -1
- package/lib/functions/assets-cleanup/build/app/index.js +0 -114
- package/lib/functions/assets-cleanup/build/app/index.js.map +0 -1
- package/lib/functions/assets-cleanup/yarn.lock +0 -1245
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
4
|
-
const consumers_1 = require("stream/consumers");
|
|
5
|
-
const MAX_DELETE_OBJECT_KEYS = 1000;
|
|
6
|
-
const ONE_DAY_IN_MILLISECONDS = 1000 * 60 * 60 * 24;
|
|
7
|
-
/**
|
|
8
|
-
* Returns the current deployment revision (build timestamp).
|
|
9
|
-
*/
|
|
10
|
-
const getCurrentRevision = async (s3Client, bucketName) => {
|
|
11
|
-
const revisionFile = await s3Client.send(new client_s3_1.GetObjectCommand({
|
|
12
|
-
Bucket: bucketName,
|
|
13
|
-
Key: 'app-revision',
|
|
14
|
-
}));
|
|
15
|
-
return new Date(await (0, consumers_1.text)(revisionFile.Body));
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* Filters the given assets by inspecting their revision and returns those, that are older than the specified cutoff date.
|
|
19
|
-
*/
|
|
20
|
-
const filterOutdatedAssetKeys = (metadataResults, returnOlderThan) => {
|
|
21
|
-
return metadataResults
|
|
22
|
-
.filter(assetMetadata => assetMetadata.metadata.revision
|
|
23
|
-
? new Date(assetMetadata.metadata.revision).getTime() <= returnOlderThan.getTime()
|
|
24
|
-
: false)
|
|
25
|
-
.map(filteredAssets => filteredAssets.key);
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Deletes the given assets.
|
|
29
|
-
*/
|
|
30
|
-
const deleteAssets = async (assetKeys, s3Client, bucketName) => {
|
|
31
|
-
let remainingAssetKeysToDelete = [...assetKeys];
|
|
32
|
-
const pendingDeletes = [];
|
|
33
|
-
while (remainingAssetKeysToDelete.length > 0) {
|
|
34
|
-
const curDeleteBatch = remainingAssetKeysToDelete.slice(0, MAX_DELETE_OBJECT_KEYS);
|
|
35
|
-
remainingAssetKeysToDelete = remainingAssetKeysToDelete.slice(MAX_DELETE_OBJECT_KEYS);
|
|
36
|
-
console.log('Deleting assets:', curDeleteBatch);
|
|
37
|
-
const pendingDelete = s3Client.send(new client_s3_1.DeleteObjectsCommand({
|
|
38
|
-
Bucket: bucketName,
|
|
39
|
-
Delete: {
|
|
40
|
-
Objects: curDeleteBatch.map(outdatedKey => {
|
|
41
|
-
return { Key: outdatedKey };
|
|
42
|
-
}),
|
|
43
|
-
},
|
|
44
|
-
}));
|
|
45
|
-
pendingDeletes.push(pendingDelete);
|
|
46
|
-
}
|
|
47
|
-
return await Promise.all(pendingDeletes);
|
|
48
|
-
};
|
|
49
|
-
exports.handler = async (event, context) => {
|
|
50
|
-
try {
|
|
51
|
-
const client = new client_s3_1.S3Client({ region: process.env.AWS_REGION });
|
|
52
|
-
const bucketName = process.env.STATIC_ASSETS_BUCKET;
|
|
53
|
-
if (!bucketName) {
|
|
54
|
-
throw new Error("Static asset's bucket name not specified in environment!");
|
|
55
|
-
}
|
|
56
|
-
if (!process.env.OUTDATED_ASSETS_RETENTION_DAYS) {
|
|
57
|
-
throw new Error('Retain duration of static assets not specified!');
|
|
58
|
-
}
|
|
59
|
-
const retainAssetsInDays = Number.parseInt(process.env.OUTDATED_ASSETS_RETENTION_DAYS);
|
|
60
|
-
const currentRevision = await getCurrentRevision(client, bucketName);
|
|
61
|
-
const deleteOlderThan = new Date(currentRevision.getTime() - retainAssetsInDays * ONE_DAY_IN_MILLISECONDS);
|
|
62
|
-
console.log(`Starting cleanup of static assets older than ${deleteOlderThan.toISOString()}...`);
|
|
63
|
-
let assetKeysToDelete = [];
|
|
64
|
-
let lastToken = undefined;
|
|
65
|
-
do {
|
|
66
|
-
const curAssetsResult = await client.send(new client_s3_1.ListObjectsV2Command({
|
|
67
|
-
Bucket: bucketName,
|
|
68
|
-
MaxKeys: 250,
|
|
69
|
-
ContinuationToken: lastToken,
|
|
70
|
-
}));
|
|
71
|
-
// Read object metadata in blocks of 10
|
|
72
|
-
let processableAssets = [...curAssetsResult.Contents];
|
|
73
|
-
while (processableAssets.length > 0) {
|
|
74
|
-
const assetsBatch = processableAssets.slice(0, 10);
|
|
75
|
-
processableAssets = processableAssets.slice(10);
|
|
76
|
-
const pendingMetadataRequests = assetsBatch.map(asset => client.send(new client_s3_1.HeadObjectCommand({
|
|
77
|
-
Bucket: bucketName,
|
|
78
|
-
Key: asset.Key,
|
|
79
|
-
})));
|
|
80
|
-
const metadataResults = await Promise.all(pendingMetadataRequests);
|
|
81
|
-
// Assign metadata to assets
|
|
82
|
-
const metadataByAsset = metadataResults.map((metadataResult, index) => ({
|
|
83
|
-
key: assetsBatch[index].Key,
|
|
84
|
-
metadata: metadataResult.Metadata,
|
|
85
|
-
}));
|
|
86
|
-
const outdatedAssetKeys = filterOutdatedAssetKeys(metadataByAsset, deleteOlderThan);
|
|
87
|
-
assetKeysToDelete.push(...outdatedAssetKeys);
|
|
88
|
-
}
|
|
89
|
-
lastToken = curAssetsResult.NextContinuationToken;
|
|
90
|
-
} while (lastToken !== undefined);
|
|
91
|
-
if (assetKeysToDelete.length === 0) {
|
|
92
|
-
console.log('No outdated assets to delete found');
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
console.log('Deleting ' + assetKeysToDelete.length + ' assets...');
|
|
96
|
-
// Delete outdated assets (max. 1000 allowed per request)
|
|
97
|
-
const results = await deleteAssets(assetKeysToDelete, client, bucketName);
|
|
98
|
-
const failed = results.reduce((previousResult, currentResult) => {
|
|
99
|
-
const currentError = !!(currentResult.Errors && currentResult.Errors.length > 0);
|
|
100
|
-
if (currentError) {
|
|
101
|
-
console.error('Failed to delete outdated static assets', currentResult.Errors);
|
|
102
|
-
}
|
|
103
|
-
return previousResult || currentError;
|
|
104
|
-
}, false);
|
|
105
|
-
if (failed) {
|
|
106
|
-
throw new Error('Failed to delete outdated static assets');
|
|
107
|
-
}
|
|
108
|
-
console.log('Cleanup of old static assets finished');
|
|
109
|
-
}
|
|
110
|
-
catch (error) {
|
|
111
|
-
console.error('### unexpected runtime error ###', error);
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DeleteObjectsCommand,\n DeleteObjectsCommandOutput,\n GetObjectCommand, HeadObjectCommand,\n ListObjectsV2Command,\n S3Client\n} from \"@aws-sdk/client-s3\";\nimport type {ListObjectsV2CommandOutput} from \"@aws-sdk/client-s3\";\nimport {text} from 'stream/consumers';\nimport {Readable} from \"stream\";\n\ninterface AssetMetadata {\n readonly key: string;\n readonly metadata: {[key: string]: string};\n}\n\nconst MAX_DELETE_OBJECT_KEYS = 1000;\nconst ONE_DAY_IN_MILLISECONDS = 1000 * 60 * 60 * 24;\n\n/**\n * Returns the current deployment revision (build timestamp).\n */\nconst getCurrentRevision = async (s3Client: S3Client, bucketName: string): Promise<Date> => {\n const revisionFile = await s3Client.send(\n new GetObjectCommand({\n Bucket: bucketName,\n Key: 'app-revision',\n })\n );\n\n return new Date(await text(revisionFile.Body as Readable));\n};\n\n/**\n * Filters the given assets by inspecting their revision and returns those, that are older than the specified cutoff date.\n */\nconst filterOutdatedAssetKeys = (metadataResults: AssetMetadata[], returnOlderThan: Date): string[] => {\n return metadataResults\n .filter(assetMetadata =>\n assetMetadata.metadata.revision\n ? new Date(assetMetadata.metadata.revision).getTime() <= returnOlderThan.getTime()\n : false\n )\n .map(filteredAssets => filteredAssets.key);\n};\n\n/**\n * Deletes the given assets.\n */\nconst deleteAssets = async (\n assetKeys: string[],\n s3Client: S3Client,\n bucketName: string\n): Promise<DeleteObjectsCommandOutput[]> => {\n let remainingAssetKeysToDelete = [...assetKeys];\n const pendingDeletes = [];\n\n while (remainingAssetKeysToDelete.length > 0) {\n const curDeleteBatch = remainingAssetKeysToDelete.slice(0, MAX_DELETE_OBJECT_KEYS);\n remainingAssetKeysToDelete = remainingAssetKeysToDelete.slice(MAX_DELETE_OBJECT_KEYS);\n\n console.log('Deleting assets:', curDeleteBatch);\n\n const pendingDelete = s3Client.send(\n new DeleteObjectsCommand({\n Bucket: bucketName,\n Delete: {\n Objects: curDeleteBatch.map(outdatedKey => {\n return {Key: outdatedKey};\n }),\n },\n })\n );\n pendingDeletes.push(pendingDelete);\n }\n\n return await Promise.all(pendingDeletes);\n};\n\nexports.handler = async (event: any, context: any) => {\n try {\n const client = new S3Client({region: process.env.AWS_REGION});\n const bucketName = process.env.STATIC_ASSETS_BUCKET;\n if (!bucketName) {\n throw new Error(\"Static asset's bucket name not specified in environment!\");\n }\n\n if (!process.env.OUTDATED_ASSETS_RETENTION_DAYS) {\n throw new Error('Retain duration of static assets not specified!');\n }\n const retainAssetsInDays = Number.parseInt(process.env.OUTDATED_ASSETS_RETENTION_DAYS);\n const currentRevision = await getCurrentRevision(client, bucketName);\n const deleteOlderThan = new Date(currentRevision.getTime() - retainAssetsInDays * ONE_DAY_IN_MILLISECONDS);\n\n console.log(`Starting cleanup of static assets older than ${deleteOlderThan.toISOString()}...`);\n\n let assetKeysToDelete: string[] = [];\n let lastToken = undefined;\n\n do {\n const curAssetsResult: ListObjectsV2CommandOutput = await client.send(\n new ListObjectsV2Command({\n Bucket: bucketName,\n MaxKeys: 250,\n ContinuationToken: lastToken,\n })\n );\n\n // Read object metadata in blocks of 10\n let processableAssets = [...curAssetsResult.Contents!];\n\n while (processableAssets.length > 0) {\n const assetsBatch = processableAssets.slice(0, 10);\n processableAssets = processableAssets.slice(10);\n\n const pendingMetadataRequests = assetsBatch.map(asset =>\n client.send(\n new HeadObjectCommand({\n Bucket: bucketName,\n Key: asset.Key,\n })\n )\n );\n\n const metadataResults = await Promise.all(pendingMetadataRequests);\n\n // Assign metadata to assets\n const metadataByAsset: AssetMetadata[] = (metadataResults.map((metadataResult, index) => ({\n key: assetsBatch[index].Key,\n metadata: metadataResult.Metadata,\n })) as AssetMetadata[]);\n\n const outdatedAssetKeys = filterOutdatedAssetKeys(metadataByAsset, deleteOlderThan);\n assetKeysToDelete.push(...outdatedAssetKeys);\n }\n lastToken = curAssetsResult.NextContinuationToken;\n } while (lastToken !== undefined);\n\n if (assetKeysToDelete.length === 0) {\n console.log('No outdated assets to delete found');\n return;\n }\n\n console.log('Deleting ' + assetKeysToDelete.length + ' assets...');\n\n // Delete outdated assets (max. 1000 allowed per request)\n const results = await deleteAssets(assetKeysToDelete, client, bucketName);\n const failed = results.reduce((previousResult: boolean, currentResult: DeleteObjectsCommandOutput): boolean => {\n const currentError: boolean = !!(currentResult.Errors && currentResult.Errors.length > 0);\n if (currentError) {\n console.error('Failed to delete outdated static assets', currentResult.Errors);\n }\n return previousResult || currentError;\n }, false);\n\n if (failed) {\n throw new Error('Failed to delete outdated static assets');\n }\n\n console.log('Cleanup of old static assets finished');\n } catch (error) {\n console.error('### unexpected runtime error ###', error);\n }\n};"]}
|