cdk-nuxt 0.10.0 → 0.10.2

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/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { NuxtServerAppStack, NuxtServerAppStackProps } from "./lib/stack/server/nuxt-server-app-stack";
2
+ export { NuxtStaticAppStack, NuxtStaticAppStackProps } from "./lib/stack/static/nuxt-static-app-stack";
package/index.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NuxtStaticAppStack = exports.NuxtServerAppStack = void 0;
4
+ var nuxt_server_app_stack_1 = require("./lib/stack/server/nuxt-server-app-stack");
5
+ Object.defineProperty(exports, "NuxtServerAppStack", { enumerable: true, get: function () { return nuxt_server_app_stack_1.NuxtServerAppStack; } });
6
+ var nuxt_static_app_stack_1 = require("./lib/stack/static/nuxt-static-app-stack");
7
+ Object.defineProperty(exports, "NuxtStaticAppStack", { enumerable: true, get: function () { return nuxt_static_app_stack_1.NuxtStaticAppStack; } });
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxrRkFBb0c7QUFBNUYsMkhBQUEsa0JBQWtCLE9BQUE7QUFDMUIsa0ZBQW9HO0FBQTVGLDJIQUFBLGtCQUFrQixPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHtOdXh0U2VydmVyQXBwU3RhY2ssIE51eHRTZXJ2ZXJBcHBTdGFja1Byb3BzfSBmcm9tIFwiLi9saWIvc3RhY2svc2VydmVyL251eHQtc2VydmVyLWFwcC1zdGFja1wiXG5leHBvcnQge051eHRTdGF0aWNBcHBTdGFjaywgTnV4dFN0YXRpY0FwcFN0YWNrUHJvcHN9IGZyb20gXCIuL2xpYi9zdGFjay9zdGF0aWMvbnV4dC1zdGF0aWMtYXBwLXN0YWNrXCJcbiJdfQ==
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const client_s3_1 = require("@aws-sdk/client-s3");
4
+ const ONE_WEEK_IN_MILLISECONDS = 1000 * 60 * 60 * 24 * 7;
5
+ exports.handler = async (event, context) => {
6
+ var _a;
7
+ console.log('Starting cleanup of static assets older than 1 week...');
8
+ try {
9
+ const client = new client_s3_1.S3Client({ region: process.env.AWS_REGION });
10
+ const bucketName = process.env.STATIC_ASSETS_BUCKET;
11
+ if (!bucketName) {
12
+ throw new Error("Static asset's bucket name not specified in environment!");
13
+ }
14
+ const deleteOlderThan = new Date(Date.now() - ONE_WEEK_IN_MILLISECONDS);
15
+ // As we don't have hundreds of deployments per week, there's no need for pagination
16
+ const deploymentFolders = await client.send(new client_s3_1.ListObjectsV2Command({
17
+ Bucket: bucketName,
18
+ Delimiter: '/', // Only retrieve the top level folders
19
+ }));
20
+ // The result is a list of objects containing the keys with a trailing slash
21
+ const folderNames = (_a = deploymentFolders.CommonPrefixes) === null || _a === void 0 ? void 0 : _a.map(folder => { var _a; return (_a = folder.Prefix) === null || _a === void 0 ? void 0 : _a.slice(0, -1); });
22
+ if (!folderNames) {
23
+ console.log('Canceled static assets cleanup as folder is empty.');
24
+ return;
25
+ }
26
+ // We sort the folders by their creation data and remove the latest one as this is the currently active one used in production
27
+ const legacyFolderNames = folderNames.sort((a, b) => {
28
+ // @ts-ignore
29
+ const creationDateA = new Date(a);
30
+ // @ts-ignore
31
+ const creationDateB = new Date(b);
32
+ return creationDateA.getTime() < creationDateB.getTime() ? -1 : 1;
33
+ });
34
+ const activeFolderName = legacyFolderNames.pop();
35
+ console.log(`Detected assets folder "${activeFolderName}" as current production folder...`);
36
+ // We want to get all outdated folders of our legacy (not productively used) folders for deletion
37
+ const outdatedFolderNames = legacyFolderNames.filter(folderName => {
38
+ // @ts-ignore
39
+ const creationDate = new Date(folderName);
40
+ return creationDate.getTime() < deleteOlderThan.getTime();
41
+ });
42
+ if (!outdatedFolderNames || outdatedFolderNames.length === 0) {
43
+ console.log('No outdated asset folders found.');
44
+ }
45
+ else {
46
+ console.log(`Deleting ${outdatedFolderNames.length} outdated folders...`);
47
+ // Unfortunately it's not possible to delete folders recursively 🙄
48
+ // so we need to query all the contents in order to delete them
49
+ const pendingPromises = outdatedFolderNames.map(folderName => {
50
+ return client
51
+ .send(new client_s3_1.ListObjectsV2Command({
52
+ Bucket: bucketName,
53
+ Prefix: folderName,
54
+ }))
55
+ .then(outdatedAssets => {
56
+ var _a;
57
+ return client.send(new client_s3_1.DeleteObjectsCommand({
58
+ Bucket: bucketName,
59
+ Delete: {
60
+ Objects: (_a = outdatedAssets.Contents) === null || _a === void 0 ? void 0 : _a.map(outdatedAsset => {
61
+ return { Key: outdatedAsset.Key };
62
+ }),
63
+ },
64
+ }));
65
+ });
66
+ });
67
+ const results = await Promise.all(pendingPromises);
68
+ results.forEach(result => {
69
+ if (result.Errors && result.Errors.length) {
70
+ const errorMsg = 'Failed to delete outdated static assets.';
71
+ console.error(errorMsg, result.Errors);
72
+ throw new Error(errorMsg);
73
+ }
74
+ });
75
+ }
76
+ console.log('Cleanup of old static assets finished.');
77
+ }
78
+ catch (error) {
79
+ console.error('### unexpected runtime error ###', error);
80
+ }
81
+ };
82
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLGtEQUF3RjtBQUV4RixNQUFNLHdCQUF3QixHQUFHLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFFekQsT0FBTyxDQUFDLE9BQU8sR0FBRyxLQUFLLEVBQUUsS0FBVSxFQUFFLE9BQVksRUFBRSxFQUFFOztJQUNqRCxPQUFPLENBQUMsR0FBRyxDQUFDLHdEQUF3RCxDQUFDLENBQUM7SUFFdEUsSUFBSTtRQUNBLE1BQU0sTUFBTSxHQUFHLElBQUksb0JBQVEsQ0FBQyxFQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBQyxDQUFDLENBQUM7UUFDOUQsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQztRQUVwRCxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ2IsTUFBTSxJQUFJLEtBQUssQ0FBQywwREFBMEQsQ0FBQyxDQUFDO1NBQy9FO1FBRUQsTUFBTSxlQUFlLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLHdCQUF3QixDQUFDLENBQUM7UUFFeEUsb0ZBQW9GO1FBQ3BGLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxNQUFNLENBQUMsSUFBSSxDQUN2QyxJQUFJLGdDQUFvQixDQUFDO1lBQ3JCLE1BQU0sRUFBRSxVQUFVO1lBQ2xCLFNBQVMsRUFBRSxHQUFHLEVBQUUsc0NBQXNDO1NBQ3pELENBQUMsQ0FDTCxDQUFDO1FBRUYsNEVBQTRFO1FBQzVFLE1BQU0sV0FBVyxHQUFHLE1BQUEsaUJBQWlCLENBQUMsY0FBYywwQ0FBRSxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsV0FBQyxPQUFBLE1BQUEsTUFBTSxDQUFDLE1BQU0sMENBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FB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LENBQUMsR0FBRyxDQUFDLHdDQUF3QyxDQUFDLENBQUM7S0FDekQ7SUFBQyxPQUFPLEtBQUssRUFBRTtRQUNaLE9BQU8sQ0FBQyxLQUFLLENBQUMsa0NBQWtDLEVBQUUsS0FBSyxDQUFDLENBQUM7S0FDNUQ7QUFDTCxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0RlbGV0ZU9iamVjdHNDb21tYW5kLCBMaXN0T2JqZWN0c1YyQ29tbWFuZCwgUzNDbGllbnR9IGZyb20gXCJAYXdzLXNkay9jbGllbnQtczNcIjtcblxuY29uc3QgT05FX1dFRUtfSU5fTUlMTElTRUNPTkRTID0gMTAwMCAqIDYwICogNjAgKiAyNCAqIDc7XG5cbmV4cG9ydHMuaGFuZGxlciA9IGFzeW5jIChldmVudDogYW55LCBjb250ZXh0OiBhbnkpID0+IHtcbiAgICBjb25zb2xlLmxvZygnU3RhcnRpbmcgY2xlYW51cCBvZiBzdGF0aWMgYXNzZXRzIG9sZGVyIHRoYW4gMSB3ZWVrLi4uJyk7XG5cbiAgICB0cnkge1xuICAgICAgICBjb25zdCBjbGllbnQgPSBuZXcgUzNDbGllbnQoe3JlZ2lvbjogcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTn0pO1xuICAgICAgICBjb25zdCBidWNrZXROYW1lID0gcHJvY2Vzcy5lbnYuU1RBVElDX0FTU0VUU19CVUNLRVQ7XG5cbiAgICAgICAgaWYgKCFidWNrZXROYW1lKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTdGF0aWMgYXNzZXQncyBidWNrZXQgbmFtZSBub3Qgc3BlY2lmaWVkIGluIGVudmlyb25tZW50IVwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGRlbGV0ZU9sZGVyVGhhbiA9IG5ldyBEYXRlKERhdGUubm93KCkgLSBPTkVfV0VFS19JTl9NSUxMSVNFQ09ORFMpO1xuXG4gICAgICAgIC8vIEFzIHdlIGRvbid0IGhhdmUgaHVuZHJlZHMgb2YgZGVwbG95bWVudHMgcGVyIHdlZWssIHRoZXJlJ3Mgbm8gbmVlZCBmb3IgcGFnaW5hdGlvblxuICAgICAgICBjb25zdCBkZXBsb3ltZW50Rm9sZGVycyA9IGF3YWl0IGNsaWVudC5zZW5kKFxuICAgICAgICAgICAgbmV3IExpc3RPYmplY3RzVjJDb21tYW5kKHtcbiAgICAgICAgICAgICAgICBCdWNrZXQ6IGJ1Y2tldE5hbWUsXG4gICAgICAgICAgICAgICAgRGVsaW1pdGVyOiAnLycsIC8vIE9ubHkgcmV0cmlldmUgdGhlIHRvcCBsZXZlbCBmb2xkZXJzXG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIFRoZSByZXN1bHQgaXMgYSBsaXN0IG9mIG9iamVjdHMgY29udGFpbmluZyB0aGUga2V5cyB3aXRoIGEgdHJhaWxpbmcgc2xhc2hcbiAgICAgICAgY29uc3QgZm9sZGVyTmFtZXMgPSBkZXBsb3ltZW50Rm9sZGVycy5Db21tb25QcmVmaXhlcz8ubWFwKGZvbGRlciA9PiBmb2xkZXIuUHJlZml4Py5zbGljZSgwLCAtMSkpXG4gICAgICAgIGlmICghZm9sZGVyTmFtZXMpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdDYW5jZWxlZCBzdGF0aWMgYXNzZXRzIGNsZWFudXAgYXMgZm9sZGVyIGlzIGVtcHR5LicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gV2Ugc29ydCB0aGUgZm9sZGVycyBieSB0aGVpciBjcmVhdGlvbiBkYXRhIGFuZCByZW1vdmUgdGhlIGxhdGVzdCBvbmUgYXMgdGhpcyBpcyB0aGUgY3VycmVudGx5IGFjdGl2ZSBvbmUgdXNlZCBpbiBwcm9kdWN0aW9uXG4gICAgICAgIGNvbnN0IGxlZ2FjeUZvbGRlck5hbWVzID0gZm9sZGVyTmFtZXMuc29ydCgoYSxiKSA9PiB7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICBjb25zdCBjcmVhdGlvbkRhdGVBID0gbmV3IERhdGUoYSk7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICBjb25zdCBjcmVhdGlvbkRhdGVCID0gbmV3IERhdGUoYik7XG5cbiAgICAgICAgICAgIHJldHVybiBjcmVhdGlvbkRhdGVBLmdldFRpbWUoKSA8IGNyZWF0aW9uRGF0ZUIuZ2V0VGltZSgpID8gLTEgOiAxO1xuICAgICAgICB9KVxuICAgICAgICBjb25zdCBhY3RpdmVGb2xkZXJOYW1lID0gbGVnYWN5Rm9sZGVyTmFtZXMucG9wKCk7XG4gICAgICAgIGNvbnNvbGUubG9nKGBEZXRlY3RlZCBhc3NldHMgZm9sZGVyIFwiJHthY3RpdmVGb2xkZXJOYW1lfVwiIGFzIGN1cnJlbnQgcHJvZHVjdGlvbiBmb2xkZXIuLi5gKTtcblxuICAgICAgICAvLyBXZSB3YW50IHRvIGdldCBhbGwgb3V0ZGF0ZWQgZm9sZGVycyBvZiBvdXIgbGVnYWN5IChub3QgcHJvZHVjdGl2ZWx5IHVzZWQpIGZvbGRlcnMgZm9yIGRlbGV0aW9uXG4gICAgICAgIGNvbnN0IG91dGRhdGVkRm9sZGVyTmFtZXMgPSBsZWdhY3lGb2xkZXJOYW1lcy5maWx0ZXIoZm9sZGVyTmFtZSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIGNvbnN0IGNyZWF0aW9uRGF0ZSA9IG5ldyBEYXRlKGZvbGRlck5hbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGlvbkRhdGUuZ2V0VGltZSgpIDwgZGVsZXRlT2xkZXJUaGFuLmdldFRpbWUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoIW91dGRhdGVkRm9sZGVyTmFtZXMgfHwgb3V0ZGF0ZWRGb2xkZXJOYW1lcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdObyBvdXRkYXRlZCBhc3NldCBmb2xkZXJzIGZvdW5kLicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYERlbGV0aW5nICR7b3V0ZGF0ZWRGb2xkZXJOYW1lcy5sZW5ndGh9IG91dGRhdGVkIGZvbGRlcnMuLi5gKTtcblxuICAgICAgICAgICAgLy8gVW5mb3J0dW5hdGVseSBpdCdzIG5vdCBwb3NzaWJsZSB0byBkZWxldGUgZm9sZGVycyByZWN1cnNpdmVseSDwn5mEXG4gICAgICAgICAgICAvLyBzbyB3ZSBuZWVkIHRvIHF1ZXJ5IGFsbCB0aGUgY29udGVudHMgaW4gb3JkZXIgdG8gZGVsZXRlIHRoZW1cbiAgICAgICAgICAgIGNvbnN0IHBlbmRpbmdQcm9taXNlcyA9IG91dGRhdGVkRm9sZGVyTmFtZXMubWFwKGZvbGRlck5hbWUgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRcbiAgICAgICAgICAgICAgICAgICAgLnNlbmQoXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgTGlzdE9iamVjdHNWMkNvbW1hbmQoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ1Y2tldDogYnVja2V0TmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVmaXg6IGZvbGRlck5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKG91dGRhdGVkQXNzZXRzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnQuc2VuZChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRGVsZXRlT2JqZWN0c0NvbW1hbmQoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCdWNrZXQ6IGJ1Y2tldE5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0czogb3V0ZGF0ZWRBc3NldHMuQ29udGVudHM/Lm1hcChvdXRkYXRlZEFzc2V0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge0tleTogb3V0ZGF0ZWRBc3NldC5LZXl9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChwZW5kaW5nUHJvbWlzZXMpO1xuICAgICAgICAgICAgcmVzdWx0cy5mb3JFYWNoKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5FcnJvcnMgJiYgcmVzdWx0LkVycm9ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAnRmFpbGVkIHRvIGRlbGV0ZSBvdXRkYXRlZCBzdGF0aWMgYXNzZXRzLic7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3JNc2csIHJlc3VsdC5FcnJvcnMpO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc29sZS5sb2coJ0NsZWFudXAgb2Ygb2xkIHN0YXRpYyBhc3NldHMgZmluaXNoZWQuJyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignIyMjIHVuZXhwZWN0ZWQgcnVudGltZSBlcnJvciAjIyMnLCBlcnJvcik7XG4gICAgfVxufTsiXX0=
@@ -0,0 +1,38 @@
1
+ import { StackProps } from "aws-cdk-lib";
2
+ /**
3
+ * Defines the common props required to deploy Nuxt apps on AWS.
4
+ */
5
+ export interface NuxtAppStackProps extends StackProps {
6
+ /**
7
+ * A string identifier for the project the Nuxt app is part of.
8
+ * A project might have multiple different services.
9
+ */
10
+ readonly project: string;
11
+ /**
12
+ * A string identifier for the project's service the Nuxt app is created for.
13
+ * This can be seen as the name of the Nuxt app.
14
+ */
15
+ readonly service: string;
16
+ /**
17
+ * A string to identify the environment of the Nuxt app. This enables us
18
+ * to deploy multiple different environments of the same Nuxt app, e.g., production and development.
19
+ */
20
+ readonly environment: string;
21
+ /**
22
+ * The domain (without the protocol) at which the Nuxt app shall be publicly available.
23
+ * A DNS record will be automatically created in Route53 for the domain.
24
+ * This also supports subdomains.
25
+ * Examples: "example.com", "sub.example.com"
26
+ */
27
+ readonly domain: string;
28
+ /**
29
+ * The id of the hosted zone to create a DNS record for the specified domain.
30
+ */
31
+ readonly hostedZoneId: string;
32
+ /**
33
+ * The ARN of the certificate to use on CloudFront for the Nuxt app to make it accessible via HTTPS.
34
+ * The certificate must be issued for the specified domain in us-east-1 (global) regardless of the
35
+ * region specified via 'env.region' as CloudFront only works globally.
36
+ */
37
+ readonly globalTlsCertificateArn: string;
38
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnV4dC1hcHAtc3RhY2stcHJvcHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJudXh0LWFwcC1zdGFjay1wcm9wcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtTdGFja1Byb3BzfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBjb21tb24gcHJvcHMgcmVxdWlyZWQgdG8gZGVwbG95IE51eHQgYXBwcyBvbiBBV1MuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTnV4dEFwcFN0YWNrUHJvcHMgZXh0ZW5kcyBTdGFja1Byb3BzIHtcblxuICAgIC8qKlxuICAgICAqIEEgc3RyaW5nIGlkZW50aWZpZXIgZm9yIHRoZSBwcm9qZWN0IHRoZSBOdXh0IGFwcCBpcyBwYXJ0IG9mLlxuICAgICAqIEEgcHJvamVjdCBtaWdodCBoYXZlIG11bHRpcGxlIGRpZmZlcmVudCBzZXJ2aWNlcy5cbiAgICAgKi9cbiAgICByZWFkb25seSBwcm9qZWN0OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBIHN0cmluZyBpZGVudGlmaWVyIGZvciB0aGUgcHJvamVjdCdzIHNlcnZpY2UgdGhlIE51eHQgYXBwIGlzIGNyZWF0ZWQgZm9yLlxuICAgICAqIFRoaXMgY2FuIGJlIHNlZW4gYXMgdGhlIG5hbWUgb2YgdGhlIE51eHQgYXBwLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IHNlcnZpY2U6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgc3RyaW5nIHRvIGlkZW50aWZ5IHRoZSBlbnZpcm9ubWVudCBvZiB0aGUgTnV4dCBhcHAuIFRoaXMgZW5hYmxlcyB1c1xuICAgICAqIHRvIGRlcGxveSBtdWx0aXBsZSBkaWZmZXJlbnQgZW52aXJvbm1lbnRzIG9mIHRoZSBzYW1lIE51eHQgYXBwLCBlLmcuLCBwcm9kdWN0aW9uIGFuZCBkZXZlbG9wbWVudC5cbiAgICAgKi9cbiAgICByZWFkb25seSBlbnZpcm9ubWVudDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGRvbWFpbiAod2l0aG91dCB0aGUgcHJvdG9jb2wpIGF0IHdoaWNoIHRoZSBOdXh0IGFwcCBzaGFsbCBiZSBwdWJsaWNseSBhdmFpbGFibGUuXG4gICAgICogQSBETlMgcmVjb3JkIHdpbGwgYmUgYXV0b21hdGljYWxseSBjcmVhdGVkIGluIFJvdXRlNTMgZm9yIHRoZSBkb21haW4uXG4gICAgICogVGhpcyBhbHNvIHN1cHBvcnRzIHN1YmRvbWFpbnMuXG4gICAgICogRXhhbXBsZXM6IFwiZXhhbXBsZS5jb21cIiwgXCJzdWIuZXhhbXBsZS5jb21cIlxuICAgICAqL1xuICAgIHJlYWRvbmx5IGRvbWFpbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGlkIG9mIHRoZSBob3N0ZWQgem9uZSB0byBjcmVhdGUgYSBETlMgcmVjb3JkIGZvciB0aGUgc3BlY2lmaWVkIGRvbWFpbi5cbiAgICAgKi9cbiAgICByZWFkb25seSBob3N0ZWRab25lSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBBUk4gb2YgdGhlIGNlcnRpZmljYXRlIHRvIHVzZSBvbiBDbG91ZEZyb250IGZvciB0aGUgTnV4dCBhcHAgdG8gbWFrZSBpdCBhY2Nlc3NpYmxlIHZpYSBIVFRQUy5cbiAgICAgKiBUaGUgY2VydGlmaWNhdGUgbXVzdCBiZSBpc3N1ZWQgZm9yIHRoZSBzcGVjaWZpZWQgZG9tYWluIGluIHVzLWVhc3QtMSAoZ2xvYmFsKSByZWdhcmRsZXNzIG9mIHRoZVxuICAgICAqIHJlZ2lvbiBzcGVjaWZpZWQgdmlhICdlbnYucmVnaW9uJyBhcyBDbG91ZEZyb250IG9ubHkgd29ya3MgZ2xvYmFsbHkuXG4gICAgICovXG4gICAgcmVhZG9ubHkgZ2xvYmFsVGxzQ2VydGlmaWNhdGVBcm46IHN0cmluZztcblxufSJdfQ==
@@ -1,5 +1,4 @@
1
1
  import {StackProps} from "aws-cdk-lib";
2
- import {NuxtConfig} from "./nuxt-config";
3
2
 
4
3
  /**
5
4
  * Defines the common props required to deploy Nuxt apps on AWS.
@@ -0,0 +1,32 @@
1
+ import { CacheControl } from "aws-cdk-lib/aws-s3-deployment";
2
+ export interface StaticAssetConfig {
3
+ /**
4
+ * The file pattern for the incoming requests that should be forwarded to the target path in the static assets S3 bucket
5
+ * with the appropriate cache and content settings defined in the same object.
6
+ */
7
+ pattern: string;
8
+ /**
9
+ * The local directory to upload the files from.
10
+ */
11
+ source: string;
12
+ /**
13
+ * The remote path at which to make the uploaded files from source accessible.
14
+ */
15
+ target: string;
16
+ /**
17
+ * The content type to set for the files in the source folder when uploading them to the target.
18
+ */
19
+ contentType: string;
20
+ /**
21
+ * The cache settings to use for the uploaded source files when accessing them on the target path with the specified pattern.
22
+ */
23
+ cacheControl?: CacheControl[];
24
+ /**
25
+ * Whether to invalidate the files matching the config's pattern in the distribution's edge caches after the files are uploaded to the destination bucket.
26
+ */
27
+ invalidateOnChange?: boolean;
28
+ }
29
+ /**
30
+ * Retrieves the static assets of the Nuxt app that shall be publicly available.
31
+ */
32
+ export declare const getNuxtAppStaticAssetConfigs: () => StaticAssetConfig[];
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getNuxtAppStaticAssetConfigs = void 0;
4
+ const aws_s3_deployment_1 = require("aws-cdk-lib/aws-s3-deployment");
5
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
6
+ /**
7
+ * Retrieves the custom static assets of the Nuxt app that shall be publicly available.
8
+ */
9
+ const getNuxtAppCustomAssetConfigs = () => {
10
+ // The custom assets of server Nuxt apps are located in the src 'static' folder
11
+ // The custom assets of static Nuxt apps are located in the build files 'dist' folder
12
+ const customAssetsSourcePath = `./.output/public`;
13
+ const customAssetsTargetPath = '/';
14
+ return [
15
+ {
16
+ pattern: '*.txt',
17
+ source: customAssetsSourcePath,
18
+ target: customAssetsTargetPath,
19
+ contentType: 'text/plain; charset=UTF-8',
20
+ cacheControl: [aws_s3_deployment_1.CacheControl.setPublic(), aws_s3_deployment_1.CacheControl.maxAge(aws_cdk_lib_1.Duration.days(1))],
21
+ },
22
+ {
23
+ pattern: '*.xml',
24
+ source: customAssetsSourcePath,
25
+ target: customAssetsTargetPath,
26
+ contentType: 'text/xml; charset=UTF-8',
27
+ cacheControl: [aws_s3_deployment_1.CacheControl.setPublic(), aws_s3_deployment_1.CacheControl.maxAge(aws_cdk_lib_1.Duration.days(1))],
28
+ },
29
+ {
30
+ pattern: '.well-known/*',
31
+ source: customAssetsSourcePath,
32
+ target: customAssetsTargetPath,
33
+ contentType: 'application/json; charset=UTF-8',
34
+ cacheControl: [aws_s3_deployment_1.CacheControl.setPublic(), aws_s3_deployment_1.CacheControl.maxAge(aws_cdk_lib_1.Duration.days(1))],
35
+ },
36
+ {
37
+ pattern: '*.ico',
38
+ source: customAssetsSourcePath,
39
+ target: customAssetsTargetPath,
40
+ contentType: 'image/x-icon',
41
+ },
42
+ {
43
+ pattern: '*.png',
44
+ source: customAssetsSourcePath,
45
+ target: customAssetsTargetPath,
46
+ contentType: 'image/png',
47
+ },
48
+ {
49
+ pattern: '*.jpg',
50
+ source: customAssetsSourcePath,
51
+ target: customAssetsTargetPath,
52
+ contentType: 'image/jpg',
53
+ },
54
+ {
55
+ pattern: '*.svg',
56
+ source: customAssetsSourcePath,
57
+ target: customAssetsTargetPath,
58
+ contentType: 'image/svg+xml',
59
+ },
60
+ {
61
+ pattern: '*.js',
62
+ source: customAssetsSourcePath,
63
+ target: customAssetsTargetPath,
64
+ contentType: 'application/javascript; charset=UTF-8',
65
+ // The js files in the custom static directory are usually not versioned
66
+ // whereby we want to prevent any caching issues when updating them -> cache for only 2 days
67
+ cacheControl: [aws_s3_deployment_1.CacheControl.setPublic(), aws_s3_deployment_1.CacheControl.maxAge(aws_cdk_lib_1.Duration.days(2))],
68
+ }
69
+ ];
70
+ };
71
+ /**
72
+ * Retrieves the static assets of the Nuxt app that are generated by the build of the app.
73
+ */
74
+ const getNuxtAppBuildAssetConfigs = () => {
75
+ // The build assets required for CSR that are generated by 'nuxt build'
76
+ const buildAssetsSourcePath = './.output/public/_nuxt';
77
+ const buildAssetsTargetPath = ('/_nuxt/'); // Must match 'build.publicPath' in nuxt.config.js
78
+ return [
79
+ // Build Assets
80
+ {
81
+ pattern: '*.js',
82
+ target: buildAssetsTargetPath,
83
+ source: buildAssetsSourcePath,
84
+ contentType: 'application/javascript; charset=UTF-8',
85
+ },
86
+ {
87
+ pattern: '*.js.map',
88
+ target: buildAssetsTargetPath,
89
+ source: buildAssetsSourcePath,
90
+ contentType: 'application/json; charset=UTF-8',
91
+ },
92
+ {
93
+ pattern: '*.css',
94
+ target: buildAssetsTargetPath,
95
+ source: buildAssetsSourcePath,
96
+ contentType: 'text/css; charset=UTF-8',
97
+ },
98
+ {
99
+ pattern: '*.html',
100
+ target: buildAssetsTargetPath,
101
+ source: buildAssetsSourcePath,
102
+ contentType: 'text/html; charset=UTF-8',
103
+ // We do not want to cache html files on the browser as we want to be able to publish new changes quickly
104
+ // However, we do cache the html files on CloudFront for a performance boost and invalidate the cache on every deployment
105
+ cacheControl: [aws_s3_deployment_1.CacheControl.setPublic(), aws_s3_deployment_1.CacheControl.sMaxAge(aws_cdk_lib_1.Duration.days(7))],
106
+ invalidateOnChange: true
107
+ },
108
+ // Manifest created by PWA module
109
+ {
110
+ pattern: 'manifest.*.json',
111
+ target: buildAssetsTargetPath,
112
+ source: buildAssetsSourcePath,
113
+ contentType: 'application/json; charset=UTF-8'
114
+ },
115
+ {
116
+ pattern: '*.png',
117
+ target: buildAssetsTargetPath,
118
+ source: buildAssetsSourcePath,
119
+ contentType: 'image/png',
120
+ },
121
+ {
122
+ pattern: '*.jpg',
123
+ target: buildAssetsTargetPath,
124
+ source: buildAssetsSourcePath,
125
+ contentType: 'image/jpg',
126
+ },
127
+ {
128
+ pattern: '*.svg',
129
+ target: buildAssetsTargetPath,
130
+ source: buildAssetsSourcePath,
131
+ contentType: 'image/svg+xml',
132
+ },
133
+ {
134
+ pattern: '*.eot',
135
+ target: buildAssetsTargetPath,
136
+ source: buildAssetsSourcePath,
137
+ contentType: 'application/vnd.ms-fontobject',
138
+ },
139
+ {
140
+ pattern: '*.ttf',
141
+ target: buildAssetsTargetPath,
142
+ source: buildAssetsSourcePath,
143
+ contentType: 'application/font-sfnt',
144
+ },
145
+ {
146
+ pattern: '*.woff',
147
+ target: buildAssetsTargetPath,
148
+ source: buildAssetsSourcePath,
149
+ contentType: 'font/woff',
150
+ },
151
+ {
152
+ pattern: '*.woff2',
153
+ target: buildAssetsTargetPath,
154
+ source: buildAssetsSourcePath,
155
+ contentType: 'font/woff2',
156
+ }
157
+ ];
158
+ };
159
+ /**
160
+ * Retrieves the static assets of the Nuxt app that shall be publicly available.
161
+ */
162
+ const getNuxtAppStaticAssetConfigs = () => {
163
+ return [...getNuxtAppBuildAssetConfigs(), ...getNuxtAppCustomAssetConfigs()];
164
+ };
165
+ exports.getNuxtAppStaticAssetConfigs = getNuxtAppStaticAssetConfigs;
166
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnV4dC1hcHAtc3RhdGljLWFzc2V0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm51eHQtYXBwLXN0YXRpYy1hc3NldHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBQTJEO0FBQzNELDZDQUFxQztBQW1DckM7O0dBRUc7QUFDSCxNQUFNLDRCQUE0QixHQUFHLEdBQXdCLEVBQUU7SUFFM0QsK0VBQStFO0lBQy9FLHFGQUFxRjtJQUNyRixNQUFNLHNCQUFzQixHQUFHLGtCQUFrQixDQUFDO0lBQ2xELE1BQU0sc0JBQXNCLEdBQUcsR0FBRyxDQUFDO0lBRW5DLE9BQU87UUFDSDtZQUNJLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLE1BQU0sRUFBRSxzQkFBc0I7WUFDOUIsTUFBTSxFQUFFLHNCQUFzQjtZQUM5QixXQUFXLEVBQUUsMkJBQTJCO1lBQ3hDLFlBQVksRUFBRSxDQUFDLGdDQUFZLENBQUMsU0FBUyxFQUFFLEVBQUUsZ0NBQVksQ0FBQyxNQUFNLENBQUMsc0JBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNsRjtRQUNEO1lBQ0ksT0FBTyxFQUFFLE9BQU87WUFDaEIsTUFBTSxFQUFFLHNCQUFzQjtZQUM5QixNQUFNLEVBQUUsc0JBQXNCO1lBQzlCLFdBQVcsRUFBRSx5QkFBeUI7WUFDdEMsWUFBWSxFQUFFLENBQUMsZ0NBQVksQ0FBQyxTQUFTLEVBQUUsRUFBRSxnQ0FBWSxDQUFDLE1BQU0sQ0FBQyxzQkFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ2xGO1FBQ0Q7WUFDSSxPQUFPLEVBQUUsZUFBZTtZQUN4QixNQUFNLEVBQUUsc0JBQXNCO1lBQzlCLE1BQU0sRUFBRSxzQkFBc0I7WUFDOUIsV0FBVyxFQUFFLGlDQUFpQztZQUM5QyxZQUFZLEVBQUUsQ0FBQyxnQ0FBWSxDQUFDLFNBQVMsRUFBRSxFQUFFLGdDQUFZLENBQUMsTUFBTSxDQUFDLHNCQUFRLENBQUMsSUFB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VyxFQUFFLGVBQWU7U0FDL0I7UUFDRDtZQUNJLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixXQUFXLEVBQUUsK0JBQStCO1NBQy9DO1FBQ0Q7WUFDSSxPQUFPLEVBQUUsT0FBTztZQUNoQixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsV0FBVyxFQUFFLHVCQUF1QjtTQUN2QztRQUNEO1lBQ0ksT0FBTyxFQUFFLFFBQVE7WUFDakIsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLFdBQVcsRUFBRSxXQUFXO1NBQzNCO1FBQ0Q7WUFDSSxPQUFPLEVBQUUsU0FBUztZQUNsQixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsV0FBVyxFQUFFLFlBQVk7U0FDNUI7S0FDSixDQUFBO0FBQ0wsQ0FBQyxDQUFDO0FBRUY7O0dBRUc7QUFDSSxNQUFNLDRCQUE0QixHQUFHLEdBQXdCLEVBQUU7SUFDbEUsT0FBTyxDQUFDLEdBQUcsMkJBQTJCLEVBQUUsRUFBRSxHQUFHLDRCQUE0QixFQUFFLENBQUMsQ0FBQztBQUNqRixDQUFDLENBQUM7QUFGVyxRQUFBLDRCQUE0QixnQ0FFdkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NhY2hlQ29udHJvbH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zMy1kZXBsb3ltZW50XCI7XG5pbXBvcnQge0R1cmF0aW9ufSBmcm9tIFwiYXdzLWNkay1saWJcIjtcblxuZXhwb3J0IGludGVyZmFjZSBTdGF0aWNBc3NldENvbmZpZyB7XG4gICAgLyoqXG4gICAgICogVGhlIGZpbGUgcGF0dGVybiBmb3IgdGhlIGluY29taW5nIHJlcXVlc3RzIHRoYXQgc2hvdWxkIGJlIGZvcndhcmRlZCB0byB0aGUgdGFyZ2V0IHBhdGggaW4gdGhlIHN0YXRpYyBhc3NldHMgUzMgYnVja2V0XG4gICAgICogd2l0aCB0aGUgYXBwcm9wcmlhdGUgY2FjaGUgYW5kIGNvbnRlbnQgc2V0dGluZ3MgZGVmaW5lZCBpbiB0aGUgc2FtZSBvYmplY3QuXG4gICAgICovXG4gICAgcGF0dGVybjogc3RyaW5nLFxuXG4gICAgLyoqXG4gICAgICogVGhlIGxvY2FsIGRpcmVjdG9yeSB0byB1cGxvYWQgdGhlIGZpbGVzIGZyb20uXG4gICAgICovXG4gICAgc291cmNlOiBzdHJpbmcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVtb3RlIHBhdGggYXQgd2hpY2ggdG8gbWFrZSB0aGUgdXBsb2FkZWQgZmlsZXMgZnJvbSBzb3VyY2UgYWNjZXNzaWJsZS5cbiAgICAgKi9cbiAgICB0YXJnZXQ6IHN0cmluZyxcblxuICAgIC8qKlxuICAgICAqIFRoZSBjb250ZW50IHR5cGUgdG8gc2V0IGZvciB0aGUgZmlsZXMgaW4gdGhlIHNvdXJjZSBmb2xkZXIgd2hlbiB1cGxvYWRpbmcgdGhlbSB0byB0aGUgdGFyZ2V0LlxuICAgICAqL1xuICAgIGNvbnRlbnRUeXBlOiBzdHJpbmcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2FjaGUgc2V0dGluZ3MgdG8gdXNlIGZvciB0aGUgdXBsb2FkZWQgc291cmNlIGZpbGVzIHdoZW4gYWNjZXNzaW5nIHRoZW0gb24gdGhlIHRhcmdldCBwYXRoIHdpdGggdGhlIHNwZWNpZmllZCBwYXR0ZXJuLlxuICAgICAqL1xuICAgIGNhY2hlQ29udHJvbD86IENhY2hlQ29udHJvbFtdLFxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0byBpbnZhbGlkYXRlIHRoZSBmaWxlcyBtYXRjaGluZyB0aGUgY29uZmlnJ3MgcGF0dGVybiBpbiB0aGUgZGlzdHJpYnV0aW9uJ3MgZWRnZSBjYWNoZXMgYWZ0ZXIgdGhlIGZpbGVzIGFyZSB1cGxvYWRlZCB0byB0aGUgZGVzdGluYXRpb24gYnVja2V0LlxuICAgICAqL1xuICAgIGludmFsaWRhdGVPbkNoYW5nZT86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSBjdXN0b20gc3RhdGljIGFzc2V0cyBvZiB0aGUgTnV4dCBhcHAgdGhhdCBzaGFsbCBiZSBwdWJsaWNseSBhdmFpbGFibGUuXG4gKi9cbmNvbnN0IGdldE51eHRBcHBDdXN0b21Bc3NldENvbmZpZ3MgPSAoKTogU3RhdGljQXNzZXRDb25maWdbXSA9PiB7XG5cbiAgICAvLyBUaGUgY3VzdG9tIGFzc2V0cyBvZiBzZXJ2ZXIgTnV4dCBhcHBzIGFyZSBsb2NhdGVkIGluIHRoZSBzcmMgJ3N0YXRpYycgZm9sZGVyXG4gICAgLy8gVGhlIGN1c3RvbSBhc3NldHMgb2Ygc3RhdGljIE51eHQgYXBwcyBhcmUgbG9jYXRlZCBpbiB0aGUgYnVpbGQgZmlsZXMgJ2Rpc3QnIGZvbGRlclxuICAgIGNvbnN0IGN1c3RvbUFzc2V0c1NvdXJjZVBhdGggPSBgLi8ub3V0cHV0L3B1YmxpY2A7XG4gICAgY29uc3QgY3VzdG9tQXNzZXRzVGFyZ2V0UGF0aCA9ICcvJztcblxuICAgIHJldHVybiBbXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLnR4dCcsIC8vIEUuZy4sIHJvYm90cy50eHQsIGFkcy50eHQsIC4uLlxuICAgICAgICAgICAgc291cmNlOiBjdXN0b21Bc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgdGFyZ2V0OiBjdXN0b21Bc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICd0ZXh0L3BsYWluOyBjaGFyc2V0PVVURi04JyxcbiAgICAgICAgICAgIGNhY2hlQ29udHJvbDogW0NhY2hlQ29udHJvbC5zZXRQdWJsaWMoKSwgQ2FjaGVDb250cm9sLm1heEFnZShEdXJhdGlvbi5kYXlzKDEpKV0sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLnhtbCcsIC8vIEUuZy4sIHNpdGVtYXAueG1sIC4uLlxuICAgICAgICAgICAgc291cmNlOiBjdXN0b21Bc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgdGFyZ2V0OiBjdXN0b21Bc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICd0ZXh0L3htbDsgY2hhcnNldD1VVEYtOCcsXG4gICAgICAgICAgICBjYWNoZUNvbnRyb2w6IFtDYWNoZUNvbnRyb2wuc2V0UHVibGljKCksIENhY2hlQ29udHJvbC5tYXhBZ2UoRHVyYXRpb24uZGF5cygxKSldLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnLndlbGwta25vd24vKicsIC8vIEZpbGVzIGZvciBuYXRpdmUgYXBwIGxpbmtzXG4gICAgICAgICAgICBzb3VyY2U6IGN1c3RvbUFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICB0YXJnZXQ6IGN1c3RvbUFzc2V0c1RhcmdldFBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ2FwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgnLFxuICAgICAgICAgICAgY2FjaGVDb250cm9sOiBbQ2FjaGVDb250cm9sLnNldFB1YmxpYygpLCBDYWNoZUNvbnRyb2wubWF4QWdlKER1cmF0aW9uLmRheXMoMSkpXSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgcGF0dGVybjogJyouaWNvJywgLy8gRmF2aWNvblxuICAgICAgICAgICAgc291cmNlOiBjdXN0b21Bc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgdGFyZ2V0OiBjdXN0b21Bc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdpbWFnZS94LWljb24nLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi5wbmcnLFxuICAgICAgICAgICAgc291cmNlOiBjdXN0b21Bc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgdGFyZ2V0OiBjdXN0b21Bc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdpbWFnZS9wbmcnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi5qcGcnLFxuICAgICAgICAgICAgc291cmNlOiBjdXN0b21Bc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgdGFyZ2V0OiBjdXN0b21Bc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdpbWFnZS9qcGcnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi5zdmcnLFxuICAgICAgICAgICAgc291cmNlOiBjdXN0b21Bc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgdGFyZ2V0OiBjdXN0b21Bc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdpbWFnZS9zdmcreG1sJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgcGF0dGVybjogJyouanMnLFxuICAgICAgICAgICAgc291cmNlOiBjdXN0b21Bc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgdGFyZ2V0OiBjdXN0b21Bc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0OyBjaGFyc2V0PVVURi04JyxcbiAgICAgICAgICAgIC8vIFRoZSBqcyBmaWxlcyBpbiB0aGUgY3VzdG9tIHN0YXRpYyBkaXJlY3RvcnkgYXJlIHVzdWFsbHkgbm90IHZlcnNpb25lZFxuICAgICAgICAgICAgLy8gd2hlcmVieSB3ZSB3YW50IHRvIHByZXZlbnQgYW55IGNhY2hpbmcgaXNzdWVzIHdoZW4gdXBkYXRpbmcgdGhlbSAtPiBjYWNoZSBmb3Igb25seSAyIGRheXNcbiAgICAgICAgICAgIGNhY2hlQ29udHJvbDogW0NhY2hlQ29udHJvbC5zZXRQdWJsaWMoKSwgQ2FjaGVDb250cm9sLm1heEFnZShEdXJhdGlvbi5kYXlzKDIpKV0sXG4gICAgICAgIH1cbiAgICBdO1xufTtcblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIHN0YXRpYyBhc3NldHMgb2YgdGhlIE51eHQgYXBwIHRoYXQgYXJlIGdlbmVyYXRlZCBieSB0aGUgYnVpbGQgb2YgdGhlIGFwcC5cbiAqL1xuY29uc3QgZ2V0TnV4dEFwcEJ1aWxkQXNzZXRDb25maWdzID0gKCk6IFN0YXRpY0Fzc2V0Q29uZmlnW10gPT4ge1xuXG4gICAgLy8gVGhlIGJ1aWxkIGFzc2V0cyByZXF1aXJlZCBmb3IgQ1NSIHRoYXQgYXJlIGdlbmVyYXRlZCBieSAnbnV4dCBidWlsZCdcbiAgICBjb25zdCBidWlsZEFzc2V0c1NvdXJjZVBhdGggPSAnLi8ub3V0cHV0L3B1YmxpYy9fbnV4dCc7XG4gICAgY29uc3QgYnVpbGRBc3NldHNUYXJnZXRQYXRoID0gKCcvX251eHQvJyk7IC8vIE11c3QgbWF0Y2ggJ2J1aWxkLnB1YmxpY1BhdGgnIGluIG51eHQuY29uZmlnLmpzXG5cbiAgICByZXR1cm4gW1xuXG4gICAgICAgIC8vIEJ1aWxkIEFzc2V0c1xuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi5qcycsXG4gICAgICAgICAgICB0YXJnZXQ6IGJ1aWxkQXNzZXRzVGFyZ2V0UGF0aCxcbiAgICAgICAgICAgIHNvdXJjZTogYnVpbGRBc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0OyBjaGFyc2V0PVVURi04JyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgcGF0dGVybjogJyouanMubWFwJyxcbiAgICAgICAgICAgIHRhcmdldDogYnVpbGRBc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgc291cmNlOiBidWlsZEFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ2FwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi5jc3MnLFxuICAgICAgICAgICAgdGFyZ2V0OiBidWlsZEFzc2V0c1RhcmdldFBhdGgsXG4gICAgICAgICAgICBzb3VyY2U6IGJ1aWxkQXNzZXRzU291cmNlUGF0aCxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiAndGV4dC9jc3M7IGNoYXJzZXQ9VVRGLTgnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi5odG1sJyxcbiAgICAgICAgICAgIHRhcmdldDogYnVpbGRBc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgc291cmNlOiBidWlsZEFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ3RleHQvaHRtbDsgY2hhcnNldD1VVEYtOCcsXG4gICAgICAgICAgICAvLyBXZSBkbyBub3Qgd2FudCB0byBjYWNoZSBodG1sIGZpbGVzIG9uIHRoZSBicm93c2VyIGFzIHdlIHdhbnQgdG8gYmUgYWJsZSB0byBwdWJsaXNoIG5ldyBjaGFuZ2VzIHF1aWNrbHlcbiAgICAgICAgICAgIC8vIEhvd2V2ZXIsIHdlIGRvIGNhY2hlIHRoZSBodG1sIGZpbGVzIG9uIENsb3VkRnJvbnQgZm9yIGEgcGVyZm9ybWFuY2UgYm9vc3QgYW5kIGludmFsaWRhdGUgdGhlIGNhY2hlIG9uIGV2ZXJ5IGRlcGxveW1lbnRcbiAgICAgICAgICAgIGNhY2hlQ29udHJvbDogW0NhY2hlQ29udHJvbC5zZXRQdWJsaWMoKSwgQ2FjaGVDb250cm9sLnNNYXhBZ2UoRHVyYXRpb24uZGF5cyg3KSldLFxuICAgICAgICAgICAgaW52YWxpZGF0ZU9uQ2hhbmdlOiB0cnVlXG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gTWFuaWZlc3QgY3JlYXRlZCBieSBQV0EgbW9kdWxlXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICdtYW5pZmVzdC4qLmpzb24nLFxuICAgICAgICAgICAgdGFyZ2V0OiBidWlsZEFzc2V0c1RhcmdldFBhdGgsXG4gICAgICAgICAgICBzb3VyY2U6IGJ1aWxkQXNzZXRzU291cmNlUGF0aCxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiAnYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCdcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgcGF0dGVybjogJyoucG5nJyxcbiAgICAgICAgICAgIHRhcmdldDogYnVpbGRBc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgc291cmNlOiBidWlsZEFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ2ltYWdlL3BuZycsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLmpwZycsXG4gICAgICAgICAgICB0YXJnZXQ6IGJ1aWxkQXNzZXRzVGFyZ2V0UGF0aCxcbiAgICAgICAgICAgIHNvdXJjZTogYnVpbGRBc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdpbWFnZS9qcGcnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi5zdmcnLFxuICAgICAgICAgICAgdGFyZ2V0OiBidWlsZEFzc2V0c1RhcmdldFBhdGgsXG4gICAgICAgICAgICBzb3VyY2U6IGJ1aWxkQXNzZXRzU291cmNlUGF0aCxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiAnaW1hZ2Uvc3ZnK3htbCcsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLmVvdCcsXG4gICAgICAgICAgICB0YXJnZXQ6IGJ1aWxkQXNzZXRzVGFyZ2V0UGF0aCxcbiAgICAgICAgICAgIHNvdXJjZTogYnVpbGRBc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi92bmQubXMtZm9udG9iamVjdCcsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLnR0ZicsXG4gICAgICAgICAgICB0YXJnZXQ6IGJ1aWxkQXNzZXRzVGFyZ2V0UGF0aCxcbiAgICAgICAgICAgIHNvdXJjZTogYnVpbGRBc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi9mb250LXNmbnQnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi53b2ZmJyxcbiAgICAgICAgICAgIHRhcmdldDogYnVpbGRBc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgc291cmNlOiBidWlsZEFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ2ZvbnQvd29mZicsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLndvZmYyJyxcbiAgICAgICAgICAgIHRhcmdldDogYnVpbGRBc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgc291cmNlOiBidWlsZEFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ2ZvbnQvd29mZjInLFxuICAgICAgICB9XG4gICAgXVxufTtcblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIHN0YXRpYyBhc3NldHMgb2YgdGhlIE51eHQgYXBwIHRoYXQgc2hhbGwgYmUgcHVibGljbHkgYXZhaWxhYmxlLlxuICovXG5leHBvcnQgY29uc3QgZ2V0TnV4dEFwcFN0YXRpY0Fzc2V0Q29uZmlncyA9ICgpOiBTdGF0aWNBc3NldENvbmZpZ1tdID0+IHtcbiAgICByZXR1cm4gWy4uLmdldE51eHRBcHBCdWlsZEFzc2V0Q29uZmlncygpLCAuLi5nZXROdXh0QXBwQ3VzdG9tQXNzZXRDb25maWdzKCldO1xufTsiXX0=
@@ -0,0 +1,201 @@
1
+ import { Stack } from 'aws-cdk-lib';
2
+ import { Construct } from 'constructs';
3
+ import { IBucket } from "aws-cdk-lib/aws-s3";
4
+ import { NuxtAppStackProps } from "../nuxt-app-stack-props";
5
+ /**
6
+ * Defines the props required for the {@see NuxtServerAppStack}.
7
+ */
8
+ export interface NuxtServerAppStackProps extends NuxtAppStackProps {
9
+ /**
10
+ * The ARN of the certificate to use at the ApiGateway for the Nuxt app to make it accessible via the custom domain
11
+ * and to provide the custom domain to the Nuxt app via the 'Host' header for server side rendering use cases.
12
+ * The certificate must be issued in the same region as specified via 'env.region' as ApiGateway works regionally.
13
+ */
14
+ readonly regionalTlsCertificateArn: string;
15
+ /**
16
+ * The memory size to apply to the Nuxt app's Lambda.
17
+ * Defaults to 1792MB (optimized for costs and performance for standard Nuxt apps).
18
+ */
19
+ readonly memorySize?: number;
20
+ /**
21
+ * Whether to enable AWS X-Ray for the Nuxt Lambda function.
22
+ */
23
+ readonly enableTracing?: boolean;
24
+ /**
25
+ * Whether to enable a global Sitemap bucket which is permanently accessible through multiple deployments.
26
+ */
27
+ readonly enableSitemap?: boolean;
28
+ }
29
+ /**
30
+ * CDK stack to deploy a dynamic Nuxt app (target=server) on AWS with Lambda, ApiGateway, S3 and CloudFront.
31
+ */
32
+ export declare class NuxtServerAppStack extends Stack {
33
+ /**
34
+ * The identifier prefix of the resources created by the stack.
35
+ *
36
+ * @private
37
+ */
38
+ private readonly resourceIdPrefix;
39
+ /**
40
+ * The identifier for the current deployment that is used as S3 folder name
41
+ * to store the static assets of the Nuxt app.
42
+ *
43
+ * @private
44
+ */
45
+ private readonly deploymentRevision;
46
+ /**
47
+ * The identity to use for accessing the deployment assets on S3.
48
+ *
49
+ * @private
50
+ */
51
+ private readonly cdnAccessIdentity;
52
+ /**
53
+ * The S3 bucket where the deployment assets gets stored.
54
+ */
55
+ staticAssetsBucket: IBucket;
56
+ /**
57
+ * The S3 bucket where the sitemap assets gets stored.
58
+ */
59
+ sitemapBucket: IBucket | undefined;
60
+ /**
61
+ * The Lambda function to render the Nuxt app on the server side.
62
+ *
63
+ * @private
64
+ */
65
+ private readonly appLambdaFunction;
66
+ /**
67
+ * The Lambda function that cleanups the outdated static assets of the Nuxt app.
68
+ *
69
+ * @private
70
+ */
71
+ private readonly cleanupLambdaFunction;
72
+ /**
73
+ * The API gateway to make the Lambda function to render the Nuxt app publicly available.
74
+ *
75
+ * @private
76
+ */
77
+ private apiGateway;
78
+ /**
79
+ * The configs for the static assets of the Nuxt app that shall be publicly available.
80
+ *
81
+ * @private
82
+ */
83
+ private staticAssetConfigs;
84
+ /**
85
+ * The CloudFront distribution to route incoming requests to the Nuxt Lambda function (via the API gateway)
86
+ * or the S3 assets folder (with caching).
87
+ *
88
+ * @private
89
+ */
90
+ private readonly cdn;
91
+ constructor(scope: Construct, id: string, props: NuxtServerAppStackProps);
92
+ /**
93
+ * Creates the identity to access the S3 deployment asset files via the CloudFront distribution.
94
+ *
95
+ * @private
96
+ */
97
+ private createCdnAccessIdentity;
98
+ /**
99
+ * Creates the bucket to store the static deployment asset files of the Nuxt app.
100
+ *
101
+ * @private
102
+ */
103
+ private createStaticAssetsBucket;
104
+ /**
105
+ * Creates the bucket to store the sitemap assets of the Nuxt app.
106
+ *
107
+ * @private
108
+ */
109
+ private createSitemapBucket;
110
+ /**
111
+ * Creates the Lambda function to render the Nuxt app.
112
+ *
113
+ * @private
114
+ */
115
+ private createAppLambdaFunction;
116
+ /**
117
+ * Creates the Lambda function that cleanups the outdated static assets of the Nuxt app.
118
+ *
119
+ * @param props
120
+ * @private
121
+ */
122
+ private createCleanupLambdaFunction;
123
+ /**
124
+ * Creates the API gateway to make the Nuxt app render Lambda function publicly available.
125
+ *
126
+ * @private
127
+ */
128
+ private createApiGateway;
129
+ /**
130
+ * Creates the CloudFront distribution that routes incoming requests to the Nuxt Lambda function (via the API gateway)
131
+ * or the S3 assets folder (with caching).
132
+ *
133
+ * @param props
134
+ * @private
135
+ */
136
+ private createCloudFrontDistribution;
137
+ /**
138
+ * Creates a behavior for the CloudFront distribution to route incoming requests to the Nuxt render Lambda function (via API gateway).
139
+ * Additionally, this automatically redirects HTTP requests to HTTPS.
140
+ *
141
+ * @private
142
+ */
143
+ private createNuxtAppRouteBehavior;
144
+ private setupCloudFrontRouting;
145
+ /**
146
+ * Creates a cache policy for the Nuxt app route behavior of the CloudFront distribution.
147
+ * Even though we don't want to cache SSR requests, we still have to create this cache policy in order to
148
+ * forward required cookies, query params and headers. This doesn't make any sense, because if nothing
149
+ * is cached, one would expect, that anything would/could be forwarded, but anyway...
150
+ */
151
+ private createSsrCachePolicy;
152
+ /**
153
+ * Creates a behavior for the CloudFront distribution to route matching incoming requests for the static assets
154
+ * to the S3 bucket that holds these static assets.
155
+ *
156
+ * @private
157
+ */
158
+ private createStaticAssetsRouteBehavior;
159
+ /**
160
+ * Creates a behavior for the CloudFront distribution to route matching incoming requests for the sitemap assets
161
+ * to the S3 bucket that holds these sitemap assets.
162
+ *
163
+ * @private
164
+ */
165
+ private createSitemapRouteBehavior;
166
+ /**
167
+ * Uploads the static assets of the Nuxt app as defined in {@see getNuxtAppStaticAssetConfigs} to the static assets S3 bucket.
168
+ * In order to enable a zero-downtime deployment, we use a new subdirectory (revision) for every deployment.
169
+ * The previous versions are retained to allow clients to continue to work with an older revision but gets cleaned up
170
+ * after a specified period of time via the Lambda function in the {@see NuxtAppAssetsCleanupStack}.
171
+ */
172
+ private configureDeployments;
173
+ /**
174
+ * Resolves the hosted zone at which the DNS records shall be created to access the Nuxt app on the internet.
175
+ *
176
+ * @param props
177
+ * @private
178
+ */
179
+ private findHostedZone;
180
+ /**
181
+ * Creates the DNS records to access the Nuxt app on the internet via the custom domain.
182
+ *
183
+ * @param props
184
+ * @private
185
+ */
186
+ private createDnsRecords;
187
+ /**
188
+ * Creates a scheduled rule to ping the Nuxt app Lambda function every 5 minutes in order to keep it warm
189
+ * and speed up initial SSR requests.
190
+ *
191
+ * @private
192
+ */
193
+ private createAppPingRule;
194
+ /**
195
+ * Creates a scheduled rule that runs every tuesday at 03:30 AM GMT to trigger
196
+ * our cleanup Lambda function.
197
+ *
198
+ * @private
199
+ */
200
+ private createCleanupTriggerRule;
201
+ }